From 4c04bb2cd778b52513a0262f9aa1d87f8d9b5991 Mon Sep 17 00:00:00 2001 From: ada Date: Sun, 7 Feb 2021 16:17:03 +0100 Subject: [PATCH 1/8] added div and mul scalar, fix when param is a func --- lisp/core.rs | 42 ++++++++++++++++++++++++++++++++++-------- lisp/jubjub-add.lisp | 17 +++++++++-------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/lisp/core.rs b/lisp/core.rs index aaba8da5a..b641aac3d 100644 --- a/lisp/core.rs +++ b/lisp/core.rs @@ -262,35 +262,61 @@ fn sub_scalar(a: MalArgs) -> MalRet { s0.sub_assign(s1); Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string())) } - _ => error("expected (scalar, scalar)"), + _ => error("scalar sub expected (scalar, scalar)"), } } fn mul_scalar(a: MalArgs) -> MalRet { println!("{:?}", a); match (a[0].clone(), a[1].clone()) { + (Func(_, _), ZKScalar(a1)) => { + if let Vector(ref values, _) = a[0].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)) => { - // let (mut s0, s1) = (Scalar::from_string(&a0), Scalar::from_string(&a1)); a0.mul_assign(a1); Ok(ZKScalar(a0)) } - _ => error("expected (zkscalar, zkscalar)"), + _ => error("scalar mul expect (zkscalar, zkscalar)"), } } fn div_scalar(a: MalArgs) -> MalRet { + println!("{:?}", a); match (a[0].clone(), a[1].clone()) { + (ZKScalar(s0), ZKScalar(s1)) => { + 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), bls12_381::Scalar::from_string(&a1), ); let ret = s1.invert().map(|other| *&s0 * other); - Ok(Str( - std::string::ToString::to_string(&ret.unwrap())[2..].to_string() - )) + if bool::from(ret.is_some()) { + Ok(Str( + std::string::ToString::to_string(&ret.unwrap())[2..].to_string() + )) + } else { + error("DivisionByZero") + } } - _ => error("expected (scalar, scalar)"), + _ => error("scalar div expected (scalar, scalar)"), } } @@ -362,7 +388,7 @@ fn add_scalar(a: MalArgs) -> MalRet { let (mut z0, z1) = (a0.clone(), a1.clone()); z0.add_assign(z1); Ok(ZKScalar(z0)) - }, + } (Str(a0), Str(a1)) => { let (mut s0, s1) = ( bls12_381::Scalar::from_string(&a0), diff --git a/lisp/jubjub-add.lisp b/lisp/jubjub-add.lisp index 5d6acba8f..0abff8ff1 100644 --- a/lisp/jubjub-add.lisp +++ b/lisp/jubjub-add.lisp @@ -3,14 +3,15 @@ ;; = (u1 + v1) * (u2 + v2) ( (let* [ EDWARDS_D (alloc-const "EDWARDS_D" (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")) - u1 (alloc "u1" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) - v1 (alloc "v1" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) - u2 (alloc "u2" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) - v2 (alloc "v2" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) - U (alloc-input "U" (* (+ u1 u2) (+ v1 v2))) - A (alloc-input "A" (* v2 u1)) - B (alloc-input "B" (* u2 v1)) - C (alloc-input "C" (* EDWARDS_D (* A B))) + u1 (alloc-input "u1" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) + v1 (alloc-input "v1" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) + u2 (alloc-input "u2" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) + v2 (alloc-input "v2" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) + U (alloc "U" (* (+ u1 u2) (+ v1 v2))) + A (alloc "A" (* v2 u1)) + B (alloc "B" (* u2 v1)) + C (alloc "C" (* EDWARDS_D (* A B))) + u3 (alloc "u3" (/ (* A A) (* scalar::one C))) ] (prove (setup From 98649a6da3b61ba8713e8920e2e9d34ae5b158a9 Mon Sep 17 00:00:00 2001 From: ada Date: Sun, 7 Feb 2021 17:05:29 +0100 Subject: [PATCH 2/8] added sub, add scalar for vector and func --- lisp/core.rs | 32 ++++++++++++++++++++++++++++++-- lisp/jubjub-add.lisp | 5 ++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lisp/core.rs b/lisp/core.rs index b641aac3d..3a721c265 100644 --- a/lisp/core.rs +++ b/lisp/core.rs @@ -254,6 +254,22 @@ fn conj(a: MalArgs) -> MalRet { fn sub_scalar(a: MalArgs) -> MalRet { match (a[0].clone(), a[1].clone()) { + (Func(_, _), ZKScalar(a1)) => { + if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() { + if let ZKScalar(mut a0) = values[0] { + a0.sub_assign(a1); + 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), Str(a1)) => { let (mut s0, s1) = ( bls12_381::Scalar::from_string(&a0), @@ -262,7 +278,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 (scalar, scalar)"), + _ => error("scalar sub expected (zkscalar, zkscalar)"), } } @@ -384,6 +400,18 @@ fn scalar_from(a: MalArgs) -> MalRet { fn add_scalar(a: MalArgs) -> MalRet { match (a[0].clone(), a[1].clone()) { + (Func(_, _), ZKScalar(a1)) => { + if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() { + if let ZKScalar(mut a0) = values[0] { + a0.add_assign(a1); + 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); @@ -397,7 +425,7 @@ fn add_scalar(a: MalArgs) -> MalRet { s0.add_assign(s1); Ok(ZKScalar(s0)) } - _ => error(&format!("add scalar expected (scalar, scalar)\n {:?}", a).to_string()), + _ => error(&format!("scalar add expect (zkscalar, zkscalar) found \n {:?}", a).to_string()), } } diff --git a/lisp/jubjub-add.lisp b/lisp/jubjub-add.lisp index 0abff8ff1..9cf37a5b7 100644 --- a/lisp/jubjub-add.lisp +++ b/lisp/jubjub-add.lisp @@ -11,7 +11,10 @@ A (alloc "A" (* v2 u1)) B (alloc "B" (* u2 v1)) C (alloc "C" (* EDWARDS_D (* A B))) - u3 (alloc "u3" (/ (* A A) (* scalar::one C))) + ;; Compute u3 = (A + B) / (1 + C) + u3 (alloc "u3" (/ (+ A B) (+ scalar::one C))) + ;; Compute v3 = (U - A - B) / (1 - C) + v3 (alloc "v3" (/ (- (- U A) B) (- scalar::one C))) ] (prove (setup From f0a67ce7e3822a506a64ce60e43407efb97422db Mon Sep 17 00:00:00 2001 From: ada Date: Sun, 7 Feb 2021 23:51:05 +0100 Subject: [PATCH 3/8] adde str conversion on alloc --- lisp/jubjub-add.lisp | 10 ++++++++++ lisp/types.rs | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lisp/jubjub-add.lisp b/lisp/jubjub-add.lisp index 9cf37a5b7..6b4470bab 100644 --- a/lisp/jubjub-add.lisp +++ b/lisp/jubjub-add.lisp @@ -35,6 +35,16 @@ (scalar::one B) (scalar::one C) ) + (enforce + (scalar::one C) + (scalar::one u3) + ((scalar::one A) (scalar::one B)) + ) + (enforce + (scalar::one::neg C) + (scalar::one v3) + ((scalar::one::neg U) (scalar::one::neg A) (scalar::one::neg B)) + ) ) ) ) diff --git a/lisp/types.rs b/lisp/types.rs index 4c4367a36..c26d6b3f1 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -6,6 +6,7 @@ use bellman::{ }; use std::ops::{Add, AddAssign, MulAssign, SubAssign}; use std::cell::RefCell; +use sapvi::bls_extensions::BlsStringConversion; use std::rc::Rc; //use std::collections::HashMap; use fnv::FnvHashMap; @@ -48,12 +49,18 @@ impl Circuit for LispCircuit { println!("Allocations\n"); for (k, v) in &self.allocs { - if let MalVal::ZKScalar(val) = v { - println!("val {:?}", val); - let var = cs.alloc(|| "alloc", || Ok(*val))?; - variables.insert(k.to_string(), var); - } else { - println!("k {:?} v {:?}", k, v); + // match str + match v { + MalVal::ZKScalar(val) => { + let var = cs.alloc(|| "alloc", || Ok(*val))?; + variables.insert(k.to_string(), var); + } + MalVal::Str(val) => { + let val_scalar = bls12_381::Scalar::from_string(&*val); + let var = cs.alloc(|| "alloc", || Ok(val_scalar))?; + variables.insert(k.to_string(), var); + } + _ => { println!("not allocated k {:?} v {:?}", k, v); } } } @@ -64,7 +71,7 @@ impl Circuit for LispCircuit { let var = cs.alloc_input(|| "alloc", || Ok(*val))?; variables.insert(k.to_string(), var); } else { - println!("k {:?} v {:?}", k, v); + println!("not allocated k {:?} v {:?}", k, v); } } @@ -96,6 +103,7 @@ impl Circuit for LispCircuit { } for values in alloc_value.right.iter() { + println!("{:?}", values); let (a, b) = values; let mut val_b = CS::one(); if b != "cs::one" { From a7788bfb68ebe6755ad45ba256f4255b04a055c5 Mon Sep 17 00:00:00 2001 From: ada Date: Sun, 7 Feb 2021 23:53:57 +0100 Subject: [PATCH 4/8] adde str conversion on alloc --- lisp/types.rs | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/lisp/types.rs b/lisp/types.rs index c26d6b3f1..22b1a0b6b 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -1,12 +1,7 @@ -use bellman::{ - gadgets::{ - Assignment, - }, - groth16, Circuit, ConstraintSystem, SynthesisError, -}; -use std::ops::{Add, AddAssign, MulAssign, SubAssign}; -use std::cell::RefCell; +use bellman::{gadgets::Assignment, groth16, Circuit, ConstraintSystem, SynthesisError}; use sapvi::bls_extensions::BlsStringConversion; +use std::cell::RefCell; +use std::ops::{Add, AddAssign, MulAssign, SubAssign}; use std::rc::Rc; //use std::collections::HashMap; use fnv::FnvHashMap; @@ -49,7 +44,7 @@ impl Circuit for LispCircuit { println!("Allocations\n"); for (k, v) in &self.allocs { - // match str + // match str match v { MalVal::ZKScalar(val) => { let var = cs.alloc(|| "alloc", || Ok(*val))?; @@ -60,18 +55,28 @@ impl Circuit for LispCircuit { let var = cs.alloc(|| "alloc", || Ok(val_scalar))?; variables.insert(k.to_string(), var); } - _ => { println!("not allocated k {:?} v {:?}", k, v); } + _ => { + println!("not allocated k {:?} v {:?}", k, v); + } } } println!("Allocations Input\n"); for (k, v) in &self.alloc_inputs { - if let MalVal::ZKScalar(val) = v { - println!("val {:?}", val); - let var = cs.alloc_input(|| "alloc", || Ok(*val))?; - variables.insert(k.to_string(), var); - } else { - println!("not allocated k {:?} v {:?}", k, v); + match v { + MalVal::ZKScalar(val) => { + println!("val {:?}", val); + let var = cs.alloc_input(|| "alloc", || Ok(*val))?; + variables.insert(k.to_string(), var); + } + MalVal::Str(val) => { + let val_scalar = bls12_381::Scalar::from_string(&*val); + let var = cs.alloc(|| "alloc", || Ok(val_scalar))?; + variables.insert(k.to_string(), var); + } + _ => { + println!("not allocated k {:?} v {:?}", k, v); + } } } @@ -94,11 +99,11 @@ impl Circuit for LispCircuit { } else if a == "scalar::one::neg" { left = left + (coeff.neg(), val_b); } else { - if let Some(value) = self.params.get(a) { - if let MalVal::ZKScalar(val) = value { - left = left + (*val, val_b); + if let Some(value) = self.params.get(a) { + if let MalVal::ZKScalar(val) = value { + left = left + (*val, val_b); + } } - } } } @@ -113,7 +118,7 @@ impl Circuit for LispCircuit { right = right + (coeff, val_b); } else if a == "scalar::one::neg" { right = right + (coeff.neg(), val_b); - } + } } for values in alloc_value.output.iter() { @@ -126,7 +131,7 @@ impl Circuit for LispCircuit { output = output + (coeff, val_b); } else if a == "scalar::one::neg" { output = output + (coeff.neg(), val_b); - } + } } cs.enforce( From cc42e9097d9ace254b6c24b795e6b9b82dd9c28d Mon Sep 17 00:00:00 2001 From: ada Date: Mon, 8 Feb 2021 00:45:04 +0100 Subject: [PATCH 5/8] added prove.out file to debug proof and verify --- lisp/lisp.rs | 10 ++++++---- lisp/types.rs | 9 +++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lisp/lisp.rs b/lisp/lisp.rs index 4f322c0ee..d16223a5c 100644 --- a/lisp/lisp.rs +++ b/lisp/lisp.rs @@ -4,7 +4,10 @@ use crate::types::LispCircuit; use bellman::groth16::PreparedVerifyingKey; use simplelog::*; +use sapvi::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof}; +use std::fs; +use std::fs::File; use bellman::{groth16}; use bls12_381::Bls12; use fnv::FnvHashMap; @@ -540,9 +543,6 @@ pub fn setup(_ast: MalVal, env: Env) -> Result, MalE } pub fn prove(_ast: MalVal, env: Env) -> MalRet { - // TODO remove it - let _quantity = bls12_381::Scalar::from(3); - let allocs_input = get_allocations(&env, "AllocationsInput"); let allocs = get_allocations(&env, "Allocations"); let enforce_allocs = get_enforce_allocs(&env); @@ -563,8 +563,10 @@ pub fn prove(_ast: MalVal, env: Env) -> MalRet { }; let start = Instant::now(); // Create a Groth16 proof with our parameters. - let _proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); + let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); println!("Prove: [{:?}]", start.elapsed()); + let mut file = File::create("prove.out").unwrap(); + proof.write(file); Ok(MalVal::Nil) } diff --git a/lisp/types.rs b/lisp/types.rs index 22b1a0b6b..de8b760ed 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -44,7 +44,7 @@ impl Circuit for LispCircuit { println!("Allocations\n"); for (k, v) in &self.allocs { - // match str + println!("k {:?} v {:?}", k, v); match v { MalVal::ZKScalar(val) => { let var = cs.alloc(|| "alloc", || Ok(*val))?; @@ -63,15 +63,15 @@ impl Circuit for LispCircuit { println!("Allocations Input\n"); for (k, v) in &self.alloc_inputs { + println!("k {:?} v {:?}", k, v); match v { MalVal::ZKScalar(val) => { - println!("val {:?}", val); let var = cs.alloc_input(|| "alloc", || Ok(*val))?; variables.insert(k.to_string(), var); } MalVal::Str(val) => { let val_scalar = bls12_381::Scalar::from_string(&*val); - let var = cs.alloc(|| "alloc", || Ok(val_scalar))?; + let var = cs.alloc_input(|| "alloc", || Ok(val_scalar))?; variables.insert(k.to_string(), var); } _ => { @@ -82,13 +82,11 @@ impl Circuit for LispCircuit { println!("Enforce Allocations\n"); for alloc_value in &self.constraints { - println!("{:?}", alloc_value); let coeff = bls12_381::Scalar::one(); let mut left = bellman::LinearCombination::::zero(); let mut right = bellman::LinearCombination::::zero(); let mut output = bellman::LinearCombination::::zero(); for values in alloc_value.left.iter() { - println!("values {:?}", values); let (a, b) = values; let mut val_b = CS::one(); if b != "cs::one" { @@ -108,7 +106,6 @@ impl Circuit for LispCircuit { } for values in alloc_value.right.iter() { - println!("{:?}", values); let (a, b) = values; let mut val_b = CS::one(); if b != "cs::one" { From 282f0c87d60f7b87b75316c31aefb06fa881afa4 Mon Sep 17 00:00:00 2001 From: ada Date: Mon, 8 Feb 2021 17:54:57 +0100 Subject: [PATCH 6/8] added prove --- lisp/jubjub-add.lisp | 38 +++++++++++--------------- lisp/lisp.rs | 64 +++++++++++++++++++++++++++++--------------- lisp/run.sh | 2 +- lisp/types.rs | 20 +++++++------- 4 files changed, 71 insertions(+), 53 deletions(-) diff --git a/lisp/jubjub-add.lisp b/lisp/jubjub-add.lisp index 6b4470bab..9ad56cec3 100644 --- a/lisp/jubjub-add.lisp +++ b/lisp/jubjub-add.lisp @@ -1,33 +1,29 @@ (println "jubjub-add.lisp") -;; Compute U = (u1 + v1) * (v2 - EDWARDS_A*u2) -;; = (u1 + v1) * (u2 + v2) -( (let* [ +(def! param1 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) +(def! param2 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) +(def! param3 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) +(def! param4 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) + +( + (let* [ + u1 (alloc-input "u1" param1) + v1 (alloc-input "v1" param2) + u2 (alloc-input "u2" param3) + v2 (alloc-input "v2" param4) EDWARDS_D (alloc-const "EDWARDS_D" (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")) - u1 (alloc-input "u1" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) - v1 (alloc-input "v1" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) - u2 (alloc-input "u2" (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e")) - v2 (alloc-input "v2" (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891")) U (alloc "U" (* (+ u1 u2) (+ v1 v2))) A (alloc "A" (* v2 u1)) B (alloc "B" (* u2 v1)) C (alloc "C" (* EDWARDS_D (* A B))) - ;; Compute u3 = (A + B) / (1 + C) u3 (alloc "u3" (/ (+ A B) (+ scalar::one C))) - ;; Compute v3 = (U - A - B) / (1 - C) v3 (alloc "v3" (/ (- (- U A) B) (- scalar::one C))) ] -(prove - (setup + (prove + (setup ( (enforce - ( - (scalar::one u1) - (scalar::one v1) - ) - ( - (scalar::one u2) - (scalar::one v2) - ) + ((scalar::one u1) (scalar::one v1)) + ((scalar::one u2) (scalar::one v2)) (scalar::one U) ) (enforce @@ -47,7 +43,5 @@ ) ) ) -) -) - ) +))) ;; (println 'verify (MyCircuit (scalar 27))) diff --git a/lisp/lisp.rs b/lisp/lisp.rs index d16223a5c..33ac38f6a 100644 --- a/lisp/lisp.rs +++ b/lisp/lisp.rs @@ -527,11 +527,11 @@ pub fn setup(_ast: MalVal, env: Env) -> Result, MalE let enforce_allocs = get_enforce_allocs(&env); let c = LispCircuit { - params: allocs_const.as_ref().clone(), - allocs: allocs.as_ref().clone(), - alloc_inputs: allocs_input.as_ref().clone(), - constraints: enforce_allocs, - env: env.clone(), + params: None, + allocs: None, + alloc_inputs: None, + constraints: None, + env: None }; // TODO move to another fn let random_parameters = @@ -548,26 +548,48 @@ pub fn prove(_ast: MalVal, env: Env) -> MalRet { let enforce_allocs = get_enforce_allocs(&env); let allocs_const = get_allocations(&env, "AllocationsConst"); - let circuit = LispCircuit { - params: allocs_const.as_ref().clone(), - allocs: allocs.as_ref().clone(), - alloc_inputs: allocs_input.as_ref().clone(), - constraints: enforce_allocs, - env: env.clone(), - }; - // Create an instance of our circuit (with the preimage as a witness). - // todo check if circuit.clone is valid let params = { - let c = circuit.clone(); + let c = LispCircuit { + params: Some(FnvHashMap::default()), + allocs: Some(FnvHashMap::default()), + alloc_inputs: Some(FnvHashMap::default()), + constraints: Some(vec![]), + env: Some(env.clone()) + }; groth16::generate_random_parameters::(c, &mut OsRng).unwrap() }; + let pvk = groth16::prepare_verifying_key(¶ms.vk); + + let circuit = LispCircuit { + params: Some(allocs_const.as_ref().clone()), + allocs: Some(allocs.as_ref().clone()), + alloc_inputs: Some(allocs_input.as_ref().clone()), + constraints: Some(enforce_allocs), + env: Some(env.clone()) + }; let start = Instant::now(); - // Create a Groth16 proof with our parameters. - let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); - println!("Prove: [{:?}]", start.elapsed()); - let mut file = File::create("prove.out").unwrap(); - proof.write(file); - Ok(MalVal::Nil) + let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng); + match proof { + _ => { + println!("Prove: [{:?}]", start.elapsed()); + let mut file = File::create("prove.out").unwrap(); + //proof.write(file); + + let mut vec_input = vec![]; + for (k, val) in allocs_input.iter() { + if let MalVal::ZKScalar(v) = val { + vec_input.push(*v); + } + } +// let verify_result = groth16::verify_proof(&pvk, &proof, &vec_input.as_slice()).is_ok(); +// println!("{:?}", verify_result); + } + Err(e) => { + println!("{:?}", e); + } + }; + Ok(MalVal::Nil) + } pub fn verify(_ast: &MalVal) -> MalRet { diff --git a/lisp/run.sh b/lisp/run.sh index 9f0c05186..f34da13f7 100755 --- a/lisp/run.sh +++ b/lisp/run.sh @@ -1,2 +1,2 @@ -#export RUST_BACKTRACE=full +export RUST_BACKTRACE=full cargo run --bin lisp load jubjub-add.lisp diff --git a/lisp/types.rs b/lisp/types.rs index de8b760ed..a7395d593 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -28,11 +28,11 @@ pub struct EnforceAllocation { #[derive(Debug, Clone)] pub struct LispCircuit { - pub params: FnvHashMap, - pub allocs: FnvHashMap, - pub alloc_inputs: FnvHashMap, - pub constraints: Vec, - pub env: Env, + pub params: Option>, + pub allocs: Option>, + pub alloc_inputs: Option>, + pub constraints: Option>, + pub env: Option, } impl Circuit for LispCircuit { @@ -41,9 +41,10 @@ impl Circuit for LispCircuit { cs: &mut CS, ) -> Result<(), SynthesisError> { let mut variables: FnvHashMap = FnvHashMap::default(); + let mut params_const = self.params.unwrap_or(FnvHashMap::default()); println!("Allocations\n"); - for (k, v) in &self.allocs { + for (k, v) in &self.allocs.unwrap_or(FnvHashMap::default()) { println!("k {:?} v {:?}", k, v); match v { MalVal::ZKScalar(val) => { @@ -62,7 +63,7 @@ impl Circuit for LispCircuit { } println!("Allocations Input\n"); - for (k, v) in &self.alloc_inputs { + for (k, v) in &self.alloc_inputs.unwrap_or(FnvHashMap::default()) { println!("k {:?} v {:?}", k, v); match v { MalVal::ZKScalar(val) => { @@ -81,7 +82,8 @@ impl Circuit for LispCircuit { } println!("Enforce Allocations\n"); - for alloc_value in &self.constraints { + for alloc_value in &self.constraints.unwrap_or(Vec::::new()) { + println!("{:?}", alloc_value); let coeff = bls12_381::Scalar::one(); let mut left = bellman::LinearCombination::::zero(); let mut right = bellman::LinearCombination::::zero(); @@ -97,7 +99,7 @@ impl Circuit for LispCircuit { } else if a == "scalar::one::neg" { left = left + (coeff.neg(), val_b); } else { - if let Some(value) = self.params.get(a) { + if let Some(value) = params_const.get(a) { if let MalVal::ZKScalar(val) = value { left = left + (*val, val_b); } From fdaebbef08ecc87a24c20e406954a5e0dffa5703 Mon Sep 17 00:00:00 2001 From: ada Date: Wed, 10 Feb 2021 00:54:23 +0100 Subject: [PATCH 7/8] some random adjustments on groth16 proof --- lisp/lisp.rs | 57 +++++++++++++++++++++------------------------------ lisp/types.rs | 5 ++--- 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/lisp/lisp.rs b/lisp/lisp.rs index 33ac38f6a..1cf3fb0ea 100644 --- a/lisp/lisp.rs +++ b/lisp/lisp.rs @@ -3,18 +3,18 @@ use crate::types::LispCircuit; use bellman::groth16::PreparedVerifyingKey; -use simplelog::*; use sapvi::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof}; +use simplelog::*; -use std::fs; -use std::fs::File; -use bellman::{groth16}; +use bellman::groth16; 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::{rc::Rc}; use types::EnforceAllocation; #[macro_use] @@ -530,8 +530,7 @@ pub fn setup(_ast: MalVal, env: Env) -> Result, MalE params: None, allocs: None, alloc_inputs: None, - constraints: None, - env: None + constraints: None }; // TODO move to another fn let random_parameters = @@ -548,48 +547,38 @@ pub fn prove(_ast: MalVal, env: Env) -> MalRet { let enforce_allocs = get_enforce_allocs(&env); let allocs_const = get_allocations(&env, "AllocationsConst"); + let start = Instant::now(); + let circuit = LispCircuit { + params: Some(allocs_const.as_ref().clone()), + allocs: Some(allocs.as_ref().clone()), + alloc_inputs: Some(allocs_input.as_ref().clone()), + constraints: Some(enforce_allocs), + }; let params = { - let c = LispCircuit { - params: Some(FnvHashMap::default()), - allocs: Some(FnvHashMap::default()), - alloc_inputs: Some(FnvHashMap::default()), - constraints: Some(vec![]), - env: Some(env.clone()) - }; + let c = circuit.clone(); groth16::generate_random_parameters::(c, &mut OsRng).unwrap() }; - let pvk = groth16::prepare_verifying_key(¶ms.vk); - - let circuit = LispCircuit { - params: Some(allocs_const.as_ref().clone()), - allocs: Some(allocs.as_ref().clone()), - alloc_inputs: Some(allocs_input.as_ref().clone()), - constraints: Some(enforce_allocs), - env: Some(env.clone()) - }; - let start = Instant::now(); - let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng); + let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); + /* match proof { - _ => { + Ok(v) => { println!("Prove: [{:?}]", start.elapsed()); - let mut file = File::create("prove.out").unwrap(); - //proof.write(file); let mut vec_input = vec![]; for (k, val) in allocs_input.iter() { if let MalVal::ZKScalar(v) = val { - vec_input.push(*v); + vec_input.push(*v); } } -// let verify_result = groth16::verify_proof(&pvk, &proof, &vec_input.as_slice()).is_ok(); -// println!("{:?}", verify_result); + // let verify_result = groth16::verify_proof(&pvk, &proof, &vec_input.as_slice()).is_ok(); + // println!("{:?}", verify_result); } Err(e) => { - println!("{:?}", e); + println!("Error {:?}", e); } }; - Ok(MalVal::Nil) - + */ + Ok(MalVal::Nil) } pub fn verify(_ast: &MalVal) -> MalRet { diff --git a/lisp/types.rs b/lisp/types.rs index a7395d593..b92d6a19b 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -31,8 +31,7 @@ pub struct LispCircuit { pub params: Option>, pub allocs: Option>, pub alloc_inputs: Option>, - pub constraints: Option>, - pub env: Option, + pub constraints: Option> } impl Circuit for LispCircuit { @@ -41,7 +40,7 @@ impl Circuit for LispCircuit { cs: &mut CS, ) -> Result<(), SynthesisError> { let mut variables: FnvHashMap = FnvHashMap::default(); - let mut params_const = self.params.unwrap_or(FnvHashMap::default()); + let mut params_const = self.params.unwrap_or(FnvHashMap::default()); println!("Allocations\n"); for (k, v) in &self.allocs.unwrap_or(FnvHashMap::default()) { From 32746d07481b5e9511ec8fcdc70ce0556422c3ff Mon Sep 17 00:00:00 2001 From: ada Date: Wed, 10 Feb 2021 21:51:54 +0100 Subject: [PATCH 8/8] adding verify on lisp --- lisp/inverse.lisp | 34 ++++++++++++++++++++++++++++++++++ lisp/lisp.rs | 40 +++++++++++++++++----------------------- lisp/new-cs.lisp | 8 ++------ lisp/run.sh | 3 ++- lisp/types.rs | 10 ++++++---- 5 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 lisp/inverse.lisp diff --git a/lisp/inverse.lisp b/lisp/inverse.lisp new file mode 100644 index 000000000..34aa17c42 --- /dev/null +++ b/lisp/inverse.lisp @@ -0,0 +1,34 @@ +(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 3)) + ] +(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))) diff --git a/lisp/lisp.rs b/lisp/lisp.rs index 1cf3fb0ea..be133575e 100644 --- a/lisp/lisp.rs +++ b/lisp/lisp.rs @@ -521,16 +521,12 @@ pub fn setup(_ast: MalVal, env: Env) -> Result, MalE let start = Instant::now(); // Create parameters for our circuit. In a production deployment these would // be generated securely using a multiparty computation. - let allocs_input = get_allocations(&env, "AllocationsInput"); - let allocs = get_allocations(&env, "Allocations"); - let allocs_const = get_allocations(&env, "AllocationsConst"); - let enforce_allocs = get_enforce_allocs(&env); let c = LispCircuit { params: None, allocs: None, alloc_inputs: None, - constraints: None + constraints: None, }; // TODO move to another fn let random_parameters = @@ -558,26 +554,24 @@ pub fn prove(_ast: MalVal, env: Env) -> MalRet { let c = circuit.clone(); groth16::generate_random_parameters::(c, &mut OsRng).unwrap() }; - let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); - /* - match proof { - Ok(v) => { - println!("Prove: [{:?}]", start.elapsed()); - let mut vec_input = vec![]; - for (k, val) in allocs_input.iter() { - if let MalVal::ZKScalar(v) = val { - vec_input.push(*v); - } - } - // let verify_result = groth16::verify_proof(&pvk, &proof, &vec_input.as_slice()).is_ok(); - // println!("{:?}", verify_result); + let proof = groth16::create_random_proof(circuit, ¶ms, &mut OsRng).unwrap(); + let mut buf = File::create("proof.output").unwrap(); + proof.write(buf); + println!("Prove: [{:?}]", start.elapsed()); + let proof_file = File::open("proof.output").unwrap(); + let reader = std::io::BufReader::new(proof_file); + let proof_read: groth16::Proof = groth16::Proof::read(reader).unwrap(); + let mut vec_input = vec![]; + for (k, val) in allocs_input.iter() { + if let MalVal::ZKScalar(v) = val { + vec_input.push(*v); } - Err(e) => { - println!("Error {:?}", e); - } - }; - */ + } + let pvk = setup(_ast.clone(), env.clone()).unwrap(); + println!("{:?}", vec_input); + let verify_result = groth16::verify_proof(&pvk, &proof, &vec_input.as_slice()); + println!("{:?}", verify_result); Ok(MalVal::Nil) } diff --git a/lisp/new-cs.lisp b/lisp/new-cs.lisp index bc33782e2..f28a446cf 100644 --- a/lisp/new-cs.lisp +++ b/lisp/new-cs.lisp @@ -4,17 +4,13 @@ x (alloc "x" aux) x2 (alloc "x2" (* aux aux)) x3 (alloc "x3" (* aux (* aux aux))) - input (alloc-input "input" aux) + input (alloc-input "input" (scalar 27)) ] (prove (setup ( (enforce - ( - (scalar::one x) - (scalar::one x2) - ) - ;;(scalar::one::neg x) + (scalar::one x) (scalar::one x) (scalar::one x2) ) diff --git a/lisp/run.sh b/lisp/run.sh index f34da13f7..9d9b6f16d 100755 --- a/lisp/run.sh +++ b/lisp/run.sh @@ -1,2 +1,3 @@ export RUST_BACKTRACE=full -cargo run --bin lisp load jubjub-add.lisp +#cargo run --bin lisp load jubjub-add.lisp +cargo run --bin lisp load inverse.lisp diff --git a/lisp/types.rs b/lisp/types.rs index b92d6a19b..129fad361 100644 --- a/lisp/types.rs +++ b/lisp/types.rs @@ -31,7 +31,7 @@ pub struct LispCircuit { pub params: Option>, pub allocs: Option>, pub alloc_inputs: Option>, - pub constraints: Option> + pub constraints: Option>, } impl Circuit for LispCircuit { @@ -81,14 +81,15 @@ impl Circuit for LispCircuit { } println!("Enforce Allocations\n"); - for alloc_value in &self.constraints.unwrap_or(Vec::::new()) { - println!("{:?}", alloc_value); + // we need to keep order + for alloc_value in self.constraints.unwrap_or(Vec::::new()).iter() { let coeff = bls12_381::Scalar::one(); let mut left = bellman::LinearCombination::::zero(); let mut right = bellman::LinearCombination::::zero(); let mut output = bellman::LinearCombination::::zero(); for values in alloc_value.left.iter() { let (a, b) = values; + println!("a {:?} b {:?}", a, b); let mut val_b = CS::one(); if b != "cs::one" { val_b = *variables.get(b).unwrap(); @@ -102,7 +103,7 @@ impl Circuit for LispCircuit { if let MalVal::ZKScalar(val) = value { left = left + (*val, val_b); } - } + } } } @@ -138,6 +139,7 @@ impl Circuit for LispCircuit { |_| right.clone(), |_| output.clone(), ); + } Ok(())