Эх сурвалжийг харах

Merge branch 'master' of github.com:narodnik/sapvi

narodnik 5 жил өмнө
parent
commit
2618a3315f

+ 0 - 9
lisp/bits.lisp

@@ -1,9 +0,0 @@
-(def! bit-dec 
-      (fn* [x] (
-        (def! bits (unpack-bits x 256))                        
-        (def! enforce-step-1 (fn* [b] (enforce (add-one-lc0 (sub-lc0 b) (add-lc1 b))))
-        (map enforce-step-1 bits)
-        (map (fn* [b] ((add-lc0 b) double-coeff-lc) bits)                       
-        (enforce reset-coeff-lc sub-lc0 add-one-lc1)
-      )))))
-                            

+ 236 - 10
lisp/core.rs

@@ -1,3 +1,4 @@
+use rand::Rng;
 use std::fs::File;
 use std::io::Read;
 use std::rc::Rc;
@@ -13,7 +14,8 @@ use crate::types::MalVal::{
 use crate::types::{MalArgs, MalRet, MalVal, _assoc, _dissoc, atom, error, func, hash_map};
 
 use bls12_381;
-use ff::PrimeField;
+use ff::{Field, PrimeField};
+use rand::rngs::OsRng;
 
 use sapvi::bls_extensions::BlsStringConversion;
 
@@ -166,7 +168,19 @@ fn unpack_bits(a: MalArgs) -> MalRet {
     match a[0].clone() {
         Str(ref s) => {
             let value = bls12_381::Scalar::from_string(s);
-            for (_, bit) in value.to_le_bits().into_iter().cloned().enumerate() {
+            for (_, bit) in value.to_le_bits().into_iter().enumerate() {
+                match bit {
+                    true => result.push(bls12_381::Scalar::one()),
+                    false => result.push(bls12_381::Scalar::zero()),
+                }
+            }
+            Ok(list!(result
+                .iter()
+                .map(|a| Str(std::string::ToString::to_string(&a)[2..].to_string()))
+                .collect::<Vec<MalVal>>()))
+        }
+        ZKScalar(ref s) => {
+            for (_, bit) in s.to_le_bits().into_iter().enumerate() {
                 match bit {
                     true => result.push(bls12_381::Scalar::one()),
                     false => result.push(bls12_381::Scalar::zero()),
@@ -189,6 +203,7 @@ fn last(a: MalArgs) -> MalRet {
         _ => error("invalid args to first"),
     }
 }
+
 fn first(a: MalArgs) -> MalRet {
     match a[0].clone() {
         List(ref seq, _) | Vector(ref seq, _) if seq.len() == 0 => Ok(Nil),
@@ -198,6 +213,15 @@ fn first(a: MalArgs) -> MalRet {
     }
 }
 
+fn second(a: MalArgs) -> MalRet {
+    match a[0].clone() {
+        List(ref seq, _) | Vector(ref seq, _) if seq.len() < 2 => Ok(Nil),
+        List(ref seq, _) | Vector(ref seq, _) => Ok(seq[1].clone()),
+        Nil => Ok(Nil),
+        _ => error("invalid args to first"),
+    }
+}
+
 fn rest(a: MalArgs) -> MalRet {
     match a[0].clone() {
         List(ref seq, _) | Vector(ref seq, _) => {
@@ -266,10 +290,33 @@ fn sub_scalar(a: MalArgs) -> MalRet {
                 error("scalar sub expect (zkscalar, zkscalar)")
             }
         }
+        (Func(_, _), Str(a1)) => {
+            if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
+                let s1 = bls12_381::Scalar::from_string(&a1);
+                if let ZKScalar(mut a0) = values[0] {
+                    a0.sub_assign(s1);
+                    Ok(ZKScalar(a0))
+                } else {
+                    error("scalar sub expect (zkscalar, zkscalar) found (func, zkscalar)")
+                }
+            } else {
+                error("scalar sub expect (zkscalar, zkscalar)")
+            }
+        }
         (ZKScalar(mut a0), ZKScalar(a1)) => {
             a0.sub_assign(a1);
             Ok(ZKScalar(a0))
         }
+        (Str(a0), ZKScalar(a1)) => {
+            let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
+            s0.sub_assign(s1);
+            Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
+        }
+        (ZKScalar(a0), Str(a1)) => {
+            let (mut s0, s1) = (a0, bls12_381::Scalar::from_string(&a1));
+            s0.sub_assign(s1);
+            Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
+        }
         (Str(a0), Str(a1)) => {
             let (mut s0, s1) = (
                 bls12_381::Scalar::from_string(&a0),
@@ -278,7 +325,7 @@ fn sub_scalar(a: MalArgs) -> MalRet {
             s0.sub_assign(s1);
             Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
         }
-        _ => error("scalar sub expected (zkscalar, zkscalar)"),
+        _ => error(&format!("scalar sub expect (zkscalar, zkscalar) found \n {:?}", a).to_string()),
     }
 }
 
@@ -296,11 +343,44 @@ fn mul_scalar(a: MalArgs) -> MalRet {
                 error("scalar mul expect (zkscalar, zkscalar)")
             }
         }
+        (ZKScalar(a1), Func(_, _)) => {
+            if let Vector(ref values, _) = a[1].apply(vec![]).unwrap() {
+                if let ZKScalar(mut a0) = values[0] {
+                    a0.mul_assign(a1);
+                    Ok(ZKScalar(a0))
+                } else {
+                    error("scalar mul expect (zkscalar, zkscalar) found (func, zkscalar)")
+                }
+            } else {
+                error("scalar mul expect (zkscalar, zkscalar)")
+            }
+        }
         (ZKScalar(mut a0), ZKScalar(a1)) => {
             a0.mul_assign(a1);
             Ok(ZKScalar(a0))
         }
-        _ => error("scalar mul expect (zkscalar, zkscalar)"),
+        (Str(a0), Str(a1)) => {
+            let (mut s0, s1) = (
+                bls12_381::Scalar::from_string(&a0),
+                bls12_381::Scalar::from_string(&a1),
+            );
+            s0.mul_assign(s1);
+            Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
+        }
+        (ZKScalar(a0), Str(a1)) => {
+            let (mut s0, s1) = (a0,
+                bls12_381::Scalar::from_string(&a1),
+            );
+            s0.mul_assign(s1);
+            Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
+        }
+        (Str(a0), ZKScalar(a1)) => {
+            let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
+            s0.mul_assign(s1);
+            Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
+        }
+        _ => error( 
+            &format!("scalar mul expect (zkscalar, zkscalar) \n {:?}", a).to_string())
     }
 }
 
@@ -316,6 +396,17 @@ fn div_scalar(a: MalArgs) -> MalRet {
                 error("DivisionByZero")
             }
         }
+        (Str(a0), ZKScalar(a1)) => {
+            let (s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
+            let ret = s1.invert().map(|other| *&s0 * other);
+            if bool::from(ret.is_some()) {
+                Ok(Str(
+                    std::string::ToString::to_string(&ret.unwrap())[2..].to_string()
+                ))
+            } else {
+                error("DivisionByZero")
+            }
+        }
         (Str(a0), Str(a1)) => {
             let (s0, s1) = (
                 bls12_381::Scalar::from_string(&a0),
@@ -330,7 +421,8 @@ fn div_scalar(a: MalArgs) -> MalRet {
                 error("DivisionByZero")
             }
         }
-        _ => error("scalar div expected (scalar, scalar)"),
+        _ => error( 
+            &format!("scalar div expect (zkscalar, zkscalar) \n {:?}", a).to_string())
     }
 }
 
@@ -348,10 +440,13 @@ fn range(a: MalArgs) -> MalRet {
 }
 
 fn scalar_zero(a: MalArgs) -> MalRet {
-    Ok(vector![vec![
-        ZKScalar(bls12_381::Scalar::zero()),
-        a[0].clone()
-    ]])
+    match a.len() {
+        0 => Ok(vector![vec![ZKScalar(bls12_381::Scalar::zero())]]),
+        _ => Ok(vector![vec![
+            ZKScalar(bls12_381::Scalar::zero()),
+            a[0].clone()
+        ]]),
+    }
 }
 
 fn scalar_one(a: MalArgs) -> MalRet {
@@ -396,6 +491,101 @@ fn scalar_from(a: MalArgs) -> MalRet {
     }
 }
 
+fn scalar_square(a: MalArgs) -> MalRet {
+    match a[0].clone() {
+        ZKScalar(a0) => {
+            let z0 = a0.clone();
+            Ok(ZKScalar(z0.square()))
+        }
+        Str(a0) => {
+            let s0 = bls12_381::Scalar::from_string(&a0);
+            Ok(ZKScalar(s0.square()))
+        }
+        _ => error(
+            &format!("scalar square expect (zkscalar or string) found \n {:?}", a).to_string(),
+        ),
+    }
+}
+
+fn scalar_double(a: MalArgs) -> MalRet {
+    match a[0].clone() {
+        ZKScalar(a0) => {
+            let z0 = a0.clone();
+            Ok(ZKScalar(z0.double()))
+        }
+        Str(a0) => {
+            let s0 = bls12_381::Scalar::from_string(&a0);
+            Ok(ZKScalar(s0.double()))
+        }
+        _ => error(
+            &format!("scalar double expect (zkscalar or string) found \n {:?}", a).to_string(),
+        ),
+    }
+}
+
+fn scalar_invert(a: MalArgs) -> MalRet {
+    match a[0].clone() {
+        Func(_, _) => {
+            if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
+                if let ZKScalar(a0) = values[0] {
+                    if a0.is_zero() {
+                        error(
+                            &format!("scalar invert divizion by zero \n {:?}", a0).to_string())
+                    } else {
+                        Ok(ZKScalar(a0.invert().unwrap()))        
+                    }
+                } else {
+                    error(
+                        &format!("scalar invert expect (zkscalar or string) found \n {:?}", a).to_string())
+                }
+            } else {
+                error(
+                    &format!("scalar invert expect (zkscalar or string) found \n {:?}", a).to_string())
+            }
+        }
+        ZKScalar(a0) => {
+            let z0 = a0.clone();
+            Ok(ZKScalar(z0.invert().unwrap()))
+        }
+        Str(a0) => {
+            let s0 = bls12_381::Scalar::from_string(&a0);
+            Ok(ZKScalar(s0.invert().unwrap()))
+        }
+        _ => error(
+            &format!("scalar invert expect (zkscalar or string) found \n {:?}", a).to_string(),
+        ),
+    }
+}
+
+fn scalar_is_zero(a: MalArgs) -> MalRet {
+    match a[0].clone() {
+        Func(_, _) => {
+            if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
+                if let ZKScalar(a0) = values[0] {
+                    Ok(Bool(a0.is_zero()))        
+                } else {
+                    error(
+                        &format!("scalar is zero expect (zkscalar or string) found \n {:?}", a).to_string())
+                }
+            } else {
+                error(
+                    &format!("scalar is zero expect (zkscalar or string) found \n {:?}", a).to_string())
+            }
+        }
+        ZKScalar(a0) => {
+            let z0 = a0.clone();
+            Ok(Bool(z0.is_zero()))
+        }
+        Str(a0) => {
+            let s0 = bls12_381::Scalar::from_string(&a0);
+            Ok(Bool(s0.is_zero()))
+        }
+        _ => error(
+            &format!("scalar is zero expect (zkscalar or string) found \n {:?}", a).to_string(),
+        ),
+    }
+}
+
 fn add_scalar(a: MalArgs) -> MalRet {
     match (a[0].clone(), a[1].clone()) {
         (Func(_, _), ZKScalar(a1)) => {
@@ -410,9 +600,22 @@ fn add_scalar(a: MalArgs) -> MalRet {
                 error("scalar add expect (zkscalar, zkscalar)")
             }
         }
+        (Func(_, _), Str(a1)) => {
+            if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
+                if let ZKScalar(mut a0) = values[0] {
+                    let s1 = bls12_381::Scalar::from_string(&a1);
+                    a0.add_assign(s1);
+                    Ok(ZKScalar(a0))
+                } else {
+                    error("scalar add expect (zkscalar, zkscalar) found (func, zkscalar)")
+                }
+            } else {
+                error("scalar add expect (zkscalar, zkscalar)")
+            }
+        }
         (ZKScalar(a0), ZKScalar(a1)) => {
             let (mut z0, z1) = (a0.clone(), a1.clone());
-            z0.add_assign(z1);
+            z0.add_assign(z1);        
             Ok(ZKScalar(z0))
         }
         (Str(a0), Str(a1)) => {
@@ -423,6 +626,11 @@ fn add_scalar(a: MalArgs) -> MalRet {
             s0.add_assign(s1);
             Ok(ZKScalar(s0))
         }
+        (Str(a0), ZKScalar(a1)) => {
+            let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
+            s0.add_assign(s1);
+            Ok(ZKScalar(s0))
+        }
         _ => error(&format!("scalar add expect (zkscalar, zkscalar) found \n {:?}", a).to_string()),
     }
 }
@@ -440,6 +648,17 @@ fn seq(a: MalArgs) -> MalRet {
     }
 }
 
+fn gen_rand(a: MalArgs) -> MalRet {
+    let mut rng = rand::thread_rng();
+    Ok(MalVal::Int(rng.gen::<i64>()))
+}
+
+fn scalar_rnd(a: MalArgs) -> MalRet {
+    let randomness_value: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+    let value = bls12_381::Scalar::from_bytes(&randomness_value.to_bytes());
+    Ok(MalVal::ZKScalar(value.unwrap()))
+}
+
 pub fn ns() -> Vec<(&'static str, MalVal)> {
     vec![
         ("=", func(|a| Ok(Bool(a[0] == a[1])))),
@@ -542,6 +761,13 @@ pub fn ns() -> Vec<(&'static str, MalVal)> {
         ("neg", func(negate_from)),
         ("scalar::zero", func(scalar_zero)),
         ("scalar", func(scalar_from)),
+        ("square", func(scalar_square)),
         ("cs::one", func(cs_one)),
+        ("second", func(second)),
+        ("genrand", func(gen_rand)),
+        ("double", func(scalar_double)),
+        ("invert", func(scalar_invert)),
+        ("zero?", func(scalar_is_zero)),
+        ("rnd-scalar", func(scalar_rnd)),
     ]
 }

+ 52 - 0
lisp/examples/jubjub-add-macro.lisp

@@ -0,0 +1,52 @@
+(println "jubjub-add-macro.lisp")
+(load-file "util.lisp")
+
+(defmacro! jubjub-add (fn* [param1 param2 param3 param4]
+    (let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
+           EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
+           C (gensym) u3 (gensym) v3 (gensym)] (
+        `(def! ~u1 (alloc ~u1 param1))
+        `(def! ~v1 (alloc ~v1 param2))
+        `(def! ~u2 (alloc ~u2 param3))
+        `(def! ~v2 (alloc ~v2 param4)) 
+        `(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
+        `(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
+        `(def! ~A (alloc ~A (* ~v2 ~u1)))
+        `(def! ~B (alloc ~B (* ~u2 ~v1)))
+        `(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
+        `(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
+        `(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))        
+  `(enforce  
+    ((scalar::one ~u1) (scalar::one ~v1))
+    ((scalar::one ~u2) (scalar::one ~v2))
+    (scalar::one ~U)
+   )
+  `(enforce
+    (~EDWARDS_D ~A)
+    (scalar::one ~B)
+    (scalar::one ~C)
+   )
+  `(enforce
+    ((scalar::one cs::one)(scalar::one ~C))
+    (scalar::one ~u3)
+    ((scalar::one ~A) (scalar::one ~B))
+   )
+  `(enforce
+    ((scalar::one cs::one) (scalar::one::neg ~C))
+    (scalar::one ~v3)
+    ((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
+   )
+  )
+  ;; improve return values
+)
+))
+
+(def! param4 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
+(def! param3 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
+(def! param2 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
+(def! param1 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
+
+(prove (
+    (def! result1 (jubjub-add param1 param2 param3 param4))
+    (println 'jubjub-result result1)
+))

+ 79 - 0
lisp/examples/jubjub.lisp

@@ -0,0 +1,79 @@
+(println "jubjub-add.lisp")
+(load-file "util.lisp")
+
+(defmacro! zk-square (fn* [var] (
+        (let* [v1 (gensym)
+               v2 (gensym)] (
+        `(alloc ~v1 ~var)
+        `(alloc ~v2 (square ~var))
+        `(enforce  
+            (scalar::one ~v1) 
+            (scalar::one ~v1) 
+            (scalar::one ~v2) 
+        )
+        )
+    ))
+))
+
+;; -u^2 + v^2 = 1 + du^2v^2
+(defmacro! zk-witness (fn* [val1 val2] (
+        (let* [v (gensym)
+               u (gensym)
+               u2v2 (gensym)] (
+        `(alloc ~v1 ~var)
+        `(alloc ~v2 (square ~var))
+        `(enforce  
+            (scalar::one ~v1) 
+            (scalar::one ~v1) 
+            (scalar::one ~v2) 
+        )
+        )
+    ))
+))
+
+(defmacro! jubjub-add (fn* [param1 param2 param3 param4]
+    (let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
+           EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
+           C (gensym) u3 (gensym) v3 (gensym)] (
+        `(def! ~u1 (alloc ~u1 param1))
+        `(def! ~v1 (alloc ~v1 param2))
+        `(def! ~u2 (alloc ~u2 param3))
+        `(def! ~v2 (alloc ~v2 param4)) 
+        `(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
+        `(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
+        `(def! ~A (alloc ~A (* ~v2 ~u1)))
+        `(def! ~B (alloc ~B (* ~u2 ~v1)))
+        `(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
+        `(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
+        `(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))        
+  `(enforce  
+    ((scalar::one ~u1) (scalar::one ~v1))
+    ((scalar::one ~u2) (scalar::one ~v2))
+    (scalar::one ~U)
+   )
+  `(enforce
+    (~EDWARDS_D ~A)
+    (scalar::one ~B)
+    (scalar::one ~C)
+   )
+  `(enforce
+    ((scalar::one cs::one)(scalar::one ~C))
+    (scalar::one ~u3)
+    ((scalar::one ~A) (scalar::one ~B))
+   )
+  `(enforce
+    ((scalar::one cs::one) (scalar::one::neg ~C))
+    (scalar::one ~v3)
+    ((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
+   )
+  )
+  ;; improve return values
+)
+))
+
+(prove 
+  (
+    (def! result-witness (zk-witness param1 param2))
+    (println 'result-witness (nth (nth result-witness 0) 1))   
+  )
+)

+ 289 - 0
lisp/examples/macro-test.lisp

@@ -0,0 +1,289 @@
+(load-file "util.lisp")
+
+(def! zk-not-small-order? (fn* [u v] (
+        (def! first-doubling (last (last (zk-double u v))))
+        (def! second-doubling (last (last 
+            (zk-double (get first-doubling "u3") (get first-doubling "v3")))))
+        (def! third-doubling (last (last 
+            (zk-double (get second-doubling "u3") (get second-doubling "v3")))))
+        (zk-nonzero? (get third-doubling "u3"))
+        )
+    )
+)
+
+(defmacro! zk-nonzero? (fn* [var] (
+        (let* [inv (gensym)
+               v1 (gensym)] (
+        `(alloc ~inv (invert ~var))
+        `(alloc ~v1 ~var)
+        `(enforce  
+            (scalar::one ~v1) 
+            (scalar::one ~inv) 
+            (scalar::one cs::one) 
+         )
+        )
+    ))
+))
+
+(defmacro! zk-square (fn* [var] (
+        (let* [v1 (gensym)
+               v2 (gensym)] (
+        `(alloc ~v1 ~var)
+        `(def! output (alloc-input ~v2 (square ~var)))
+        `(enforce  
+            (scalar::one ~v1) 
+            (scalar::one ~v1) 
+            (scalar::one ~v2) 
+         )
+        `{ "v2" output }
+        )
+    ))
+))
+
+(defmacro! zk-mul (fn* [val1 val2] (
+        (let* [v1 (gensym)
+               v2 (gensym)
+               var (gensym)] (
+        `(alloc ~v1 ~val1)
+        `(alloc ~v2 ~val2)
+        `(def! result (alloc-input ~var (* ~val1 ~val2)))
+        `(enforce  
+            (scalar::one ~v1) 
+            (scalar::one ~v2) 
+            (scalar::one ~var) 
+         )
+        `{ "result" result }
+        )
+    ))
+))
+
+(defmacro! zk-witness (fn* [val1 val2] (
+        (let* [u2 (gensym)
+               v2 (gensym)
+               u2v2 (gensym)
+               EDWARDS_D (gensym)] (
+        `(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
+        `(def! ~u2 (alloc ~u2 (get (nth (nth (zk-square ~val1) 0) 3) "v2")))
+        `(def! ~v2 (alloc ~v2 (get (nth (nth (zk-square ~val2) 0) 3) "v2")))
+        `(def! result (alloc-input ~u2v2 (get (last (last (zk-mul ~u2 ~v2))) "result")))        
+        `(enforce  
+            ((scalar::one::neg ~u2) (scalar::one ~v2))
+            (scalar::one cs::one)
+            ((scalar::one cs::one) (~EDWARDS_D ~u2v2))
+         )
+        `{ "result" result }
+        )
+    ))
+))
+
+(defmacro! zk-double (fn* [val1 val2] (
+        (let* [u (gensym)
+               v (gensym)
+               u3 (gensym)
+               v3 (gensym)
+               T (gensym)
+               A (gensym)
+               C (gensym)
+               EDWARDS_D (gensym)] (
+        `(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
+        `(def! ~u (alloc ~u ~val1))
+        `(def! ~v (alloc ~v ~val2))
+        `(def! ~T (alloc ~T (* (+ ~val1 ~val2) (+ ~val1 ~val2))))
+        `(def! ~A (alloc ~A (* ~u ~v)))
+        `(def! ~C (alloc ~C (* (square ~A) ~EDWARDS_D)))
+        `(def! ~u3 (alloc-input ~u3 (/ (double ~A) (+ scalar::one ~C))))
+        `(def! ~v3 (alloc-input ~v3 (/ (- ~T (double ~A)) (- scalar::one ~C))))
+        `(enforce  
+            ((scalar::one ~u) (scalar::one ~v))
+            ((scalar::one ~u) (scalar::one ~v))
+            (scalar::one ~T)
+         )
+         `(enforce  
+            (~EDWARDS_D ~A)
+            (scalar::one ~A)
+            (scalar::one ~C)
+         )
+         `(enforce  
+            ((scalar::one cs::one) (scalar::one ~C))
+            (scalar::one ~u3)
+            ((scalar::one ~A) (scalar::one ~A))    
+         )
+         `(enforce  
+            ((scalar::one cs::one) (scalar::one::neg ~C))
+            (scalar::one ~v3)
+            ((scalar::one ~T) (scalar::one::neg ~A) (scalar::one::neg ~A))    
+         )    
+        { "u3" u3, "v3" v3 }
+        )
+    ))
+))
+
+(defmacro! conditionally-select (fn* [val1 val2 val3] (
+        (let* [u-prime (gensym)
+               v-prime (gensym)
+               u (gensym)
+               v (gensym)
+               condition (gensym)
+               ] (
+            `(def! ~u (alloc ~u ~val1))
+            `(def! ~v (alloc ~v ~val2))
+            `(def! ~condition (alloc ~condition ~val3))
+            `(def! ~u-prime (alloc-input ~u-prime (* ~u ~condition)))
+            `(def! ~v-prime (alloc-input ~v-prime (* ~v ~condition)))
+            `(enforce
+                (scalar::one ~u)
+                (scalar::one ~condition)
+                (scalar::one ~u-prime)
+             )
+            `(enforce
+                (scalar::one ~v)
+                (scalar::one ~condition)
+                (scalar::one ~v-prime)
+             )
+             { "u-prime" u-prime, "v-prime" v-prime }
+        )
+))))
+
+(defmacro! jj-add (fn* [param1 param2 param3 param4]
+    (let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
+           EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
+           C (gensym) u3 (gensym) v3 (gensym)] (
+        ;; debug
+        ;; `(println 'jj-add ~param1 ~param2 ~param3 ~param4)
+        `(def! ~u1 (alloc ~u1 ~param1))
+        `(def! ~v1 (alloc ~v1 ~param2))
+        `(def! ~u2 (alloc ~u2 ~param3))
+        `(def! ~v2 (alloc ~v2 ~param4)) 
+        `(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
+        `(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
+        `(def! ~A (alloc ~A (* ~v2 ~u1)))
+        `(def! ~B (alloc ~B (* ~u2 ~v1)))
+        `(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
+        `(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
+        `(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))        
+  `(enforce  
+    ((scalar::one ~u1) (scalar::one ~v1))
+    ((scalar::one ~u2) (scalar::one ~v2))
+    (scalar::one ~U)
+   )
+  `(enforce
+    (~EDWARDS_D ~A)
+    (scalar::one ~B)
+    (scalar::one ~C)
+   )
+  `(enforce
+    ((scalar::one cs::one)(scalar::one ~C))
+    (scalar::one ~u3)
+    ((scalar::one ~A) (scalar::one ~B))
+   )
+  `(enforce
+    ((scalar::one cs::one) (scalar::one::neg ~C))
+    (scalar::one ~v3)
+    ((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
+   ) 
+   `{ "u3" u3, "v3" v3 }
+  )  
+)
+))
+
+;; cs.enforce(
+;;     || "boolean constraint",
+;;     |lc| lc + CS::one() - var,
+;;     |lc| lc + var,
+;;     |lc| lc,
+;; );
+(defmacro! zk-boolean (fn* [val] (
+        (let* [var (gensym)] (
+            `(alloc ~var ~val)
+            `(enforce
+                (scalar::one cs::one) (scalar::one ~var)
+                (scalar::one ~var)
+                ()
+             )
+        )
+))))
+
+(def! jj-mul (fn* [u v b] (
+    (def! result (unpack-bits b))
+    (eval (map zk-boolean result))
+    (def! val (last (last (zk-double u v))))
+    (def! acc 0)
+    (dotimes (count result) (                    
+        (def! acc (i+ acc 1))        
+        (def! u3 (get val "u3"))
+        (def! v3 (get val "v3"))            
+        (def! r (nth result acc))        
+        (def! cond-result (last (last (conditionally-select u3 v3 r))))
+        (def! u-prime (get cond-result "u-prime"))
+        (def! v-prime (get cond-result "v-prime"))        
+        (def! add-result (last (jj-add u3 v3 u-prime v-prime)))               
+        (def! u-add (get add-result "u3"))
+        (def! v-add (get add-result "v3"))        
+        (def! val (last (last (zk-double u-add v-add))))             
+        ;; debug
+        (println 'first-double val)
+        (println 'r r)
+        (println 'cond cond-result)
+        (println 'add add-result)
+        (println 'double acc val)        
+    ))
+    (println 'out val)
+)))
+
+(load-file "mimc-constants.lisp")
+(defmacro! mimc-macro (fn* [xr xl acc] (
+    (let* [tmp-xl (gensym) xl-new-value (gensym) cur-mimc-const (gensym)] (
+    `(def! ~cur-mimc-const (alloc-const ~cur-mimc-const (nth mimc-constants ~acc)))
+    `(def! ~tmp-xl (alloc ~tmp-xl (square (+ ~cur-mimc-const ~xl))))        
+    `(enforce 
+        ((scalar::one xl) (~cur-mimc-const cs::one))
+        ((scalar::one xl) (~cur-mimc-const cs::one))
+        (scalar::one ~tmp-xl)
+    )        
+    (if (= acc 321)
+        `(def! ~xl-new-value (alloc ~xl-new-value (+ (* ~tmp-xl (+ ~cur-mimc-const ~xl)) ~xr)))    
+        `(def! ~xl-new-value (alloc-input ~xl-new-value (+ (* ~tmp-xl (+ ~cur-mimc-const ~xl)) ~xr)))    
+    )
+    `(enforce 
+        (scalar::one ~tmp-xl)
+        ((scalar::one xl) (~cur-mimc-const cs::one))            
+        ((scalar::one ~xl-new-value) (scalar::one::neg xr))            
+    )
+)))))
+(def! mimc (fn* [left right] (
+    (def! xl (alloc "xl" left))
+    (def! xr (alloc "xr" right))
+    (def! acc 0)
+    (dotimes 322 (
+        (println (mimc-macro xl xr acc))
+        (def! acc (i+ acc 1))
+        (println acc)
+    ))
+)))
+
+(def! param3 (rnd-scalar))
+;; (println 'rnd-scalar param3)
+(def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
+(def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
+(prove 
+  (
+    ;; (jj-mul param-u param-v param3)
+    (mimc param-u param-v)
+  )
+)
+
+;; following some examples 
+;; (def! alloc-u (alloc "alloc-u" param-u))
+;;     (def! alloc-v (alloc "alloc-v" param-v))
+;;     (def! condition (alloc "condition" param3))
+;;     (println 'conditionally_select 
+;;         (conditionally_select alloc-u alloc-v condition))
+;; (println (zk-mul param1 param2))
+;; (def! param1 (scalar 3))
+;; (def! param2 (scalar 9))
+;; (println (zk-square param1))
+;; (println (zk-mul param1 param2))
+;; (println 'witness (zk-witness param-u param-v))
+;; (println 'double (last (last (zk-double param-u param-v))))
+;; (println 'nonzero (zk-nonzero? param3))    
+;; (println 'not-small-order? (zk-not-small-order? param-u param-v))

+ 323 - 0
lisp/examples/mimc-constants.lisp

@@ -0,0 +1,323 @@
+(def! mimc-constants ("4699afdd3f9ce9916eaffcfbef597c5009ae9d3209c3b15feb6928a4a8d4b59e"
+"41e2431761fee4a40b468524d91b3d64590b3c242de10d18f55f0c5e3883ef02" 
+"5a04a1ea758bf1cc1140fcec1ce2c9d68da53d6cf7ee8dfeedfb2ee45db08c27"
+"2e4b930078e93e73581d7b71120a8e8b9627955a0aabf139bbfa5feceaab2e3b"
+"6a9db69e4fd0a3f94402cf22076bd18300c344c69bf665542129ad887f0030ab"
+"4458f2de4e16ce2ead3fe9dd164cca36d2b70a25e71f55cf0c51ca553a4f83ad"
+"04f539ab6ea2d344049219c720a16c4e6033f8360b124519fdbb6d441428143b"
+"6b9c7b12a4b3cf92e2f2b386426058709573f9abdf1bcc5411dacd7ea0eaf8f3"
+"4375e3120921697155b3ea15c32b9412adce3a8ff8e28e1b8c95935cc71ad853"
+"041854bb643e9e5e5d8aa6e828dc4c732c8fa24192a160f40da85737372c5d0c"
+"65d9cc7ab2a2060d198d66310a902bddeeb7f5150173190036d2fae68de1c2b9"
+"1e7d2b472c6a40254a228b0543aff318084e7f6152617a6cf7fc405d917bfc37"
+"35293381012ebaf649d8c6db4e4d5e594bd114c99c234ddff7b9b5f6f8a9ec36"
+"3a50794418ac54a1467578ed61e34d8be5d52c5f188f42955fe8d5e257ad3e89"
+"446d905f60110dbd51129896a63a0e34bb0502101ad6311998ad2dfd74818277"
+"3eee70356bab144c54b5fc1095f9bce59c727a57a5582dcbbd5c3afc3c61ceca"
+"40b08ae056833e12c82f7e15e2dc72febc15d3275b51ec70afaffa6ce8bbb3d0"
+"205923e6eb137869a552b4857bb64f946c912f3335a94291ebb8b29ecd3e6034"
+"2a6aebced756f7e33c466bca2169ba24c471a088c8363fe0a966a223fd3b59ea"
+"566efaf4e022036a8e073fd9812376888ac9f37c794daebe3fa77b1a87bf109e"
+"1ee814f2660e7272712d588477e458c06f8f06950402e97c542d3682ad5f9aed"
+"257fe0ace4965622be247dba9185f108707f4ab16c910c03c565afab43b0fb4f"
+"43e156f0cad02ff6b763645c97663ab72229bb0a34f975681359797ccd58093c"
+"317f43b78cc26f0332a3ec3ec187332d4de0f2baf04f62fe76bee9b11256130b"
+"076ca6cd23830e3b3ece767b774e1b2243408098a7c5b816e7c616cb88f6b916"
+"14e30a644f034c72cf40b1bc790200c2e8ab3e750e38f3fb0160188e817e4560"
+"02eb02bfbac795a497a0882d66b718bb23de64f9fe7644179ddd3241cc407942"
+"644f175cf6f2268d451e5188e467c508bc91d870646de9297911be2aedf26daf"
+"14aef8f4f5499a0387e521a1c6064094590f149c52fb99e37b583434ca6bd46c"
+"2ddc7c6bba8895913f3deee128bc63b5e34797274de80da775c4a0c810ac60e6"
+"46adc33428a63a20459699183272b14797a5a7d1d66079701d214bced9a4be71"
+"552847d9a2a5b03f726b277ba01ad61c0e28114667e7a9e11229b83224f74349"
+"624921e44f5811f76c06ab74a11ad56e5241e4c597e9d172ee3c862bf6d4b1fd"
+"506af906fab5f9407ee71824d72dfcd99115c5a2eb53b55a1d5877910a645282"
+"514ddde7e75b27ae6f31efb7375bc209dcdd0ab4c277ee0f8b362cb5211def31"
+"2e3be2e2a10f8e24b411902d9578d44e2a4a5042036ecc397e1cc5ab88e76329"
+"61755a2f6a9729a3bd8d21aea98f4cf885aa1751a714e251a517395711674bf5"
+"68f8f91713d81c2a6d601411447e944c27f7a1862855b940ef3521cbf4074e96"
+"32e6b3dfaa0162846620ace97838a93f48999b5bbc078964687c795a9e5b71a0"
+"3c783bf0caa35bd381603b9e3aa5dbcc4ed4fc93b03d69a49fa15286a6374f8d"
+"4a3f322f033de27244d79dd5c6c2f34d84c24c917ce95cfb6458d72124280e70"
+"3ee0abb7af79168e05566994017fade2d69bdb55c4253f996362b73d49f3f70e"
+"15498a06e80c6060320e9a01292ee1a805c2aafd7b92f76b5f5e8be515e0a3b3"
+"02424410de65455350831f5b1c3554626f6bbf373ed0f627b42f0d3ec2fdd487"
+"5886da407f6014665272b45d213cb388987503398d407732f278c9a35267622d"
+"15f6180f287d2ef5d9d057dc18eb7df732d97632bfb31e93ac065dcf0c67fd40"
+"65f5dc85c9660f184a09ee768ae9af0f62911af31920d3b5c49ac0360d261441"
+"65751a6bbccb0ea7fd79fe7231d03d2f14ec6a24c5d9c4a77d1a86acf3d027a9"
+"4c21c6990442cb96b2ca684c9d427dc41090447248378f50b4de15b616f1f133"
+"34cde97ef5c2459e29dbad8324fbefa5097f744f737cc59ad2681e49dfa43f99"
+"5df3e3787510f9e2b32beb2fdf76fc6d646b3fb94d4ede65309762fc515ffb55"
+"30394778b396dd8191e78cb7627636eb82b15b0de788c1e2db2788b05caedd8b"
+"695a64cc6953c658f40c1c2666715790410e302d3d902fcb809924896c2d1f4e"
+"6a4fe5863990f4b4d588841b0e52c4dc7a8c4644edfec7c721ab66b162ec5de9"
+"62e4428cb1856ae809589806e5e7869ab0fb818d6c0a696d94ee616fe549400e"
+"0b1e8a6d6581c13b6888d0bd9816bda3695f917d03510d9b42452f3501e3d55a"
+"5e5a2b767f853d0f0bf0e3cae872fb942065db112cb48a12dbce3ce4da28aa87"
+"2c1c59e21a9741edbaf1e5a275c573bbeb395c6a79abdd0e532e000298dc8c00"
+"25d648572388935cac47095b4f38b3ebe6519766a0d03bf7de9b4368b7bc1b58"
+"475a00fdc58c8a7092cae8942af520dd5e0f476dc469f0c3e908da68be55e6ff"
+"3fe62baf8e0a5286b0055e16e712ad06d233fa71fb374557d4c3d585e33dd37b"
+"54d74923f593c55659f92b34bf5c05a400187e143850173786c8a1dd2f3a1283"
+"6aa3afe84262b6c5bc8994a2c0e66a64a534904efcf47ead067fa09cd2d58a6a"
+"2069d079cd963cec28ccac413172576ace57da0b4ab502c11289fff6ff2de6eb"
+"364b3a05a8b1271aa61d5894b51a445c5896e86a535869b70e56e1e0f7f49f42"
+"1c904753197233afda76661025e67f6a8e7a5c209292e151a7f34119397c281f"
+"45f6d1ed8bc4395ccc6cfc90a1cf5f636248e966d82d040d795014f5d184b3ac"
+"1bdbb396d84fe4c8b5b230e1c925e9f0f5f88faea9b713b319c7c11c307cbdbe"
+"347c35497a65e93d8f4ec06c1546991841fd680868e145849195e38ef783d1a4"
+"1d9c23cb0d4a20c384d629c6e706ebaf12fe0fc4eb0860c8175e687742e941cc"
+"59378cc30bc5948d66a6f1671e84e2e9ef342e0e3dd682015d93f96a68159f3a"
+"59992c34faff2238e03be3d6e87086a427e6eef2c5647a690363a9ddc0c82d67"
+"60b13d9cae9b2504ca982c50b14ee5a628d40832bab95108e6640b9a8ef8a853"
+"4cea35b5ebf7d7956c0c592d4238051c37bdb8bcb4c08fa29239ffaff00793bf"
+"25344d0db88e9df26d216c287ddc36a958ba1e4d4c05a9cd59715de870d47e36"
+"19a1c0a1f3aa80db57b014a2dad65eecf645fcd442a09b97e78d044a50ba58c3"
+"32a6b9ba275d0204fd0e3de5fed3eac823aa8ce0ef5eca627fe92030e4506fe3"
+"4e4f1056e9e3b8861117ba8bba1a1c37e784ef9e1358473aa55156e3b1523dff"
+"710f51f9f3866ab261df0fad6ad3986f75d9990bf7776f4e4775f9c8f95045c2"
+"48623d21c816d6a47a6339d9bda7ff31f2b32b8491c72967b93f2734ec37f64d"
+"69aae3a126e0625c52d05e8c98ea912f56a582419cef7f13f31be66ec14bd43c"
+"2f7264fc97a0ff9188c506d5df4bf3d4f28cb1d12fa2767e18d023f8a7e907b0"
+"54bf8632b89211a06bbf9c0ee5ba2328b1f2cbc1892b76282599c0fb432d761d"
+"0deb44dd3e20b34cfb473944f4f8f07b4d337da0fc18021777c983bf3e4e7f44"
+"37a108a7b9e612231e21f0b4c7186163e3cc59325cbb17a39e1e25b4c4345dba"
+"317515ddac6dcb33a4ac68d4c02c6d93d147b61cd892474292258ebceaf5ce83"
+"38e225b4f524fa89f414976687473eb4c5f3edfe983dbdd07d3e8486f3b93c0a"
+"636b27e505a14fb8362beb2e436582db991e3089e6edaeb9aaba3d67f58c8c60"
+"28fd1afb8cf1e9c7594b5b8d6b50ff1f81aa19f211c5c271f2181836158bb625"
+"1a8cf4f8569d80ca7d878d7a76d959956ac5e7edb37fbcfd2f5d130e3841dbc0"
+"2cfbffcc25a0a01ab7cd1e700030d0e363ac170dd000397fa83d107a6d12bd54"
+"325355d6824f71f550b102c6fa6c8c129de58d325174c5981c562e606a58c55f"
+"1716f66b4ad2388a23ce111dd5ff7c04d4478dd81930050fdf0c4a90fcd6d381"
+"02992cefec8ee9bef9602858d51c87a2c4180d9fe0c02e6c6003531010793572"
+"2132b3fd309dd69a9f3c39b450534d857721dd5a2bcb23b479a29b08e8f8551e"
+"369986658b8e7e4f990fd6fc09b99a056d81ee47c7a9e46b4109d8af0956678c"
+"25e00309f0c3097a6500df9ed5587ec128b20a97379814b4a0522f7e775a4548"
+"529a8ecdddfb500c68b664f7303dad768da802c29a933801b2199cf74a3470f5"
+"3cf98a6dc8290785ede38da9455dbd28a64a1bda35a48d6c6b1b35ba6df3268b"
+"127401f379aa992d492782910baee0fb331b3e9c1a66492c9b002a37999f356a"
+"449dabe3e12e7b495e0421de157acbd4b3852cb824bba7171c8e3da565e3f95e"
+"410d1d4fb041736101f5468ebdfd9380f2066593534339bc419f35d530c92cd7"
+"09747f87db187d67e7881e1b64345754ec9bc9ec353e9b055bc377f1618ef17e"
+"5fec471449175525c56b18200dd8ab96b2f9ee383849545628f0ceff76f631d8"
+"0c7e402c723170d5dc5f15e229f4bacc5eb50b34dbfb6129215ee662288e159c"
+"158896654586f5c3a34808ef7ab93def61fc9257d5b7631ed6869259a45d1d01"
+"57ab3eab90ec38cfb23625e7110948e4b56e38a1ccc2cfffc344876d28aceddd"
+"08d08f8650f5ca7bf03aad9a80ae09c697327a131827a9c2aec67d1d9f58064e"
+"273607089f1e9c2b99812e032dfb62c359438c76556a15692a3de02b8c13df4d"
+"55bf5cd5a1a89d7e3d1d274cc5b1b765e42a9eab5cfd32148c1633550ecfffce"
+"5c4f6e0acb889fbb573583767535e95bc537641769c35063c0bd3a65812ade57"
+"581faa1d0a57ef947001fd8e57eee26e645d15eebedb7ebb1d85581968544ca6"
+"48b77ab45f5fb6d615bd759a6661097bb8a3b5c27ba35f1b127d2ee12f043bc4"
+"590618389009da43c679b6254ae4cc86dbfa397981f4dff30e064e07bfdc9eab"
+"3ef9bd95ccaa3c577ab98d3fad87fe69953bbbba6c8bbca0301a6c88e9bed8e6"
+"2bc1dd87795feb2a5e8d98759371592ba7147ee4c2a3473d18c496ebe3721216"
+"620ba5be31e353f1f3c72a4380f32c016f0746f5446f9e1743fb01fe6994051e"
+"151d0bcf972db311553ef8da672b1c861d118e9b78da632d24c49d4a0fa177b7"
+"01f1bda7ed65ad241d6fa13d8c5cb40cc335a0b2a31b433f2c65cb01e8dad5bc"
+"4aec58578fdfd5e59d18063bdcc69086dae303518f5155facdc2824878862c53"
+"1ca2d39cd13b6c690faf2be3da4d4517e28244fbf9ca0f8f4d80565205fb86f2"
+"72432f39b454d6457ffae81f2e843df03c1526920384c50136beca0627f9054a"
+"1910c2e6bb35a12e22ec46cd0db6185f352bf3581cf46d2f9c494daf8d94b993"
+"4e47d6f9080e682d34ae07d5886c29869d16324c468782bea9c62334b583251f"
+"3240024a0dd08da0c135caf8114ea8d333ab181e94a3a01edabb760a64adcee4"
+"1669aabbd01c4541575f150981af0cf9a196e0b98908af53ea14b81734ecce5a"
+"316aa08fd611919a73b60dc2b3175b3843f17035d71b9edf2f72c32850629574"
+"4919d1e48c28eb1d36a689d8a5826c4ae4cd4e84a8347a9c9238b825a0b53a8e"
+"4572211d4d1c8257d142ff2335eea65ccbf3177a982fed00931410f3bdf08c19"
+"5d2d04f110bb9a50adf25427b232870f2be2307685f19df47f9b2f1bae984a04"
+"472609c977c6854de75985c9154f70a7fda1843a38f10dd4985ab8dc353ad5a7"
+"5c2ba4f8bec80b52e65afbe7b2ff41ad73542275e40acba8730403e9e33c7697"
+"267614d22d526f429346fb2e9dcc4930880971780e85ef44a199feabe2b48227"
+"1110d3da8ece3e4eda99c2d63f6724779af505b9527f0b191b34b5bfabbf5584"
+"68fc77023c046909572d302630c6508922cbc03e6c6d9a05108bc8db71e045ff"
+"1b6630a5ab959106f3951689fcbc6a757c97511d08a3d4652b8ee7eab820d575"
+"2e34a9c19201971c6cffc366e7955b33d0b7dc59fbaf87cadeb8d0c099cfb541"
+"060bd11957a053af7aec4b2c2caf7e227512d9e856552e5cf6f4ed4b04753bec"
+"0d8a6987303d76b12f97eaeacfd783401ffef6ac2e994182eaa93843300385ae"
+"0e9b15bfa73141c59edc9d11ec4ee316525ba53c4b91e4f1a8adb8d372e91dff"
+"55215d958a6afccf90247026efb61dd9bae318cd31ad27746b227de8873add8c"
+"4ccb674b94da03efd3404a424a422d42fd4f3a8b9f73de3aa7377e728400e797"
+"256f31bdb0e0cad47ec44da9bdd1fc146d0284f1d71c596e12b0c690e202d1c4"
+"60797d9977e8cf8484240c0ac4d3703818c096db8d61ca640bab83ea4e675919"
+"57fd867a56f6fba130d5cd80d1aa2562ca3bdb6956892c0f66e8d9bbe1fe49e7"
+"09115f248d518063beb8d89c11115a6b53ac2927b2eeb0c50b50b3e82c314e5e"
+"6a10f8ecb4e14465b19148ae366be2452b809596eec80f4913a2240e5e89c98d"
+"0399008978536884058e8b36c86b622d5da6cde04ceabb591fe8057153f6c7b2"
+"2c7ba50ad84ce603d8206950a09277dbf59da814c5b5119763a208953d946812"
+"02a697c90f23766d5fde4b61101665b865375243f1bde57522bcb4bcda33804d"
+"3bba46c732127685e3a7c6963ec063f961bfa23dce70af06fbbdba02d295aa8a"
+"206c47de6dfd8600586a42f98aea1284742671c605e7a274a306e188015e031d"
+"608a94a91f8e4e1b0adf94c1af4992b0176fc84d8d79b881ec02d2613f4d9083"
+"28f906b6e3e6d01ac90251789b81001bb5d96ec2f55be04354b37bd7211c8731"
+"25c66f7f7c9db885d9f7d7b64bd555f7e2e939878a6f1f1056c0c5af008949a7"
+"4992f08ef5816859cd16e02a367e55fb073cc08ba19fce061e83288caba6e308"
+"432fd05cdbd6ce762396cc6b88f6db33f0e6daa1e4faf602a599575fe797979d"
+"4961bcdf4ad6da150ed71fe78f84c9faaa28e63e378af83aedd33870e337c362"
+"4d1025421a43054ecb8eab1d4ed666a8cfc7b3e1d3f5243bd945032b7ae19a1b"
+"0eb68c99851461def5baf569dff154f8ac4591e8ad194f641dc5fcfbc157c07d"
+"256cd6ef41e108838bc52d51af281be02ad6c5d2a3e6f49f2cb864bcf2397447"
+"0df82b76b04d8813711f92ed2bc6dda5f32e4778b5f1b328bd3b2a3b82928645"
+"73397a58cf55ae9d2b14647125725f053dc0a9d5d5599f67955b8b8ceb8c43d8"
+"352a6762b6764cd234a5e7e24e1beaed50618b691be9e40d4b15813d6023439a"
+"4ebe36c93f3561edd31170f6775e38889598f0b40a3a2967882b60c6bcf8d6f6"
+"4af798462ebca10935795dcb09770d98e2a93bc25a99af876c1f080fdf04047e"
+"6f9acbad33e5d972376f1f67457fb5565582c0cc233006fe51942c48479a3c9f"
+"395558ce9453ad4999a1d87585bc88b08731882ae0ffbbec886db1cc3fc7ee62"
+"17b48a7db220b2b4e4a3e9139168f050056e71049e4080ded3949222d3915dd2"
+"13266faaffcb6e011f73a4065bb1f7bdc373571d1b9c0210674f4f9d18cdbf3f"
+"0edbbed85597c4beb59685811f7f3c0ce807083c032e6c71e5869004bb37c93d"
+"64a7409e0e833df31fb574e1c12f764ecf0e3d335cc53afcdc22ac13d7a81da8"
+"730fbba0d85d06eabf3f517d4826457bacb2fa8c2f24168c1b026ada9eca5bf5"
+"1ffdde6d216f269f8d25efca3b28590416ea7340d92df2c02d111e30302ba020"
+"6551f0ba88e2b256f61e052c2ed98e5253fb7791614da7f7f10f9db1dbace96f"
+"5a40abaaa2542543cd1710bab187798b01f6c7d93395e3a1cdaed5b8866018e9"
+"7021fa2631484663ef5e14124c49b3078b460d77c9972b9f3aa8fe7bed79bed6"
+"28e1b47a74ed1328c9cf0188bcce0e6bc8e32d808ad91d62d747382141e7c439"
+"267bb1817a59e83c9cb67f740cb31fccde2ae0f6dc49745f826267f78136bc5a"
+"6f2a6bdaf2152c1368e51b4d1ae3ce48bb8a62e00d92f2f9f21393c691243aee"
+"00cd4b3d36b639b44a828c3dfe8e8da68a7cccaf7063fa92877683c0e5080869"
+"3e8e056dee60929e925fdcd2395a9959202ef71b82a638fd1e3decba9051d016"
+"651baeb3fea106c59cefec6a9c8973347a481a75b04f547d8d2f63a1ced57161"
+"1e6ea48da02249378957d446d9603e4a1e0efd343426933d0cf5a1400148f654"
+"5eb2faa76b282614614ae97db1e0bb722146ac8230739cf9abb35058ae7f6363"
+"6400a9ba34a8ce081b7755a5241338c78c10c07ff6cc97ac94f29b23775922f3"
+"5c475b1284568d5c55fae4840fd5bf9b9f8041fb4c75f3fd902681d97d4b09d2"
+"037e3fa79fcab75541fe4ceed6404d2a89228694646835e0422fb558477fb128"
+"39186a11b8693a21684796f4dd227523ac2782d6d23330d8287d77e19f106923"
+"44b4264d680b2bfa7081436798dce5bc3b20bedf250dfb2103abdde5b3f24eb2"
+"01fd3211afd7ab17103dd5a181b91982d83e69f9df9568ed132db65c23bfba2d"
+"66bd19f66bf63ef557cd87c638d6a97f2853a284307ff04392e61b7a68e56b12"
+"09e3ea8c3c87110454cb0045179ac850f74285652c6854351682cd1706b54f88"
+"22b7ffce8814457850e403085d0f725dc72396144565f4542d5bf826f4627106"
+"255b1285cd235b83bbdc8032f637a74bc8b33a798e2751969ebe67c593b578bb"
+"5b568413938daa1acec17d776af723451fc067e63ed8a24d58cefc27ef7feca9"
+"4fc38e950b447f3040484e58a7d106386da69400c9292640014886e33eb7596f"
+"044e95a76627fade400c813061a56bd38ae137734ac1b7b11fce4a12eed6bb68"
+"129d3939b05352392ee46921665e027d3cb9c9857f0b2f161bb1f0fdd58a74bf"
+"327b98a9fc847d6b6d54a175aaed3678172d615d37cf1c4448c9d4588a2eb7c7"
+"63675e996ad78bc6725b923b4cbeacf40f7d4b85bf38fd8b5ed0f63424779ab5"
+"7374af204d7432c7954dbbd12ed973b79fd0a6d7109061ffd10ecb2f6942d5fd"
+"0fdf70b408b29ce4bb3ef9a02c333ba7789fffbf2b17dc2ef4dce8714ada06a8"
+"4373b306976a59fbd07f82bb44c4ee4e4a11806801960c5c18f32f7679321d3c"
+"1b218fbc57953d8d44ab45c19993b223939a121a1e6bf87b4ca549e06699880a"
+"09b95f647fc4e11ed6a4757be6287d3f4d6bbdc6da8173da072d7a5d046862b1"
+"1def7155ba82eebd07611e2dd694a49dac9085004c1b4e9de2b4f0bf40c063fd"
+"38921799f2fae22e5dc387e3b63a8d4d2210ad60690f61cce190bad2a304c035"
+"2cfc11979ac028eea6636015cd2241a9ca2b9256bcdbae2f89df853751f63589"
+"21e602b39eade2ce622e3da4c76124a5f9b2580296037a33f88044895aa8562c"
+"25c9a818e3691a8d36cc881eed8513110fbcd2c855270ae265cc4a53283e2f4e"
+"6d17e4bdef0620c74ce13ee9b219e49bf2c8ac57cb1882bca03c64ec7c7c69fc"
+"2285fe01b02e1cb4331c2e86272f10d7e7daeac3d368b914e9115d832aab4e12"
+"3fb801cc1a5264babd7f35a65091d15eb9b47a6f06ab9422defafaee4cd35a84"
+"5b2ae60ec46971d3b3535743c3ab4d99f07ee2f551bfb2212ecfc7120169c8eb"
+"5322e28426199923aab00dcb5aa2c0c92690628e69ddbeaa8a9e0b92e4d84aa4"
+"1db225ddf28a651a6f809533078dfc8a006d4b76b59afde3d3356c7f26bf1ac2"
+"600fcc0f370b76ed88186364efc8d0435ba4efe84abd6b2573e87e213cb405dc"
+"007c21ae6a4471fb33141d353cb73f3769ee63d78cbc5d7e6a8c1bdb7cf3eb4f"
+"17520db9848586770ced86adfca305209a0884592720f70eb91f9e3a22c23a94"
+"3db8aeed94f87b37fc9cfee7a7c027605bec03af4965b840a8942b89fef39ecf"
+"10b3102359b66388bf079dd2f30d8131ec4da41bf159fae392838a9708e1cfc9"
+"0c9f537a5a0efc930019893a3fbd46c5e2a85b78b22b4bb60c0c1ec2da334a07"
+"165f9cb0313efaf5a0636141f39c3ff22089c0f9c494ebc40e9e8060b84f149f"
+"001879a49e2e539bf9e9c713416f517ee14f6e510a9cafb9a321fef9ca23ed49"
+"32e53a1e65305675144ebd5bb49bdcf81879daab30fff361eba5cfef952184a3"
+"51b4edb20a2bbb2daf144d4ab3b72a5a4cc956d9bd9e2ba5017c2163928118c3"
+"140c9db4c384a0e3757a41ae5005b2557148cb3c190ab7101059053039d655ed"
+"1737e47c806e74be09d8f7daf7c9d12ede33929f5152eda6c8c008064cfc1be3"
+"23f3501123499df44f5cd31b08fa1338be61194a023c9101a41ce7518acddcdd"
+"68dcbacbeb6727e3b47ef3a6291421496a78d81a645f2451c2cd89818715329b"
+"2f1dd4d3ce3e7b49d67a4bca9ba8b5b64ee37a20496ddbc302aa8c1bed9b2fbf"
+"2b5427a54294793e926c0ed030eff8b5020801ae8a46b1d7cecc49d01d2cd4a1"
+"1bcdebbdce2545485d5db25d9776f7bdc31dc799c61cb726e20e0071e939e4c4"
+"6021616995863e2b6fb9015892f2f361b60656bf1998239aa471d4c698564e9f"
+"4816704f77b55fba8188d9424143ffd7b015587467072992b2482e9bacd4f072"
+"60aad5cbecde71eae3fb3e8355137d5890f2947227093bacd23291a731720e79"
+"5bff651adb907adde66b4a4810173bb8cc0cc618e6698e236979750865b68466"
+"4dc639d5986ad912fc2632704ad03b039c6982fccad820b16ce2e519de54dcb0"
+"1780c0f66f7afefb6b32a019956b2a209224b9eeba8a643a222f7355214be300"
+"6d23740f70b21671e66d9bb35d7387b017dd56c78b65973db44e5479567c27a0"
+"1784ada0fe2211721dff5b63c46ddbd0cc2a7161e42f24b26b10cf0a807398c9"
+"3721b5cbdc714dc02db737a41bac0ad9dfd640229e4ef73c780f2abc7907a101"
+"6777e0e8612172897bde7e5e4d7edafdfac32f855d07b645ef0a2c2b6815d7bd"
+"5430480105f06250a915e429d5436268eeff94a54606848883d84eece231db3a"
+"5b06f0578c8e419abaf9365b1e0e4605a270d831b886b1310c2b30830f70aa05"
+"064faf1daa9415f3bf666dccf10e96a660e3c3e08945cecfad74bcf656a09b63"
+"5a7cf453cdc309e004ac0d4b161686c9497ddd5333302ce1ac689d3cd3f15fe8"
+"3d1cdaba6330736b0b9c17a27d3f31b58ea7b0aa1a46faa5cbc191faef9e41ef"
+"59c894b434302a88c78f3438263ff4a3f82f27af2f086958497b75ba9ede3267"
+"4f96eab2814accfe7cc529624df63fd4d9d3932ecace112a52d488ebd64f86a9"
+"5c3395a99f651f587c1e9f88fb32ffde50f312874219daec0f67f604ba56f55a"
+"10bc86369a85dae2cbcb60d1a110675555b1f29f01af909d0b0a452fd6f8aa0a"
+"025c11c9d5846be858ed85b2706718d0859b14b5e6afafc50e5b7cab9390e88d"
+"6a0df7099df32bbf845516682d8b2c40d5b238bab4493508146ec7da5280b31d"
+"15dee1455b9289a97a4fb4561cd05cc4eaac7f45e2098e6db369c4e38780a898"
+"6b00cd849365b050f85b3bcb73dc91ae063ed60360b053ccecd4ea226f5d3480"
+"36ba01e51f6cce897b12718e2947d0ded1b43f1ad65045d9e80792cc0d2afbcf"
+"705ec3f8f1bdd15381e69d0241b37349e11963b509f73dde27e4d00f7173e9d2"
+"00259c2c2a277983602c80547343f0037a7a3c7edfdf98a1ffd16bea20204aa2"
+"07ba65993dc66a3359f96e202f8408f9367d24e37a83164c622f682ef4d113d0"
+"56324ef5c5a36793bc76d0c2a38e6ae35916ab04bc072325036d9e832981518d"
+"3cdc6e8fc9101d4e6be6b5fb368a3911ac13c4090ea7da9f345cd5f7ae7b1e6c"
+"3fe62a321b08da7f8f6cd2080867b98b6c9f54bf910bac77db5a71da68b18270"
+"53915ca5503403181327eea9143a99782e31f1636a324a946882376fb9d07681"
+"45ec1e9c297bdd973aec556197b1168f8a55b0d7bb0519b5db479f95d11cd045"
+"7310ab366f789b5264f16fd563b6dd31462f3e352a92fbb5e2357a9fbb9a1f16"
+"739ebe2484fabba7b18d7f3a213bb9d3bb2d78a8c05f41515aa20533b933cc2e"
+"048f8d7f23612a95c09d90137f7a4d87e340a1e83ec3c94284d6784ea8006423"
+"49a59faf4bbf57ee29b5e186bb0008a4ec74c8fdb7ea8fe7e1aa46bc40873b50"
+"5cf260d13f5da4870855a40e71d4effda202f310a955db2d140e9317e4238998"
+"38c2eba027b51ab146dc61e33b7403789b63641a5cba018829e3dfc9336cbcb8"
+"1f90a83ada4e0d548c8beea8f902f4bdd8466948161fe2760a0127f44a0edea8"
+"6b65cc39e2d766f83e8f6f59fd5e40290bf8b887c99da8c166417d5a9cae1444"
+"1da9f1f317f97e9c6132dc6808def44d32daa0c2dbcffe580d8f35b85400ccc3"
+"3df94f558d1e935080d48183a3e742f6be2992f5aea51387f01c90219e980fa2"
+"59974c89246e978cbee6e84478252843235f550eb7ba45324d4a7ea572ca7e2b"
+"094be891b94edbc55530775ac31dd8f5ac0d1e2462579c158ce2f28843a2e9b2"
+"02c997879aff55f85e9e19e36a32758b868a0504ff0cb4a704fabdb897f308bd"
+"090a6946efff80828d498845e43aebaf02f19cc8a5459db7b12952e4924e1fd1"
+"3cf7d767a121eb81462c2731ee18da4f5579e007ed7e198ed9c74d0e4122d247"
+"4dafcb7ed415b248c5f169092d29b0f5d213e599e2bf15ade507d9ae2c9d764d"
+"5204fb985e7a86bb77fd705bf71787c4a09b97e7729318e6828a422f70aabcea"
+"0e1b38375d5ded933a6c9d7512ade1e96679651be670f381f875dd62c7279827"
+"6b612638db66a469241a60b7222956ca0364f2d77ea8849aeb99fad2a0b5637f"
+"3626c1544bd18d8a9bde32d6210aa6179839b1ebefb87fdb914d3735db50f92e"
+"222fd118f0cc69ef015f43fdd95a4db3fc08eec734f4cd3fce78e73348373e03"
+"369885b7348e2be8c21dce937e248cc6c390c703a09dddbb88b39bbfb3fa2943"
+"0794753806f2502ff43f7b8c4990e446c37677a49f78e0a8e38622a23c34eb60"
+"4b9b69b8b54c2ba38a23c409263b2ea543ba2082b6fded12c3c9b9dc754c4202"
+"06fae323404cc19a099fb298803a76737720c25913e21f38a75f1c8e63a96b9c"
+"50461e3977f12ec2de486071fc3924cd1aef82a6bc9fbde215eaddee6780de1d"
+"5ff12618767830d17a759dadc62c40221cc848ef84da8cd91b76e5ca59ccaa37"
+"6b7bdeac8d4dc989219510a928aa2e2a8995f4aba16e9f59d85e88ae3f6f5f5f"
+"5fbc48469f2e94eaee4ce3cc7af5c45f27a6532f0b7d8aaad76e61091a319ecd"
+"024ec0f964b1ce01b08352c231662c238c623cd66a2da4ef330debc7323dba8e"
+"0dfd978f5c1e804bd89e9d579edb44c49335296cd5948420d7650775cf88fc0c"
+"57ecafcf80a257780a9bbac3793c3e772fde0c88d6ce8e39399c7eb0a7e76d6a"
+"705b423e84afdccba45b0286397d1a29896cc1dc3fb41721e9e14942a2c13db6"
+"61efd69d156931b397d7aebd87d6c7599f6a5e2925cb7d8891fd751b7757c486"
+"5b0a8e0bc9d55850e65cb119b6b43abd5eda13de38ffd6e45130a6b2c7184251"
+"2ee9eb134a2f83e93bb4b09c71da3e7810d9a2bd01acaacf70fc7b43ccc2fec6"
+"136a3734420b9a29249f23e3292d871653540c3a86fdfbdbb655596aac99d0ce"
+"11ea5a840d53c0f0eaa111e6f43d953cdadcddedd8b7658d82266fd0897cd71a"
+"51a4d6a93c09813a72f272b043ef5cf88fe27eeadb2065cb75c95620874ea281"
+"00b698d1b30b8486b7fb7cafdae54bb93ac182be3623f1feffa7edc12486d4e8"
+"22386f894f2a9326c7ab4cfbceae435cb69f3e359ee49946dc566f242f4238de"
+"636d98aea6cb6afe50fd1e96bb8bfdf18a9d54a87e66fd79e3dff80abda98c18"
+"067a4de70930459165ff7d84a0dc375adb145ac07e67eb0e1fadebd4e2610eeb"
+"64721850463f2d1dfe148e429e472914d67d9867409de6c39150225106d4d425"
+"6c87827aa64247be6bb132c49e271a6e23c54c8334f2c3eca5551b4ae5260f05"
+"65cbbc751ea4f5e7956628b8645708187b37f2d65c6c297a5854355256de476e"
+"6bf24b343856b4066e2835b1fe3e5d16496a36f41386c2afd44d001ba886fdc7"
+"41d82825d409ab7c996773b516f6720e34cbfdebdc9c069fa579dcea11ef44f6"
+"45f741f2e9481a85b86467ab30d363fd0328e33d53fce6b39286c2494ee7bd28"
+"6c06f72d4e071f9c1ddca4f9ea231853f6d8c5e9b7418e9c564c995912d19c18"
+"154f9ecfb65370a8b59a12cd736348aead2e59a7e3701d20a669bec15363fe62"
+"0c4d910fbd3b57be6d6680e8d2db47c1454712b240b78468cb764702be5c1aec"
+"0e1ac575e1125f5ee86da3342018bc4f3c1e2310148043d5074eb4ee22fc55b6"
+"273531c7d0d03d8f97b722ef1f0c324dac39f804e0222202f7502946647ef332"
+"101464d19cf380958e5aef1084736db89f4cb131033ae670f6de0a5cf9d92b73"
+"597cdd384abdad1beccc73fb39f74a18eb44d056951d602c2ef6ef6448fc5626"
+))

+ 23 - 0
lisp/examples/util.lisp

@@ -0,0 +1,23 @@
+(def! inc (fn* [a] (i+ a 1)))
+(def! gensym
+  (let* [counter (atom 0)]
+    (fn* []
+      ;; (symbol (str "G__" (genrand) (swap! counter inc))))))
+      (symbol (str "G__" (swap! counter inc))))))
+
+;; Like load-file, but will never load the same path twice.
+
+;; This file is normally loaded with `load-file`, so it needs a
+;; different mechanism to neutralize multiple inclusions of
+;; itself. Moreover, the file list should never be reset.
+
+(def! load-file-once
+  (try*
+    load-file-once
+  (catch* _
+    (let* [seen (atom {"../lib/util.mal" nil})]
+      (fn* [filename]
+        (if (not (contains? @seen filename))
+          (do
+            (swap! seen assoc filename nil)
+            (load-file filename))))))))

+ 0 - 34
lisp/inverse.lisp

@@ -1,34 +0,0 @@
-(println "new-cs.lisp")
-
-( (let* [aux (scalar 3)
-      x (alloc "x" aux)
-      x2 (alloc "x2" (* aux aux))
-      x3 (alloc "x3" (* aux (* aux aux)))
-      input (alloc-input "input" (scalar 27))
-      ]
-(prove
- (setup 
-  (
-  (enforce 
-    (scalar::one input)
-    (scalar::one cs::one)
-    (scalar::one x3)  
-  )
-
-  (enforce 
-    (scalar::one x2)
-    (scalar::one x)
-    (scalar::one x3)
-  )
-
-  (enforce  
-    (scalar::one x)
-    (scalar::one x)
-    (scalar::one x2)
-  )
-  )
-  )
- )
-)
-)
-;; (println 'verify  (MyCircuit (scalar 27)))

+ 0 - 47
lisp/jubjub-add.lisp

@@ -1,47 +0,0 @@
-(println "jubjub-add.lisp")
-(def! param4 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
-(def! param3 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
-(def! param2 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
-(def! param1 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
-
-(
-    (let* [
-      u1 (alloc "u1" param1)
-      v1 (alloc "v1" param2)
-      u2 (alloc "u2" param3)
-      v2 (alloc "v2" param4)
-      EDWARDS_D (alloc-const "EDWARDS_D" (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1"))
-      U (alloc "U" (* (+ u1 v1) (+ u2 v2)))
-      A (alloc "A" (* v2 u1))
-      B (alloc "B" (* u2 v1))
-      C (alloc "C" (* EDWARDS_D (* A B)))
-      u3 (alloc-input "u3" (/ (+ A B) (+ scalar::one C)))
-      v3 (alloc-input "v3" (/ (- (- U A) B) (- scalar::one C)))
-      ]
-    (prove
-        (setup 
-  (
-  (enforce  
-    ((scalar::one u1) (scalar::one v1))
-    ((scalar::one u2) (scalar::one v2))
-    (scalar::one U)
-  )
-  (enforce
-    (EDWARDS_D A)
-    (scalar::one B)
-    (scalar::one C)
-  )
-  (enforce
-    ((scalar::one cs::one)(scalar::one C))
-    (scalar::one u3)
-    ((scalar::one A) (scalar::one B))
-  )
-  (enforce
-    ((scalar::one cs::one) (scalar::one::neg C))
-    (scalar::one v3)
-    ((scalar::one U) (scalar::one::neg A) (scalar::one::neg B))
-  )
-  )
- )
-)))
-;; (println 'verify  (MyCircuit (scalar 27)))

+ 0 - 59
lisp/jubjub-mul.lisp

@@ -1,59 +0,0 @@
-(println "jubjub-mul.lisp")
-
-(def! param4 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
-(def! param3 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
-(def! param2 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
-(def! param1 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
-
-(setup
-    (prove 
-      (
-    (def! double (fn* [val1 val2] (
-            (def! u11 (alloc "u11" (scalar val1)))
-            (def! v11 (alloc "v11" (scalar val2)))
-            (def! U1 (alloc-input "U1" (* u11 v11)))
-            (enforce  
-                (scalar::one u11) 
-                (scalar::one v11)
-                (scalar::one U1)
-            )
-        )
-    ))
-
-     (def! u1 (alloc "u1" param1))
-     (def! v1 (alloc "v1" param2))
-     (def! u2 (alloc "u2" param3))
-     (def! v2 (alloc "v2" param4))
-     (def! EDWARDS_D (alloc-const "EDWARDS_D" (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
-     (def! U (alloc "U" (* (+ u1 v1) (+ u2 v2))))
-     (def! A (alloc "A" (* v2 u1)))
-     (def! B (alloc "B" (* u2 v1)))
-     (def! C (alloc "C" (* EDWARDS_D (* A B))))
-     (def! u3 (alloc-input "u3" (/ (+ A B) (+ scalar::one C))))
-     (def! v3 (alloc-input "v3" (/ (- (- U A) B) (- scalar::one C))))
-     (double param1 param1)
-  (
-  (enforce  
-    ((scalar::one u1) (scalar::one v1))
-    ((scalar::one u2) (scalar::one v2))
-    (scalar::one U)
-  )
-  (enforce
-    (EDWARDS_D A)
-    (scalar::one B)
-    (scalar::one C)
-  )
-  (enforce
-    ((scalar::one cs::one)(scalar::one C))
-    (scalar::one u3)
-    ((scalar::one A) (scalar::one B))
-  )
-  (enforce
-    ((scalar::one cs::one) (scalar::one::neg C))
-    (scalar::one v3)
-    ((scalar::one U) (scalar::one::neg A) (scalar::one::neg B))
-  )
-  )
- )
-)
-)

+ 112 - 50
lisp/lisp.rs

@@ -11,10 +11,13 @@ use bls12_381::Bls12;
 use fnv::FnvHashMap;
 use itertools::Itertools;
 use rand::rngs::OsRng;
-use std::fs;
 use std::fs::File;
 use std::rc::Rc;
 use std::time::Instant;
+use std::{
+    borrow::{Borrow, BorrowMut},
+    fs,
+};
 use types::EnforceAllocation;
 
 #[macro_use]
@@ -38,8 +41,6 @@ use crate::env::{env_bind, env_find, env_get, env_new, env_set, env_sets, Env};
 #[macro_use]
 mod core;
 
-pub const ZK_CIRCUIT_ENV_KEY: &str = "ZKC";
-
 // read
 fn read(str: &str) -> MalRet {
     reader::read_str(str.to_string())
@@ -102,12 +103,12 @@ fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
 fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
     let mut was_expanded = false;
     while let Some((mf, args)) = is_macro_call(&ast, env) {
-        //println!("macroexpand 1: {:?}", ast);
+        // println!("macroexpand 1: {:?}", ast);
         ast = match mf.apply(args) {
             Err(e) => return (false, Err(e)),
             Ok(a) => a,
         };
-        //println!("macroexpand 2: {:?}", ast);
+        // println!("macroexpand 2: {:?}", ast); 
         was_expanded = true;
     }
     (was_expanded, Ok(ast))
@@ -168,7 +169,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
                     }
                     Sym(ref a0sym) if a0sym == "zk*" => {
-                        println!("zk* {:?}", l[1]);
+                        // println!("zk* {:?}", l[1]);
                         let (a1, a2) = (l[1].clone(), l[2].clone());
                         match a1 {
                             List(ref binds, _) | Vector(ref binds, _) => {
@@ -287,6 +288,17 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                             _ => error("invalid do form"),
                         }
                     }
+                    Sym(ref a0sym) if a0sym == "dotimes" => {
+                        match eval(l[1].clone(), env.clone())? {
+                            MalVal::Int(v) => {
+                                for _i in 1..v {
+                                    eval(l[2].clone(), env.clone())?;
+                                }
+                                Ok(Nil)
+                            }
+                            _ => error("invalid args for dotimes"),
+                        }                        
+                    }
                     Sym(ref a0sym) if a0sym == "if" => {
                         let cond = eval(l[1].clone(), env.clone())?;
                         match cond {
@@ -330,7 +342,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                     }
                     Sym(ref a0sym) if a0sym == "prove" => {
                         let a1 = l[1].clone();
-                        ast = eval(a1.clone(), env.clone())?;
+                        eval(a1.clone(), env.clone())?;
                         prove(a1.clone(), env.clone())
                     }
                     Sym(ref a0sym) if a0sym == "alloc-const" => {
@@ -342,12 +354,20 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         for (k, v) in allocs.iter() {
                             new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
                         }
-                        new_hm.insert(a1.pr_str(false), result.clone());
-                        env_set(
-                            &env,
-                            Sym("AllocationsConst".to_string()),
-                            Hash(Rc::new(new_hm), Rc::new(Nil)),
-                        )?;
+                        new_hm.insert(a1.pr_str(false), result.clone());      
+                        if let Some(e) = &env.outer {
+                            env_set(
+                                &e,
+                                Sym("AllocationsConst".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        } else {
+                            env_set(
+                                &env,
+                                Sym("AllocationsConst".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        }
                         Ok(result.clone())
                     }
                     Sym(ref a0sym) if a0sym == "alloc-input" => {
@@ -360,16 +380,27 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                             new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
                         }
                         new_hm.insert(a1.pr_str(false), result.clone());
-                        env_set(
-                            &env,
-                            Sym("AllocationsInput".to_string()),
-                            Hash(Rc::new(new_hm), Rc::new(Nil)),
-                        )?;
+                        if let Some(e) = &env.outer {
+                            env_set(
+                                &e,
+                                Sym("AllocationsInput".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        } else {
+                            env_set(
+                                &env,
+                                Sym("AllocationsInput".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        }
                         Ok(result.clone())
                     }
                     Sym(ref a0sym) if a0sym == "alloc" => {
                         let a1 = l[1].clone();
-                        let value = eval(l[2].clone(), env.clone())?;
+                        let mut value = eval(l[2].clone(), env.clone())?;
+                        if let Func(_, _) = value {
+                            value = value.apply(vec![]).unwrap();
+                        } 
                         let result = eval(value.clone(), env.clone())?;
                         let allocs = get_allocations(&env, "Allocations");
                         let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
@@ -377,11 +408,19 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                             new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
                         }
                         new_hm.insert(a1.pr_str(false), result.clone());
-                        env_set(
-                            &env,
-                            Sym("Allocations".to_string()),
-                            Hash(Rc::new(new_hm), Rc::new(Nil)),
-                        )?;
+                        if let Some(e) = &env.outer {
+                            env_set(
+                                &e,
+                                Sym("Allocations".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        } else {
+                            env_set(
+                                &env,
+                                Sym("Allocations".to_string()),
+                                Hash(Rc::new(new_hm), Rc::new(Nil)),
+                            )?;
+                        }
                         Ok(result.clone())
                     }
                     //Sym(ref a0sym) if a0sym == "verify" => {
@@ -457,20 +496,28 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         for value in enforce_vec.iter() {
                             new_vec.push(value.clone());
                         }
-                        env_set(
-                            &env,
-                            Sym("AllocationsEnforce".to_string()),
-                            vector![vec![Enforce(Rc::new(new_vec))]],
-                        );
-                        /*
-                                                println!("\n\nallocations {:?}", get_allocations(&env, "Allocations"));
-                                                println!(
-                                                    "\n\nallocations input {:?}",
-                                                    get_allocations(&env, "AllocationsInput")
-                                                );
-                                                println!("\n\nallocations enforce {:?}", get_enforce_allocs(&env));
-                        */
-                        Ok(vector![vec![]])
+                        // TODO change it
+                        if let Some(e) = &env.outer {
+                            env_set(
+                                &e,
+                                Sym("AllocationsEnforce".to_string()),
+                                vector![vec![Enforce(Rc::new(new_vec.clone()))]],
+                            )?;
+                        } else {
+                            env_set(
+                                &env,
+                                Sym("AllocationsEnforce".to_string()),
+                                vector![vec![Enforce(Rc::new(new_vec.clone()))]],
+                            )?;
+                        }
+
+                        // println!(
+                        //     "allocs here {:?}",
+                        //     get_allocations_nested(&env, "Allocations")
+                        // );
+                        // println!("enforce here {:?}", get_enforce_allocs_nested(&env));
+
+                        Ok(MalVal::Nil)
                     }
                     _ => match eval_ast(&ast, &env)? {
                         List(ref el, _) => {
@@ -491,7 +538,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                                     continue 'tco;
                                 }
                                 _ => {
-                                    println!("{:?}", args);
+                                    // println!("{:?}", args);
                                     Ok(vector![el.to_vec()])
                                     //error("call non-function")
                                 }
@@ -511,7 +558,14 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
 }
 
 pub fn get_enforce_allocs(env: &Env) -> Vec<EnforceAllocation> {
-    // todo need some cleanup
+    if let Some(e) = &env.outer {
+        get_enforce_allocs_nested(&e)
+    } else {
+        get_enforce_allocs_nested(&env)
+    }
+}
+
+pub fn get_enforce_allocs_nested(env: &Env) -> Vec<EnforceAllocation> {
     match env_find(env, "AllocationsEnforce") {
         Some(e) => match env_get(&e, &Sym("AllocationsEnforce".to_string())) {
             Ok(f) => {
@@ -530,7 +584,16 @@ pub fn get_enforce_allocs(env: &Env) -> Vec<EnforceAllocation> {
         _ => vec![],
     }
 }
+
 pub fn get_allocations(env: &Env, key: &str) -> Rc<FnvHashMap<String, MalVal>> {
+    if let Some(e) = &env.outer {
+        get_allocations_nested(&e, key)
+    } else {
+        get_allocations_nested(&env, key)
+    }
+}
+
+pub fn get_allocations_nested(env: &Env, key: &str) -> Rc<FnvHashMap<String, MalVal>> {
     let alloc_hm: Rc<FnvHashMap<String, MalVal>> = Rc::new(FnvHashMap::default());
     match env_find(env, key) {
         Some(e) => match env_get(&e, &Sym(key.to_string())) {
@@ -567,7 +630,7 @@ pub fn setup(_ast: MalVal, env: Env) -> Result<VerifyKeyParams, MalErr> {
 }
 
 pub fn prove(_ast: MalVal, env: Env) -> MalRet {
-    let start = Instant::now();
+    // let start = Instant::now();
     let allocs_input = get_allocations(&env, "AllocationsInput");
     let allocs = get_allocations(&env, "Allocations");
     let enforce_allocs = get_enforce_allocs(&env);
@@ -632,7 +695,7 @@ fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
 fn main() -> Result<(), ()> {
     let matches = clap_app!(zklisp =>
         (version: "0.1.0")
-        (author: "mileschet <miles.chet@gmail.com>")
+        (author: "Dark Renaissance")
         (about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
         (@subcommand load =>
             (about: "Load the file into the interpreter")
@@ -641,13 +704,13 @@ fn main() -> Result<(), ()> {
     )
     .get_matches();
 
-    CombinedLogger::init(vec![TermLogger::new(
-        LevelFilter::Debug,
-        Config::default(),
-        TerminalMode::Mixed,
-    )
-    .unwrap()])
-    .unwrap();
+    // CombinedLogger::init(vec![TermLogger::new(
+    //     LevelFilter::Debug,
+    //     Config::default(),
+    //     TerminalMode::Mixed,
+    // )
+    // .unwrap()])
+    // .unwrap();
 
     match matches.subcommand() {
         Some(("load", matches)) => {
@@ -673,7 +736,6 @@ fn repl_load(file: String) -> Result<(), ()> {
         "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
         &repl_env,
     );
-    //let _ = rep("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", &repl_env);
     match rep(&format!("(load-file \"{}\")", file), &repl_env) {
         Ok(_) => std::process::exit(0),
         Err(e) => {

+ 0 - 34
lisp/new-cs.lisp

@@ -1,34 +0,0 @@
-(println "new-cs.lisp")
-
-( (let* [aux (scalar 3)
-      x (alloc "x" aux)
-      x2 (alloc "x2" (* aux aux))
-      x3 (alloc "x3" (* aux (* aux aux)))
-      input (alloc-input "input" (scalar 27))
-      ]
-(prove
- (setup 
-  (
-  (enforce  
-    (scalar::one x)
-    (scalar::one x)
-    (scalar::one x2)
-  )
-
-  (enforce 
-    (scalar::one x2)
-    (scalar::one x)
-    (scalar::one x3)
-  )
-
-  (enforce 
-    (scalar::one input)
-    (scalar::one cs::one)
-    (scalar::one x3)  
-  )
-  )
-  )
- )
-)
-)
-;; (println 'verify  (MyCircuit (scalar 27)))

+ 0 - 17
lisp/new.lisp

@@ -1,17 +0,0 @@
-(def! x "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000")
-(def! one "0000000000000000000000000000000000000000000000000000000000000001")
-(def! bits (unpack-bits x))
-(defzk! circuit ())
-(def! cvalues (map (fn* [b] (eval
-                    (add lc0 one) 
-                    (sub lc0 b)
-                    (add lc1 x)
-                    enforce)
-                        ) bits))
-(def! cs (concat cvalues (list 
-                 'reset-coeff-lc
-                 (sub lc0 x)
-                 (add lc1 one)
-                 'enforce)))
-(println "bit-dec")
-(cs! circuit cs)

+ 3 - 2
lisp/run.sh

@@ -1,3 +1,4 @@
-#export RUST_BACKTRACE=full
-cargo run --bin lisp load jubjub-mul.lisp
+export RUST_BACKTRACE=full
+cargo run --bin lisp load macro-test.lisp
+#cargo run --bin lisp load jubjub-mul.lisp
 #cargo run --bin lisp load new-cs.lisp

+ 16 - 4
lisp/types.rs

@@ -97,7 +97,6 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
 
         println!("Allocations Input\n");
         for (k, v) in &self.alloc_inputs {
-            println!("k {:?} v {:?}", k, v);
             match v {
                 MalVal::ZKScalar(val) => {
                     let var = cs.alloc_input(|| k, || Ok(*val))?;
@@ -142,7 +141,7 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                         }
                     }
                 }
-                //                println!("left: a {:?} b {:?} val_b: {:?}", a, b, val_b);
+                println!("left: a {:?} b {:?} val_b: {:?}", a, b, val_b);
             }
 
             for values in alloc_value.right.iter() {
@@ -155,22 +154,35 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                     right = right + (coeff, val_b);
                 } else if a == "scalar::one::neg" {
                     right = right + (coeff.neg(), val_b);
+                } else {
+                    if let Some(value) = params_const.get(a) {
+                        if let MalVal::ZKScalar(val) = value {
+                            right = right + (*val, val_b);
+                        }
+                    }
                 }
-                //println!("right: a {:?} b {:?} val_b: {:?}", a, b, val_b);
+                println!("right: a {:?} b {:?} val_b: {:?}", a, b, val_b);
             }
 
             for values in alloc_value.output.iter() {
                 let (a, b) = values;
                 let mut val_b = CS::one();
                 if b != "cs::one" {
+                    println!("{:?}", b);
                     val_b = *variables.get(b).unwrap();
                 }
                 if a == "scalar::one" {
                     output = output + (coeff, val_b);
                 } else if a == "scalar::one::neg" {
                     output = output + (coeff.neg(), val_b);
+                } else {
+                    if let Some(value) = params_const.get(a) {
+                        if let MalVal::ZKScalar(val) = value {
+                            output = output + (*val, val_b);
+                        }
+                    }
                 }
-                //println!("output: a {:?} b {:?} val_b: {:?}", a, b, val_b);
+                println!("output: a {:?} b {:?} val_b: {:?}", a, b, val_b);
             }
 
             println!("Enforcing ...");

+ 1 - 1
proofs/mint2.psm

@@ -271,7 +271,7 @@ constant G_VCV_v 0x466a7e3a82f67ab1d32294fd89774ad6bc3332d0fa1ccd18a77a81f50667c
     # Performs a scalar multiplication of this twisted Edwards
     # point by a scalar represented as a sequence of booleans
     # in little-endian bit order.
-
+    
     {% for i in range(n) %}
         {% if i == 0 %}
             {{ jubjub_conditionally_select(

+ 2 - 2
run_mint.sh

@@ -1,5 +1,5 @@
 #!/bin/bash -x
-python scripts/preprocess.py proofs/mint2.psm > /tmp/mint2.psm || exit $?
-python scripts/compile.py --supervisor /tmp/mint2.psm --output mint.zcd || exit $?
+python3 scripts/preprocess.py proofs/mint2.psm > /tmp/mint2.psm || exit $?
+python3 scripts/compile.py --supervisor /tmp/mint2.psm --output mint.zcd || exit $?
 cargo run --release --bin mint
 

+ 4 - 0
scripts/modp.py

@@ -3,9 +3,13 @@ from finite_fields.modp import IntegersModP
 q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
 modq = IntegersModP(q)
 
+a = modq(-1) 
+print("0x%x" % a.n)
+print("\n")
 two = modq(2)
 inv2 = modq(2).inverse()
 print("Inverse of 2 = 0x%x" % inv2.n)
+print((two * inv2))
 # This is from bellman
 inv2_bellman = 0x39f6d3a994cebea4199cec0404d0ec02a9ded2017fff2dff7fffffff80000001
 assert inv2.n == inv2_bellman