1use rsnark::PlonkBN254GnarkProver;
2use rsnark_core::{API, Circuit, CircuitWitness, Witness, circuit};
3
4#[circuit]
6pub struct AdderCircuit {
7 a: u32,
8 b: u32,
9 pub sum: u32,
10}
11
12impl Circuit for AdderCircuit {
13 fn define(&self, api: &mut impl API) {
14 let result = api.add(&self.a, &self.b);
15 api.assert_is_equal(&result, &self.sum);
16 }
17}
18
19#[circuit]
21pub struct MultiplierCircuit {
22 x: u32,
23 y: u32,
24 pub product: u32,
25}
26
27impl Circuit for MultiplierCircuit {
28 fn define(&self, api: &mut impl API) {
29 let result = api.mul(&self.x, &self.y);
30 api.assert_is_equal(&result, &self.product);
31 }
32}
33
34#[circuit]
36pub struct CompositeCircuit {
37 adder: AdderCircuit,
39 pub multiplier: MultiplierCircuit,
40
41 pub final_result: u32,
42}
43
44impl Circuit for CompositeCircuit {
45 fn define(&self, api: &mut impl API) {
46 self.adder.define(api);
48
49 self.multiplier.define(api);
51
52 let final_sum = api.add(&self.adder.sum, &self.multiplier.product);
54 api.assert_is_equal(&final_sum, &self.final_result);
55 }
56}
57
58fn main() {
59 let prover = PlonkBN254GnarkProver::new();
60
61 let circuit_prover = prover.compile_circuit::<CompositeCircuit>().unwrap();
62 let (pk, vk) = circuit_prover.setup().unwrap();
63
64 let circuit_witness = Witness::<CompositeCircuit> {
68 adder: Witness::<AdderCircuit> { a: 1, b: 2, sum: 3 },
69 multiplier: Witness::<MultiplierCircuit> {
70 x: 2,
71 y: 3,
72 product: 6,
73 },
74 final_result: 9,
75 };
76
77 let proof = circuit_prover.prove(&pk, &circuit_witness).unwrap();
78
79 let solidity_proof = proof.to_solidity().unwrap();
80 println!("Solidity proof: {:#?}", solidity_proof);
81
82 let public_witness = circuit_witness.into_public_witness();
83 circuit_prover.verify(&vk, &proof, public_witness).unwrap();
84}