bkase
I think in the future the overhead will improve significantly, and we can already see incremental improvements in some proof systems. For Kimchi (the proof system we’ve built for zkapps/Mina), we've instead focused on features — like infinite recursion. To really see the performance overhead reduce, we’ll need to push more of the compute into silicon (think opcodes designed for zk similar to the ones we have now to accelerate RSA). In the meantime, modern processors are fast enough that this overhead doesn’t hold back many sorts of applications.
On fixed inputs: Kimchi is “universal” in that it can recursively compose arbitrary circuits efficiently — including ones with different public and private inputs and including ones that haven’t been defined yet. This is what powers zkapps and zkapps’ ability to recursively compose circuits on itself (think application-specific rollups).
Randomness: Modern blockchains have mechanisms for trustlessly agreeing on securely generated random seeds. We can tap into that and use mechanisms like verifiable random functions (which Mina uses internally during consensus) to securely manage randomness (caveat: we haven’t built out the randomness APIs for zkapps yet so there may be some nuance here that we haven’t run into yet). If you want to learn more about how this works in Mina, read up on Ouroboros Samasika, Mina Protocol’s consensus mechanism.
Prevent replay attacks: Blockchains are designed for this :). Basically increment a nonce and feed the current nonce as one of the public inputs to the zkapp.
Remote attestation: This requires nuance to define properly as there are different solutions to different versions of this problem. I’ll outline a few here:
1. Consider the case where you trust the entity that attesting to something and they can upgrade their backend: the entity adds a snark friendly signature to their endpoint and you check the signature within the zkapp (remember since they run locally, you execution can just make async network requests)
2. Consider the case where you trust the entity but can’t convince them to change their API: here you can verify the contents of the response against the TLS signature that already exists in the modern web. Caveat: this is still a work in progress, we’re currently calling it zkOracles
3. Consider the case where you don’t trust the entity — in this case we’re talking about reading information from other zkapps or blockchains. Luckily, these all come with signatures in different shapes and sizes so the problem becomes efficiently verifying those signatures from within the zkapp. You can solve this in modern plonkish zk proof systems with custom gates. Caveat: this is also a work in progress for zkapps in Mina.
Yes you are right, you should not replace grep for one off regexes due to the latency of the io operations. As far as I recall, memory throughput however is much higher on house than on CPUs (or at least this was true in 2012). Our intended use cases for this sort of a grep were cases where you are finding many needles in enormous haystacks such as: Looking for malicious machine code in executables that you download off of the internet (virus scanning), or searching for certain genetic sequences in DNA code. I believe we discussed this in our final presentation, but perhaps we left it out of the written report.
Yes we probably should have included the numbers to show why you wouldn't want to use this instead of grep for simple tasks. I am sorry we missed it.
Fast Accumulation on Streams
A CRDT is just what mathematicians (and functional programmers) call a Semilattice[1], right? In general, I find it frustrating when people make up new names for existing mathematical concepts because it deprives others from learning and seeing the big picture. Does this resonate with anyone here?
Write a function `ACM : (String -> a) -> a` aka a function that takes a string consumer as input (such as flip_upper_and_lower_cases: String -> String, or word-count String -> Int) and outputs the result of applying this transform to it's own source code.
For example if the contents of the ACM file were: `ACM(f) = print f("foo")` (note that this is clearly not a correct answer in any language)
`ACM(flip_upper_and_lower_cases)` invoked from another file should yield: 'acm(F) = PRINT F("FOO")'
(please don't post a solution publicly just in case they're still using this as homework)
[1] https://www.youtube.com/watch?v=HnZipJOan54 [2] http://shem.io/
My favorite feature is that after a `gs` all the files listed are bound to sh variables $e1, $e2, etc.
This is extremely cool, by the way.
Again I wasn't being very clear, sorry about that: Kotlin doesn't always reify generics, but it can for functions you mark as inline if you want (it's useful!). Check out the inline function docs!
I'm sorry that I didn't make it clearer in my post (I'll edit it), but the thing I really appreciate is that I can use functional methods on objects (like map, fold, filter on iterables or our monadic bind method on optionals) and pass lambdas because I know it will be inlined. The inlining -- which should always happen this particular scenario (please correct me if I'm wrong) -- makes using these methods super cheap!
We wanted to iterate on a lot of the software structure we came up with for our Swift iOS app, and for a bunch of pieces we needed a powerful type system. So rather than just stick with Java -- as others have said, it's way too verbose, we started looking at alternatives. We wanted a strong type system. Scala has too much overhead for Android. Kotlin really stood out for us. This document by Jake Wharton at Square https://docs.google.com/document/d/1ReS3ep-hjxWA8kZi0YqDbEhC... made the decision easier. So we took the risk.
And we love it!
The best features:
Null type safety!
Lambdas can be inlined! No need to be afraid of anonymous inner class overhead on the map/filter/fold of iterables.
Reified generics!
Extension functions!
Single-method interfaces/classes can be represented as lambdas! aka
view.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { /* do something */ }
});
becomes view.setOnClickListener { /* do something */ }
This is great for things like RxJava.Speaking of which, the Java interoperability is fantastic. Any Android libraries we've tried work great from Kotlin.
Using these tools, we've built a simple dependency injection framework, a handful of really useful extensions on things like T? (for example monadic bind), a hack for algebraic data types and pattern matching, and of course a fairly complex app.
Android Studio's Kotlin support is fantastic (good job JetBrains!) -- it's a pleasure to use.
I think Kotlin is totally worth using. The biggest issue for us is the build time. Our build takes anywhere from 1.5 to 6 minutes depending on how much you've changed, but I've found that the type system is strong enough that you don't have to do too many build-change a line-rebuild cycles.
We'll be starting a blog soon to talk about some of the stuff we've been doing, but if you can't wait send me a message bkase at highlig.ht if you're interested in hearing more (I love talking about this stuff)
# clone and then
make && ./irscc test/main.c
open a.pdfIRSCC: Compile C code into tax forms
autoload -U add-zsh-hook
record_pwd() { pwd > ~/.cwd }
add-zsh-hook chpwd record_pwd
touch ~/.cwd
cd `cat ~/.cwd`Since people seem really interested in this, mburman and I are going to spend the day fixing up this project.
This was a final project for 15-418 in Spring of 2012 (that was a great class). We need to update it for the newer versions of CUDA, and we'll probably clean up some of our code since we're both better programmers now.
Pull-requests always welcome!