# Lurk: Lambda the Ultimate Recursive Knowledge (Experience Report) Nada Amin, John Burnham, François Garillot , Rosario Gennaro, Chhi’mèd Künzang, Daniel Rogozin, Cameron Wong ICFP 2023 --- ## Introduction ![](https://hackmd.io/_uploads/SksFgDw0n.png) ---- ### Wouldn't it be nice? - to create a proof artefact that's asymptotically faster to verify than redoing the type-checking, - to demonstrate that you have a valid proof of a theorem ... while witholding the proof (*Like Fermat !*) ---- ### This talk - NOT how we built e.g. a Lean type-checker in a Zero-knowledge proof system (see paper), - at the *cheap* cost of writing it in Lisp, - why this involved building a general-purpose FPL (Lisp-ish) interpreter, - how interpreters work in the cryptographic context, and where we'd like your help. ---- ### Warning : the word "proof" is overloaded Proofs of type-checking are an example, this isn't a talk about theorem proving. ---- ### Zero-knowledge proofs: - a protocol involving a *prover*, and a *verifier*, - the prover creates a proof of satisfiability, which is a piece of data, - For $x, y, f$ fixed publicly (known to all) the proof demonstrates: $$ \exists w, f(x, w) = y$$ - the protocol for verifying the proof is *sound* & *complete*, - $f$ must be expressed as an *arithmetic circuit*. ---- ### Other key properties - succintness: verifying the proof is at most a polylog in the size of $f$, - zero-knowledge: if the witness w is present. Hence the name SNARKs: Succint Non-interactive Arguments of Knowledge (SNARKs) ---- ### Arithmetic Circuits ```mermaid graph LR A[ ] -->|a| Add B[ ] -->|b| Add Add(+) --> |a+b| Mul C[ ] --> |c| Mul Mul(*) -->| c*a + c*b| Output[ ] ``` - and equality constraints, - input wires contain field elements. --- ### Expressing Computation as Arithmetic circuits Some ZK-proof DSLs compiling to circuits - circom, - Zokrates, - snarkyJS / snarky, - Leo, - Noir ---- ### Expressing Computation as Arithmetic circuits 1. Direct compilation approach: stepwise translation & ad-hoc combinators 2. Arithmetic circuits are a flat structure, requires flattening control and unrolling loops, 3. a *non-uniform model of computation* that really represents traces. ---- ### Loop unrolling When we don't know the iteration count, it's harder to produce the circuit: ```scheme (let ((collatz (lambda (n) (letrec ((aux (lambda (acc n) (if (= n 1) acc (let ((x (/ n 2))) (if (< x 0) ; odd (aux (+ 1 acc) (+ 1 (* 3 n))) (aux (+ 1 acc) x))))))) (aux 0 n)))) (collatz 27)) ``` ---- ### Branching ```scheme (let (f n) (if (= n 0) 1 (/ 5 n))) ``` --- ## IVC ---- ### Incrementally Verifiable Computation for SNARKs (IVC, Valiant 2008) 1. Assume you can break $f$ down as repeated $f_1\ldots f_n$ steps and verify correctness step-by-step, 4. *Traditionally*, you'd create at each step a proof of $\Pi_n$ s.t.: $$ \exists w_n, \textrm{verif}(\Pi_{n-1}) = true \wedge f_n(y_{n-1}, w_n) = y_n$$ 5. Should look like a Y combinator to you, ---- ### IVC ![](https://hackmd.io/_uploads/By8n9QuZ3.png) ([slide source: Kothapalli & al. 2022](https://www.youtube.com/watch?v=Jj19k2AXH2k)) ---- ## Nova: a most efficient IVC candidate (Kothapalli, Setty, Tzianna 2022) - cheap folding argument rather than recursion, - finish with a final SNARK over *a smaller proof statement*, - but we need a "natural" iterative form of the computation. --- ## Language definitions to the rescue! - interpreters are natively expressed as recursive applications of a step function, - the cryptographic $f$ becomes the interpreter of our language, - the user's Lisp program becomes "just" an input (e.g. $x$ n prior notation) ---- ## Definitional language interpreters A common way of defining a language : giving it an interpreter. ![](https://hackmd.io/_uploads/r1BWftV-2.png) ---- ### Interpreters and abstract machines ![](https://hackmd.io/_uploads/SkpTlKEbh.png) See e.g. _Defunctionalized Interpreters for Programming Languages_, Danvy et al. 2014 ---- ### The CEK machine ![](https://hackmd.io/_uploads/rk7BamO-h.png) ---- ### Lurk is a (fancy) iterated CEK abstract machine stepper ![](https://hackmd.io/_uploads/H1AAVKN-3.png) ---- ### Some Lurk characteristics - 12k constraints for the CEK step machine, - for comparison, a sha-256 hash function is 44k constraints, - the sha256 compression function is 27K constraints. Lurk is really small! (and *when we figure out how to do way fewer steps*, that wil mean really fast!) --- ## Writing an interpreter in the cryptographic context - state management is adversarial, - rather than passing large inputs for the state of the abstract machine, pass $commitments$ to it, - the program and its inputs/output can be arbitrarily large, or hidden, - Concretely, $H(C), H(E), H(K)$ rather than $C, E, K$. ---- ## Commitments ```scheme! > (commit 123) Iterations: 2 Result: (comm 0x2937881e) ``` ---- ### Opening commitments ```scheme! ((open 0x1aec2d8c) 9); here 9 is a salt Iterations: 12 Result: 88 ``` ---- ### Hashing all the things! - hash-consing: a classic functional programming technique to share structurally equal values, - we hash each value rigorously, and compare using hash equality, - concretely, this holds the prover accountable to a unique program, while focusing on a fragment in a given step. --- ## A taste of Lurk ---- ### Lurk is a Lisp ```scheme > (let ((collatz (lambda (n) (letrec ((aux (lambda (acc n) (if (= n 1) acc (let ((x (/ n 2))) (if (< x 0) ; odd (aux (+ 1 acc) (+ 1 (* 3 n))) (aux (+ 1 acc) x))))))) (aux 0 n)))) (collatz 27)) Iterations: 4016 Result: 111 ``` ---- ### Functional commitments ```scheme! (commit (lambda (x) (+ 7 (* x x)))) Iterations: 2 Result: (comm 0x1aec2d8c) ``` ---- ### Higher-order functional commitments ```scheme! > (let ((secret-data 555) (data-interface (lambda (f) (f secret-data)))) (commit data-interface)) Iterations: 7 Result: (comm 0x03836e2e) > ((open 0x03836e2e) (lambda (data) (+ data 111))) Iterations: 14 Result: 666 ``` --- ## Lurk release 1.0 alpha - [the blog post](https://blog.lurk-lang.org/posts/announcing-lurk-alpha/) - [the pre-print](https://eprint.iacr.org/2023/369) - and more! Specification, audit report, tutorial etc. --- ## Future work - in the cryptographic context, book-keeping steps are more expensive than abstract machines assume, - this is ripe for *formal verification*, - abstract machines (for functional PLs) are very similar : is there a general discipline for encoding them to circuits? - importantly: **if you think we are being dunces, your feedback would be a gift.**
{"title":"Lurk: Lambda the Ultimate Recursive Knowledge","slideOptions":"{\"transition\":\"slide\",\"tags\":\"Lurk, talk, crypto\"}","description":"circom,","contributors":"[{\"id\":\"dbd3a2cc-6969-479a-9e28-e36eca77e32e\",\"add\":9386,\"del\":2487}]"}
    453 views