Просмотр исходного кода

fix linear combination zero on enforce field

plato 5 лет назад
Родитель
Сommit
d9aab92fe2
5 измененных файлов с 126 добавлено и 90 удалено
  1. 31 18
      lisp/core.rs
  2. 1 1
      lisp/env.rs
  3. 35 2
      lisp/examples/mint2.lisp
  4. 49 65
      lisp/lisp.rs
  5. 10 4
      lisp/types.rs

+ 31 - 18
lisp/core.rs

@@ -191,7 +191,7 @@ fn unpack_bits(a: MalArgs) -> MalRet {
                 .map(|a| Str(std::string::ToString::to_string(&a)[2..].to_string()))
                 .collect::<Vec<MalVal>>()))
         }
-        _ => error("invalid args to unpack-bits"),
+        _ => error(&format!("invalid args to unpack-bits found \n {:?}", a).to_string()),
     }
 }
 
@@ -368,9 +368,7 @@ fn mul_scalar(a: MalArgs) -> MalRet {
             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),
-            );
+            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()))
         }
@@ -379,8 +377,7 @@ fn mul_scalar(a: MalArgs) -> MalRet {
             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())
+        _ => error(&format!("scalar mul expect (zkscalar, zkscalar) \n {:?}", a).to_string()),
     }
 }
 
@@ -421,8 +418,7 @@ fn div_scalar(a: MalArgs) -> MalRet {
                 error("DivisionByZero")
             }
         }
-        _ => error( 
-            &format!("scalar div expect (zkscalar, zkscalar) \n {:?}", a).to_string())
+        _ => error(&format!("scalar div expect (zkscalar, zkscalar) \n {:?}", a).to_string()),
     }
 }
 
@@ -529,18 +525,21 @@ fn scalar_invert(a: MalArgs) -> MalRet {
             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())
+                        error(&format!("scalar invert divizion by zero \n {:?}", a0).to_string())
                     } else {
-                        Ok(ZKScalar(a0.invert().unwrap()))        
+                        Ok(ZKScalar(a0.invert().unwrap()))
                     }
                 } else {
                     error(
-                        &format!("scalar invert expect (zkscalar or string) found \n {:?}", a).to_string())
+                        &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())
+                    &format!("scalar invert expect (zkscalar or string) found \n {:?}", a)
+                        .to_string(),
+                )
             }
         }
         ZKScalar(a0) => {
@@ -562,14 +561,24 @@ fn scalar_is_zero(a: MalArgs) -> MalRet {
         Func(_, _) => {
             if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
                 if let ZKScalar(a0) = values[0] {
-                    Ok(Bool(a0.is_zero()))        
+                    Ok(Bool(a0.is_zero()))
                 } else {
                     error(
-                        &format!("scalar is zero expect (zkscalar or string) found \n {:?}", a).to_string())
+                        &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())
+                    &format!(
+                        "scalar is zero expect (zkscalar or string) found \n {:?}",
+                        a
+                    )
+                    .to_string(),
+                )
             }
         }
         ZKScalar(a0) => {
@@ -581,7 +590,11 @@ fn scalar_is_zero(a: MalArgs) -> MalRet {
             Ok(Bool(s0.is_zero()))
         }
         _ => error(
-            &format!("scalar is zero expect (zkscalar or string) found \n {:?}", a).to_string(),
+            &format!(
+                "scalar is zero expect (zkscalar or string) found \n {:?}",
+                a
+            )
+            .to_string(),
         ),
     }
 }
@@ -615,7 +628,7 @@ fn add_scalar(a: MalArgs) -> MalRet {
         }
         (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)) => {

+ 1 - 1
lisp/env.rs

@@ -1,6 +1,6 @@
 use std::cell::RefCell;
-use std::rc::Rc;
 use std::collections::HashMap;
+use std::rc::Rc;
 // use fnv::FnvHashMap;
 
 use crate::types::MalErr::ErrString;

+ 35 - 2
lisp/examples/mint2.lisp

@@ -190,7 +190,7 @@
         (let* [var (gensym)] (
             `(alloc ~var ~val)
             `(enforce
-                (scalar::one cs::one) (scalar::one ~var)
+                ((scalar::one cs::one) (scalar::one::neg ~var))
                 (scalar::one ~var)
                 ()
              )
@@ -265,6 +265,34 @@
     ))
 )))
 
+(defmacro! rangeproof-alloc (fn* [value] (
+    (let* [bit (gensym2 'bit)] (
+    `(alloc ~bit ~value)
+    `(enforce 
+        (scalar::one ~bit) 
+        (scalar::one::neg ~bit) 
+        () 
+    )
+)))))
+
+(def! rangeproof (fn* [value] (
+    (def! value-alloc (alloc "value-alloc" value))
+    (def! values-bit (unpack-bits value))
+    (def! acc 0)
+    (def! digit (scalar::one))    
+    (def! value-result (scalar::zero))
+    (println (count values-bit))
+    (dotimes 64 (
+        (rangeproof-alloc (nth values-bit acc))
+        (def! digit (double digit))
+        (def! value-result (add bit))
+        (def! acc (i+ acc 1))
+    ))
+    ;; todo add last enforce
+    (println 'value-result value-result)
+    (println 'bit bit)
+)))
+
 (def! mint-contract (fn* [public-u public-v] (
     (def! randomness (rnd-scalar))    
     (def! witness-result (zk-witness public-u public-v))    
@@ -290,10 +318,15 @@
   (            
     (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
     (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
-    (mint-contract param-u param-v)    
+    (rangeproof param-u)
   )
 )
 
+;; (mint-contract param-u param-v)    
+;; (def! param3 (rnd-scalar))
+;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
+;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
+;; (jj-mul param-u param-v param3)
 ;; following some examples 
 ;; (def! left (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
 ;; (def! right (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))

+ 49 - 65
lisp/lisp.rs

@@ -11,13 +11,13 @@ use bls12_381::Bls12;
 // use fnv::FnvHashMap;
 use itertools::Itertools;
 use rand::rngs::OsRng;
-use std::{collections::HashMap, cell::RefCell};
 use std::rc::Rc;
 use std::time::Instant;
 use std::{
     borrow::{Borrow, BorrowMut},
     fs,
 };
+use std::{cell::RefCell, collections::HashMap};
 use types::EnforceAllocation;
 
 #[macro_use]
@@ -31,7 +31,9 @@ extern crate regex;
 #[macro_use]
 mod types;
 use crate::types::MalErr::{ErrMalVal, ErrString};
-use crate::types::MalVal::{Bool, Enforce, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector, Alloc};
+use crate::types::MalVal::{
+    Alloc, Bool, Enforce, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector,
+};
 use crate::types::VerifyKeyParams;
 use crate::types::{error, format_error, MalArgs, MalErr, MalRet, MalVal};
 mod env;
@@ -108,7 +110,7 @@ fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
             Err(e) => return (false, Err(e)),
             Ok(a) => a,
         };
-        // println!("macroexpand 2: {:?}", ast); 
+        // println!("macroexpand 2: {:?}", ast);
         was_expanded = true;
     }
     (was_expanded, Ok(ast))
@@ -297,7 +299,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                                 Ok(Nil)
                             }
                             _ => error("invalid args for dotimes"),
-                        }                        
+                        }
                     }
                     Sym(ref a0sym) if a0sym == "if" => {
                         let cond = eval(l[1].clone(), env.clone())?;
@@ -352,23 +354,15 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         let result = eval(value.clone(), env.clone())?;
                         let allocs = get_allocations(&env, "AllocationsConst");
                         allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
-                        // let mut new_hm: HashMap<String, MalVal> = HashMap::default();                        
+                        // let mut new_hm: HashMap<String, MalVal> = HashMap::default();
                         // for (k, v) in allocs.borrow_mut().iter() {
                         //     new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
                         // }
-                        // new_hm.insert(a1.pr_str(false), result.clone());      
+                        // new_hm.insert(a1.pr_str(false), result.clone());
                         if let Some(e) = &env.outer {
-                            env_set(
-                                &e,
-                                Sym("AllocationsConst".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&e, Sym("AllocationsConst".to_string()), Alloc(allocs))?;
                         } else {
-                            env_set(
-                                &env,
-                                Sym("AllocationsConst".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&env, Sym("AllocationsConst".to_string()), Alloc(allocs))?;
                         }
                         // println!("Alloc Const: {:?}", start.elapsed());
                         Ok(result.clone())
@@ -386,17 +380,9 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         // }
                         // new_hm.insert(a1.pr_str(false), result.clone());
                         if let Some(e) = &env.outer {
-                            env_set(
-                                &e,
-                                Sym("AllocationsInput".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&e, Sym("AllocationsInput".to_string()), Alloc(allocs))?;
                         } else {
-                            env_set(
-                                &env,
-                                Sym("AllocationsInput".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&env, Sym("AllocationsInput".to_string()), Alloc(allocs))?;
                         }
                         // println!("Alloc Input: {:?}", start.elapsed());
                         Ok(result.clone())
@@ -407,27 +393,19 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         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");
                         allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
                         // let mut new_hm: HashMap<String, MalVal> = HashMap::default();
                         // for (k, v) in allocs.borrow_mut().iter() {
                         //     new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
-                        // }                                        
+                        // }
                         // new_hm.insert(a1.pr_str(false), result.clone());
                         if let Some(e) = &env.outer {
-                            env_set(
-                                &e,
-                                Sym("Allocations".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&e, Sym("Allocations".to_string()), Alloc(allocs))?;
                         } else {
-                            env_set(
-                                &env,
-                                Sym("Allocations".to_string()),
-                                Alloc(allocs),
-                            )?;
+                            env_set(&env, Sym("Allocations".to_string()), Alloc(allocs))?;
                         }
                         // println!("Alloc: {:?}", start.elapsed());
                         Ok(result.clone())
@@ -445,51 +423,57 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                         // todo extract a macro for this
                         match l[1].clone() {
                             List(v, _) | Vector(v, _) => {
-                                if let List(_, _) = &v.to_vec()[0] {
-                                    for ele in v.to_vec().iter() {
-                                        if let List(ele_vec, _) = ele {
-                                            left_vec.push((
-                                                ele_vec[0].pr_str(false),
-                                                ele_vec[1].pr_str(false),
-                                            ));
+                                if v.to_vec().len() > 0 {
+                                    if let List(_, _) = &v.to_vec()[0] {
+                                        for ele in v.to_vec().iter() {
+                                            if let List(ele_vec, _) = ele {
+                                                left_vec.push((
+                                                    ele_vec[0].pr_str(false),
+                                                    ele_vec[1].pr_str(false),
+                                                ));
+                                            }
                                         }
+                                    } else {
+                                        left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                     }
-                                } else {
-                                    left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                 }
                             }
                             _ => {}
                         };
                         match l[2].clone() {
                             List(v, _) | Vector(v, _) => {
-                                if let List(_, _) = &v.to_vec()[0] {
-                                    for ele in v.to_vec().iter() {
-                                        if let List(ele_vec, _) = ele {
-                                            right_vec.push((
-                                                ele_vec[0].pr_str(false),
-                                                ele_vec[1].pr_str(false),
-                                            ));
+                                if v.to_vec().len() > 0 {
+                                    if let List(_, _) = &v.to_vec()[0] {
+                                        for ele in v.to_vec().iter() {
+                                            if let List(ele_vec, _) = ele {
+                                                right_vec.push((
+                                                    ele_vec[0].pr_str(false),
+                                                    ele_vec[1].pr_str(false),
+                                                ));
+                                            }
                                         }
+                                    } else {
+                                        right_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                     }
-                                } else {
-                                    right_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                 }
                             }
                             _ => {}
                         };
                         match l[3].clone() {
                             List(v, _) | Vector(v, _) => {
-                                if let List(_, _) = &v.to_vec()[0] {
-                                    for ele in v.to_vec().iter() {
-                                        if let List(ele_vec, _) = ele {
-                                            out_vec.push((
-                                                ele_vec[0].pr_str(false),
-                                                ele_vec[1].pr_str(false),
-                                            ));
+                                if v.to_vec().len() > 0 {
+                                    if let List(_, _) = &v.to_vec()[0] {
+                                        for ele in v.to_vec().iter() {
+                                            if let List(ele_vec, _) = ele {
+                                                out_vec.push((
+                                                    ele_vec[0].pr_str(false),
+                                                    ele_vec[1].pr_str(false),
+                                                ));
+                                            }
                                         }
+                                    } else {
+                                        out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                     }
-                                } else {
-                                    out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
                                 }
                             }
                             _ => {}

+ 10 - 4
lisp/types.rs

@@ -1,8 +1,8 @@
 use bellman::{gadgets::Assignment, groth16, Circuit, ConstraintSystem, SynthesisError};
 use sapvi::bls_extensions::BlsStringConversion;
-use std::{cell::RefCell, collections::HashMap};
 use std::ops::{Add, AddAssign, MulAssign, SubAssign};
 use std::rc::Rc;
+use std::{cell::RefCell, collections::HashMap};
 // use fnv::FnvHashMap;
 use itertools::Itertools;
 
@@ -142,7 +142,9 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                                 let val = bls12_381::Scalar::from_string(&s.to_string());
                                 left = left + (val, val_b);
                             }
-                            _ => { println!("not a valid param {:?}", value) }
+                            _ => {
+                                println!("not a valid param {:?}", value)
+                            }
                         }
                     }
                 }
@@ -169,7 +171,9 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                                 let val = bls12_381::Scalar::from_string(&s.to_string());
                                 right = right + (val, val_b);
                             }
-                            _ => { println!("not a valid param {:?}", value) }
+                            _ => {
+                                println!("not a valid param {:?}", value)
+                            }
                         }
                     }
                 }
@@ -197,7 +201,9 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                                 let val = bls12_381::Scalar::from_string(&s.to_string());
                                 output = output + (val, val_b);
                             }
-                            _ => { println!("not a valid param {:?}", value) }
+                            _ => {
+                                println!("not a valid param {:?}", value)
+                            }
                         }
                     }
                 }