Multiplication Circuit

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(&params.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, &params, &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!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.