use snarkvm_errors::gadgets::SynthesisError;
use snarkvm_models::{
curves::{Field, Zero},
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
};
struct MySillyCircuit<F: Field> {
a: Option<F>,
b: Option<F>,
}
impl<ConstraintF: Field> ConstraintSynthesizer<ConstraintF> for MySillyCircuit<ConstraintF> {
fn generate_constraints<CS: ConstraintSystem<ConstraintF>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?;
let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?;
let c = cs.alloc_input(
|| "c",
|| {
let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?;
let b = self.b.ok_or(SynthesisError::AssignmentMissing)?;
a.mul_assign(&b);
Ok(a)
},
)?;
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c);
Ok(())
}
}
mod bls12_377 {
use super::*;
use crate::snark::groth16::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof};
use core::ops::MulAssign;
use snarkvm_curves::bls12_377::{Bls12_377, Fr};
use snarkvm_utilities::rand::{test_rng, UniformRand};
#[test]
fn prove_and_verify() {
let rng = &mut test_rng();
let params = generate_random_parameters::<Bls12_377, _, _>(&MySillyCircuit { a: None, b: None }, rng).unwrap();
for _ in 0..100 {
let a = Fr::rand(rng);
let b = Fr::rand(rng);
let mut c = a;
c.mul_assign(&b);
let proof = create_random_proof(&MySillyCircuit { a: Some(a), b: Some(b) }, ¶ms, rng).unwrap();
let pvk = prepare_verifying_key::<Bls12_377>(params.vk.clone());
assert!(verify_proof(&pvk, &proof, &[c]).unwrap());
assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
}
}
}
mod bw6_761 {
use super::*;
use crate::snark::groth16::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof};
use snarkvm_curves::bw6_761::{Fr, BW6_761};
use snarkvm_utilities::rand::{test_rng, UniformRand};
#[test]
fn prove_and_verify() {
let rng = &mut test_rng();
let params = generate_random_parameters::<BW6_761, _, _>(&MySillyCircuit { a: None, b: None }, rng).unwrap();
let a = Fr::rand(rng);
let b = Fr::rand(rng);
let c = a * &b;
let proof = create_random_proof(&MySillyCircuit { a: Some(a), b: Some(b) }, ¶ms, rng).unwrap();
let pvk = prepare_verifying_key::<BW6_761>(params.vk);
assert!(verify_proof(&pvk, &proof, &[c]).unwrap());
assert!(!verify_proof(&pvk, &proof, &[Fr::zero()]).unwrap());
}
}