Hey everyone, I wrote a zero knowledge proof using rust and bellman library and there is the code I have written.
use ff::PrimeField;
use bellman::{Circuit, ConstraintSystem, SynthesisError};
use rand::rngs::OsRng;
use ff::Field;
use bls12_381::{Bls12, Scalar};
use bellman::groth16::{
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
Proof,
};
struct MultiplyDemo<S: PrimeField>{
a: Option<S>,
b: Option<S>,
//w: Option<S>,
}
fn main(){
println!("Parameter Generation...");
let params = {
let c = MultiplyDemo{
a: None,
b: None,
//w: None,
};
generate_random_parameters::<Bls12,_,_>(c,&mut OsRng).unwrap()
};
let pvk = prepare_verifying_key(¶ms.vk);
println!("Creating Proof Elements..");
let a_prior: u8 = 10;
let b_prior: u8 = 20;
//let c_prior: u8 = 200;
let a = convert_u8(a_prior);
println!("{:?}",a);
let b = convert_u8(b_prior);
println!("{:?}",b);
let w_prior = a_prior*b_prior;
let w = convert_u8(w_prior);
println!("{:?}",w);
//let d = w;
//let c = pairing::Engine::Fr::c_prior;
let c = MultiplyDemo{
a: Some(a),
b: Some(b),
//w: Some(w),
};
let proof = create_random_proof(c, ¶ms, &mut OsRng).unwrap();
println!("{:?}",proof.a);
println!("{:?}",proof.b);
println!("{:?}",proof.c);
println!("Verifying...");
assert!(verify_proof(&pvk,&proof,&[w]).is_ok());
}
fn convert_u8<S: ff::PrimeField>(x: u8) -> S {
S::from(u64::from(x))
}
//implementation of the demo circuit
impl <S: PrimeField> Circuit<S> for MultiplyDemo<S>{
fn synthesize<CS: ConstraintSystem<S>>(self, cs: &mut CS) -> Result<(), SynthesisError>
{
//private input
let a_value = self.a;
let a = cs.alloc(|| "a",|| a_value.ok_or(SynthesisError::AssignmentMissing))?;
//public input
let b_value = self.b;
let b = cs.alloc(|| "b",|| b_value.ok_or(SynthesisError::AssignmentMissing))?;
//public input
//let cs = &mut cs.namespace(|| format!("round {}", i));
let w_value = a_value.map(|mut e| {
e.mul_assign(&b_value.unwrap());
e
});
let w = cs.alloc(|| "w", || {
w_value.ok_or(SynthesisError::AssignmentMissing)
})?;
//enforcing the fact that indeed a*b = w, using multiplication gate
cs.enforce(
|| "mult",
|lc| lc + a,
|lc| lc + b,
|lc| lc + w
);
Ok(())
}
}
It compiles fine but it does not successfully proves to be zero knowledge. I have been trying everything but I get,
thread 'main' panicked at 'assertion failed: verify_proof(&pvk, &proof, &[w]).is_ok()', src/main.rs:52:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Even if I have given the right inputs. I am really confused. Please help me understand what exactly I am doing wrong??
Thanks!