debugging

This commit is contained in:
ada
2021-02-11 20:55:42 +01:00
parent 32746d0748
commit b652168355
4 changed files with 175 additions and 152 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

View File

@@ -29,6 +29,7 @@ extern crate regex;
mod types;
use crate::types::MalErr::{ErrMalVal, ErrString};
use crate::types::MalVal::{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;
mod printer;
@@ -297,7 +298,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
let a1 = l[1].clone();
// todo
ast = eval(a1.clone(), env.clone())?;
let _pvk = setup(a1.clone(), env.clone())?;
// let _pvk = setup(a1.clone(), env.clone())?;
continue 'tco;
}
Sym(ref a0sym) if a0sym == "prove" => {
@@ -517,69 +518,73 @@ pub fn get_allocations(env: &Env, key: &str) -> Rc<FnvHashMap<String, MalVal>> {
}
}
pub fn setup(_ast: MalVal, env: Env) -> Result<PreparedVerifyingKey<Bls12>, MalErr> {
pub fn setup(_ast: MalVal, env: Env) -> Result<VerifyKeyParams, MalErr> {
let start = Instant::now();
// Create parameters for our circuit. In a production deployment these would
// be generated securely using a multiparty computation.
let c = LispCircuit {
params: None,
allocs: None,
alloc_inputs: None,
constraints: None,
};
// TODO move to another fn
let c = LispCircuit {
params: FnvHashMap::default(),
allocs: FnvHashMap::default(),
alloc_inputs: FnvHashMap::default(),
constraints: Vec::new()
};
let random_parameters =
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap();
let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
println!("Setup: [{:?}]", start.elapsed());
Ok(pvk)
Ok(VerifyKeyParams {
verifying_key: pvk,
random_params: random_parameters,
})
}
pub fn prove(_ast: MalVal, env: Env) -> MalRet {
let start = Instant::now();
let allocs_input = get_allocations(&env, "AllocationsInput");
let allocs = get_allocations(&env, "Allocations");
let enforce_allocs = get_enforce_allocs(&env);
let allocs_const = get_allocations(&env, "AllocationsConst");
let start = Instant::now();
let params = Some({
let c = LispCircuit {
params: FnvHashMap::default(),
allocs: FnvHashMap::default(),
alloc_inputs: FnvHashMap::default(),
constraints: Vec::new()
};
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng)?
});
let verifying_key = Some(groth16::prepare_verifying_key(&params.as_ref().unwrap().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),
};
let params = {
let c = circuit.clone();
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
params: allocs_const.as_ref().clone(),
allocs: allocs.as_ref().clone(),
alloc_inputs: allocs_input.as_ref().clone(),
constraints: enforce_allocs.clone(),
};
let proof = groth16::create_random_proof(circuit, &params, &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<bls12_381::Bls12> = groth16::Proof::read(reader).unwrap();
let proof =
groth16::create_random_proof(circuit, params.as_ref().unwrap(), &mut OsRng)?;
let mut vec_input = vec![];
for (k, val) in allocs_input.iter() {
if let MalVal::ZKScalar(v) = val {
vec_input.push(*v);
}
}
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);
println!("vec input {:?}", vec_input);
let result = groth16::verify_proof(
verifying_key.as_ref().unwrap(),
&proof,
vec_input.as_slice(),
);
println!("{:?}", result);
Ok(MalVal::Nil)
}
pub fn verify(_ast: &MalVal) -> MalRet {
let _public_input = vec![bls12_381::Scalar::from(27)];
let start = Instant::now();
// Check the proof!
//assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
println!("Verify: [{:?}]", start.elapsed());
Ok(MalVal::Nil)
}

View File

@@ -4,7 +4,7 @@
x (alloc "x" aux)
x2 (alloc "x2" (* aux aux))
x3 (alloc "x3" (* aux (* aux aux)))
input (alloc-input "input" (scalar 27))
input (alloc-input "input" (scalar 3))
]
(prove
(setup

View File

@@ -11,6 +11,7 @@ use crate::env::{env_bind, Env};
use crate::types::MalErr::{ErrMalVal, ErrString};
use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector};
use bellman::Variable;
use bls12_381::Bls12;
use bls12_381::Scalar;
#[derive(Debug, Clone)]
@@ -26,124 +27,17 @@ pub struct EnforceAllocation {
pub output: Vec<(String, String)>,
}
#[derive(Debug, Clone)]
pub struct LispCircuit {
pub params: Option<FnvHashMap<String, MalVal>>,
pub allocs: Option<FnvHashMap<String, MalVal>>,
pub alloc_inputs: Option<FnvHashMap<String, MalVal>>,
pub constraints: Option<Vec<EnforceAllocation>>,
pub struct VerifyKeyParams {
pub random_params: groth16::Parameters<Bls12>,
pub verifying_key: groth16::PreparedVerifyingKey<Bls12>,
}
impl Circuit<bls12_381::Scalar> for LispCircuit {
fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
let mut variables: FnvHashMap<String, Variable> = 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()) {
println!("k {:?} v {:?}", k, v);
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);
}
}
}
println!("Allocations Input\n");
for (k, v) in &self.alloc_inputs.unwrap_or(FnvHashMap::default()) {
println!("k {:?} v {:?}", k, v);
match v {
MalVal::ZKScalar(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_input(|| "alloc", || Ok(val_scalar))?;
variables.insert(k.to_string(), var);
}
_ => {
println!("not allocated k {:?} v {:?}", k, v);
}
}
}
println!("Enforce Allocations\n");
// we need to keep order
for alloc_value in self.constraints.unwrap_or(Vec::<EnforceAllocation>::new()).iter() {
let coeff = bls12_381::Scalar::one();
let mut left = bellman::LinearCombination::<Scalar>::zero();
let mut right = bellman::LinearCombination::<Scalar>::zero();
let mut output = bellman::LinearCombination::<Scalar>::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();
}
if a == "scalar::one" {
left = left + (coeff, val_b);
} else if a == "scalar::one::neg" {
left = left + (coeff.neg(), val_b);
} else {
if let Some(value) = params_const.get(a) {
if let MalVal::ZKScalar(val) = value {
left = left + (*val, val_b);
}
}
}
}
for values in alloc_value.right.iter() {
let (a, b) = values;
let mut val_b = CS::one();
if b != "cs::one" {
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
right = right + (coeff, val_b);
} else if a == "scalar::one::neg" {
right = right + (coeff.neg(), val_b);
}
}
for values in alloc_value.output.iter() {
let (a, b) = values;
let mut val_b = CS::one();
if b != "cs::one" {
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);
}
}
cs.enforce(
|| "constraint",
|_| left.clone(),
|_| right.clone(),
|_| output.clone(),
);
}
Ok(())
}
#[derive(Debug, Clone)]
pub struct LispCircuit {
pub params: FnvHashMap<String, MalVal>,
pub allocs: FnvHashMap<String, MalVal>,
pub alloc_inputs: FnvHashMap<String, MalVal>,
pub constraints: Vec<EnforceAllocation>,
}
#[derive(Debug, Clone)]
@@ -171,12 +65,136 @@ pub enum MalVal {
ZKScalar(bls12_381::Scalar),
}
impl Circuit<bls12_381::Scalar> for LispCircuit {
fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
let mut variables: FnvHashMap<String, Variable> = FnvHashMap::default();
let mut params_const = self.params;
println!("Allocations\n");
for (k, v) in &self.allocs {
println!("k {:?} v {:?}", k, v);
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);
}
}
}
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(|| "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_input(|| "alloc", || Ok(val_scalar))?;
variables.insert(k.to_string(), var);
}
_ => {
println!("not allocated k {:?} v {:?}", k, v);
}
}
}
println!("Enforce Allocations\n");
// we need to keep order
for alloc_value in self.constraints.iter() {
let coeff = bls12_381::Scalar::one();
let mut left = bellman::LinearCombination::<Scalar>::zero();
let mut right = bellman::LinearCombination::<Scalar>::zero();
let mut output = bellman::LinearCombination::<Scalar>::zero();
for values in alloc_value.left.iter() {
let (a, b) = values;
println!("left: a {:?} b {:?}", a, b);
let mut val_b = CS::one();
if b != "cs::one" {
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
left = left + (coeff, val_b);
} else if a == "scalar::one::neg" {
left = left + (coeff.neg(), val_b);
} else {
if let Some(value) = params_const.get(a) {
if let MalVal::ZKScalar(val) = value {
left = left + (*val, val_b);
}
}
println!("here i am");
}
}
for values in alloc_value.right.iter() {
let (a, b) = values;
println!("right: a {:?} b {:?}", a, b);
let mut val_b = CS::one();
if b != "cs::one" {
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
right = right + (coeff, val_b);
} else if a == "scalar::one::neg" {
right = right + (coeff.neg(), val_b);
} else {
println!("here i am");
}
}
for values in alloc_value.output.iter() {
let (a, b) = values;
println!("output: a {:?} b {:?}", a, b);
let mut val_b = CS::one();
if b != "cs::one" {
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
output = output + (Scalar::one(), val_b);
} else if a == "scalar::one::neg" {
output = output + (Scalar::one().neg(), val_b);
} else {
println!("here i am");
}
}
cs.enforce(
|| "constraint",
|_| left.clone(),
|_| right.clone(),
|_| output.clone(),
);
}
Ok(())
}
}
#[derive(Debug)]
pub enum MalErr {
ErrString(String),
ErrMalVal(MalVal),
}
impl From<SynthesisError> for MalErr {
fn from(err: SynthesisError) -> MalErr {
ErrString("SynthesisError".to_string())
}
}
pub type MalArgs = Vec<MalVal>;
pub type MalRet = Result<MalVal, MalErr>;