1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
//! # rSnark
//!
//! rSnark is a Rust library for writing zero-knowledge circuits and generating proofs.
//!
//! It provides a core library to write circuits and a provers library to generate proofs using
//! various backend implementations like Gnark.
//!
//! ## Writing Circuits
//!
//! Defining a circuit requires two simple steps:
//!
//! 1. Define the circuit's inputs and outputs using the `#[circuit]` attribute.
//! 2. Implement the `Circuit` trait to define the circuit's constraint rules.
//!
//! ```rust,ignore
//! use rsnark::{
//! Groth16BN254GnarkProver,
//! core::{API, Circuit},
//! circuit,
//! };
//!
//! #[circuit]
//! pub struct TestCircuit {
//! a: u32, // private input
//! b: u32, // private input
//! pub c: u32, // public input
//! }
//!
//! impl Circuit for TestCircuit {
//! fn define(&self, api: &mut impl API) {
//! let c = api.add(&self.a, &self.b);
//! api.assert_is_equal(&c, &self.c);
//! }
//! }
//! ```
//!
//! ### Circuit Macro
//!
//! The `#[circuit]` attribute treats Rust's visibility modifiers as indicators of whether
//! a field is a public input or private input, automatically generating the corresponding structures.
//!
//! - Fields without `pub` are treated as **private inputs**
//! - Fields with `pub` are treated as **public inputs**
//!
//! The macro also automatically generates a Public Witness structure that can be accessed
//! using the [`PublicWitness`](crate::core::PublicWitness).
//!
//! ### Defining Circuit Constraints
//!
//! Use the `Circuit` trait to define the circuit's constraint rules. The `define` method
//! receives an API object that provides various operations for building constraints.
//!
//! ```rust,ignore
//! use rsnark::core::{API, Circuit};
//! use rsnark::circuit;
//!
//! #[circuit]
//! pub struct MultiplyCircuit {
//! x: u32,
//! y: u32,
//! pub result: u32,
//! }
//!
//! impl Circuit for MultiplyCircuit {
//! fn define(&self, api: &mut impl API) {
//! let product = api.mul(&self.x, &self.y);
//! api.assert_is_equal(&product, &self.result);
//! }
//! }
//! ```
//!
//! ### Nested Circuits
//!
//! Circuits can be easily nested by embedding other circuits as fields in the struct.
//! Sub-circuits can also implement the Circuit trait, but you must manually call the
//! sub-circuit's `define` function within the parent circuit's `define` function.
//!
//! > Note: Private has higher priority. This means that if you set a sub-circuit (which contains public fields) as private,
//! > the public inputs of that sub-circuit will not be treated as public inputs in the parent circuit.
//! > However, if you set a sub-circuit as public, its private inputs will still be treated as private inputs.
//!
//! ```rust,ignore
//! use rsnark::core::{API, Circuit};
//!
//! #[circuit]
//! pub struct AdderCircuit {
//! a: u32,
//! b: u32,
//! pub sum: u32,
//! }
//!
//! impl Circuit for AdderCircuit {
//! fn define(&self, api: &mut impl API) {
//! let result = api.add(&self.a, &self.b);
//! api.assert_is_equal(&result, &self.sum);
//! }
//! }
//!
//! #[circuit]
//! pub struct MultiplierCircuit {
//! x: u32,
//! y: u32,
//! pub product: u32,
//! }
//!
//! impl Circuit for MultiplierCircuit {
//! fn define(&self, api: &mut impl API) {
//! let result = api.mul(&self.x, &self.y);
//! api.assert_is_equal(&result, &self.product);
//! }
//! }
//!
//! #[circuit]
//! pub struct CompositeCircuit {
//! adder: AdderCircuit,
//! pub multiplier: MultiplierCircuit,
//! pub final_result: u32,
//! }
//!
//! impl Circuit for CompositeCircuit {
//! fn define(&self, api: &mut impl API) {
//! // Execute sub-circuits
//! self.adder.define(api);
//! self.multiplier.define(api);
//!
//! // Main circuit logic
//! let final_sum = api.add(&self.adder.sum, &self.multiplier.product);
//! api.assert_is_equal(&final_sum, &self.final_result);
//! }
//! }
//! ```
//!
//! ## Backend Triple
//!
//! Similar to compiler target triples, rSnark uses backend triples to define which backend,
//! curve, and proving system to use. The format is: `{proving_system}-{curve}-{backend}`.
//!
//! Currently supported backend triples:
//!
//! - [`groth16-bn254-gnark`](Groth16BN254GnarkProver) - Groth16 with BN254 curve using Gnark backend
//! - [`groth16-bls12_381-gnark`](Groth16BLS12_381GnarkProver) - Groth16 with BLS12-381 curve using Gnark backend
//! - [`groth16-bls12-377-gnark`](Groth16BLS12_377GnarkProver) - Groth16 with BLS12-377 curve using Gnark backend
//! - [`groth16-bls24_317-gnark`](Groth16BLS24_317GnarkProver) - Groth16 with BLS24-317 curve using Gnark backend
//! - [`groth16-bls24_315-gnark`](Groth16BLS24_315GnarkProver) - Groth16 with BLS24-315 curve using Gnark backend
//! - [`groth16-bw6_761-gnark`](Groth16BW6_761GnarkProver) - Groth16 with BW6-761 curve using Gnark backend
//! - [`groth16-bw6_633-gnark`](Groth16BW6_633GnarkProver) - Groth16 with BW6-633 curve using Gnark backend
//! - [`plonk-bn254-gnark`](PlonkBN254GnarkProver) - PLONK with BN254 curve using Gnark backend
//! - [`plonk-bls12_381-gnark`](PlonkBLS12_381GnarkProver) - PLONK with BLS12-381 curve using Gnark backend
//! - [`plonk-bls12_377-gnark`](PlonkBLS12_377GnarkProver) - PLONK with BLS12-377 curve using Gnark backend
//! - [`plonk-bls24-317-gnark`](PlonkBLS24_317GnarkProver) - PLONK with BLS24-317 curve using Gnark backend
//! - [`plonk-bls24_315-gnark`](PlonkBLS24_315GnarkProver) - PLONK with BLS24-315 curve using Gnark backend
//! - [`plonk-bw6_761-gnark`](PlonkBW6_761GnarkProver) - PLONK with BW6-761 curve using Gnark backend
//! - [`plonk-bw6_633-gnark`](PlonkBW6_633GnarkProver) - PLONK with BW6-633 curve using Gnark backend
//!
pub use rsnark_core as core;
/// Prover to generate
/// Provers with backend triple `groth16-bn254-gnark`
pub type Groth16BN254GnarkProver =
Prover;
/// Provers with backend triple `groth16-bls12-381-gnark`
pub type Groth16BLS12_381GnarkProver =
Prover;
/// Provers with backend triple `groth16-bls24-317-gnark`
pub type Groth16BLS24_317GnarkProver =
Prover;
/// Provers with backend triple `groth16-bls12-377-gnark`
pub type Groth16BLS12_377GnarkProver =
Prover;
/// Provers with backend triple `groth16-bw6-761-gnark`
pub type Groth16BW6_761GnarkProver =
Prover;
/// Provers with backend triple `groth16-bls24-315-gnark`
pub type Groth16BLS24_315GnarkProver =
Prover;
/// Provers with backend triple `groth16-bw6-633-gnark`
pub type Groth16BW6_633GnarkProver =
Prover;
/// Provers with backend triple `plonk-bn254-gnark`
pub type PlonkBN254GnarkProver = Prover;
/// Provers with backend triple `plonk-bls12-381-gnark`
pub type PlonkBLS12_381GnarkProver =
Prover;
/// Provers with backend triple `plonk-bls24-317-gnark`
pub type PlonkBLS24_317GnarkProver =
Prover;
/// Provers with backend triple `plonk-bls12-377-gnark`
pub type PlonkBLS12_377GnarkProver =
Prover;
/// Provers with backend triple `plonk-bw6-761-gnark`
pub type PlonkBW6_761GnarkProver =
Prover;
/// Provers with backend triple `plonk-bls24-315-gnark`
pub type PlonkBLS24_315GnarkProver =
Prover;
/// Provers with backend triple `plonk-bw6-633-gnark`
pub type PlonkBW6_633GnarkProver =
Prover;