arkworks_circuits/circuit/
basic.rs1use 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}