arkworks_circuits/circuit/
basic.rs

1use ark_ff::PrimeField;
2use ark_relations::{
3	lc,
4	r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError},
5};
6
7#[derive(Copy)]
8struct DummyCircuit<F: PrimeField> {
9	pub a: Option<F>,
10	pub b: Option<F>,
11	pub num_variables: usize,
12	pub num_constraints: usize,
13}
14
15impl<F: PrimeField> Clone for DummyCircuit<F> {
16	fn clone(&self) -> Self {
17		DummyCircuit {
18			a: self.a,
19			b: self.b,
20			num_variables: self.num_variables,
21			num_constraints: self.num_constraints,
22		}
23	}
24}
25
26impl<F: PrimeField> ConstraintSynthesizer<F> for DummyCircuit<F> {
27	fn generate_constraints(self, cs: ConstraintSystemRef<F>) -> Result<(), SynthesisError> {
28		let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?;
29		let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?;
30		let c = cs.new_input_variable(|| {
31			let a = self.a.ok_or(SynthesisError::AssignmentMissing)?;
32			let b = self.b.ok_or(SynthesisError::AssignmentMissing)?;
33
34			Ok(a * b)
35		})?;
36
37		for _ in 0..self.num_constraints {
38			cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?;
39		}
40
41		Ok(())
42	}
43}
44
45#[cfg(test)]
46mod test {
47	use super::*;
48	use ark_bls12_381::{Bls12_381, Fr as BlsFr};
49	use ark_ed_on_bn254::{EdwardsAffine, Fr as BabyJubJub};
50	use ark_groth16::Groth16;
51	use ark_marlin::Marlin;
52	use ark_poly::univariate::DensePolynomial;
53	use ark_poly_commit::{ipa_pc::InnerProductArgPC, marlin_pc::MarlinKZG10};
54	use ark_snark::SNARK;
55	use ark_std::{ops::*, UniformRand};
56	use blake2::Blake2s;
57
58	#[test]
59	fn should_verify_basic_circuit() {
60		let rng = &mut ark_std::test_rng();
61
62		let nc = 3;
63		let nv = 3;
64		let c = DummyCircuit::<BlsFr> {
65			a: Some(BlsFr::rand(rng)),
66			b: Some(BlsFr::rand(rng)),
67			num_variables: nv,
68			num_constraints: nc,
69		};
70
71		type KZG10 = MarlinKZG10<Bls12_381, DensePolynomial<BlsFr>>;
72		type MarlinSetup = Marlin<BlsFr, KZG10, Blake2s>;
73
74		let srs = MarlinSetup::universal_setup(nc, nv, nv, rng).unwrap();
75		let (pk, vk) = MarlinSetup::index(&srs, c).unwrap();
76		let proof = MarlinSetup::prove(&pk, c.clone(), rng).unwrap();
77
78		let v = c.a.unwrap().mul(c.b.unwrap());
79
80		let res = MarlinSetup::verify(&vk, &vec![v], &proof, rng).unwrap();
81		assert!(res);
82	}
83
84	#[test]
85	fn should_verify_basic_ipa_circuit() {
86		let rng = &mut ark_std::test_rng();
87
88		let nc = 3;
89		let nv = 3;
90		let c = DummyCircuit::<BabyJubJub> {
91			a: Some(BabyJubJub::rand(rng)),
92			b: Some(BabyJubJub::rand(rng)),
93			num_variables: nv,
94			num_constraints: nc,
95		};
96
97		type UniPoly = DensePolynomial<BabyJubJub>;
98		type IPA = InnerProductArgPC<EdwardsAffine, Blake2s, UniPoly>;
99		type MarlinSetup = Marlin<BabyJubJub, IPA, Blake2s>;
100
101		let srs = MarlinSetup::universal_setup(nc, nc, nc, rng).unwrap();
102		let (pk, vk) = MarlinSetup::index(&srs, c).unwrap();
103		let proof = MarlinSetup::prove(&pk, c, rng).unwrap();
104
105		let v = c.a.unwrap().mul(c.b.unwrap());
106
107		let res = MarlinSetup::verify(&vk, &vec![v], &proof, rng).unwrap();
108		assert!(res);
109	}
110
111	#[test]
112	fn should_verify_basic_circuit_groth16() {
113		let rng = &mut ark_std::test_rng();
114		let c = DummyCircuit::<BlsFr> {
115			a: Some(BlsFr::rand(rng)),
116			b: Some(BlsFr::rand(rng)),
117			num_variables: 0,
118			num_constraints: 3,
119		};
120
121		let (pk, vk) = Groth16::<Bls12_381>::circuit_specific_setup(c, rng).unwrap();
122		let proof = Groth16::<Bls12_381>::prove(&pk, c.clone(), rng).unwrap();
123
124		let v = c.a.unwrap().mul(c.b.unwrap());
125
126		let res = Groth16::<Bls12_381>::verify(&vk, &vec![v], &proof).unwrap();
127		assert!(res);
128	}
129}