@@ -36,228 +36,7 @@ To import `libspartan` into your Rust project, add the following dependency to `
36
36
spartan = "0.8.0"
37
37
```
38
38
39
- The following example shows how to use ` libspartan ` to create and verify a SNARK proof.
40
- Some of our public APIs' style is inspired by the underlying crates we use.
41
-
42
- ``` rust
43
- extern crate libspartan;
44
- extern crate merlin;
45
- use libspartan :: {Instance , SNARKGens , SNARK };
46
- use merlin :: Transcript ;
47
- fn main () {
48
- // specify the size of an R1CS instance
49
- let num_vars = 1024 ;
50
- let num_cons = 1024 ;
51
- let num_inputs = 10 ;
52
- let num_non_zero_entries = 1024 ;
53
-
54
- // produce public parameters
55
- let gens = SNARKGens :: new (num_cons , num_vars , num_inputs , num_non_zero_entries );
56
-
57
- // ask the library to produce a synthentic R1CS instance
58
- let (inst , vars , inputs ) = Instance :: produce_synthetic_r1cs (num_cons , num_vars , num_inputs );
59
-
60
- // create a commitment to the R1CS instance
61
- let (comm , decomm ) = SNARK :: encode (& inst , & gens );
62
-
63
- // produce a proof of satisfiability
64
- let mut prover_transcript = Transcript :: new (b " snark_example" );
65
- let proof = SNARK :: prove (& inst , & comm , & decomm , vars , & inputs , & gens , & mut prover_transcript );
66
-
67
- // verify the proof of satisfiability
68
- let mut verifier_transcript = Transcript :: new (b " snark_example" );
69
- assert! (proof
70
- . verify (& comm , & inputs , & mut verifier_transcript , & gens )
71
- . is_ok ());
72
- println! (" proof verification successful!" );
73
- }
74
- ```
75
-
76
- Here is another example to use the NIZK variant of the Spartan proof system:
77
-
78
- ``` rust
79
- extern crate libspartan;
80
- extern crate merlin;
81
- use libspartan :: {Instance , NIZKGens , NIZK };
82
- use merlin :: Transcript ;
83
- fn main () {
84
- // specify the size of an R1CS instance
85
- let num_vars = 1024 ;
86
- let num_cons = 1024 ;
87
- let num_inputs = 10 ;
88
-
89
- // produce public parameters
90
- let gens = NIZKGens :: new (num_cons , num_vars , num_inputs );
91
-
92
- // ask the library to produce a synthentic R1CS instance
93
- let (inst , vars , inputs ) = Instance :: produce_synthetic_r1cs (num_cons , num_vars , num_inputs );
94
-
95
- // produce a proof of satisfiability
96
- let mut prover_transcript = Transcript :: new (b " nizk_example" );
97
- let proof = NIZK :: prove (& inst , vars , & inputs , & gens , & mut prover_transcript );
98
-
99
- // verify the proof of satisfiability
100
- let mut verifier_transcript = Transcript :: new (b " nizk_example" );
101
- assert! (proof
102
- . verify (& inst , & inputs , & mut verifier_transcript , & gens )
103
- . is_ok ());
104
- println! (" proof verification successful!" );
105
- }
106
- ```
107
-
108
- Finally, we provide an example that specifies a custom R1CS instance instead of using a synthetic instance
109
-
110
- ``` rust
111
- #![allow(non_snake_case)]
112
- extern crate curve25519_dalek;
113
- extern crate libspartan;
114
- extern crate merlin;
115
- use curve25519_dalek :: scalar :: Scalar ;
116
- use libspartan :: {InputsAssignment , Instance , SNARKGens , VarsAssignment , SNARK };
117
- use merlin :: Transcript ;
118
- use rand :: rngs :: OsRng ;
119
-
120
- fn main () {
121
- // produce a tiny instance
122
- let (
123
- num_cons ,
124
- num_vars ,
125
- num_inputs ,
126
- num_non_zero_entries ,
127
- inst ,
128
- assignment_vars ,
129
- assignment_inputs ,
130
- ) = produce_tiny_r1cs ();
131
-
132
- // produce public parameters
133
- let gens = SNARKGens :: new (num_cons , num_vars , num_inputs , num_non_zero_entries );
134
-
135
- // create a commitment to the R1CS instance
136
- let (comm , decomm ) = SNARK :: encode (& inst , & gens );
137
-
138
- // produce a proof of satisfiability
139
- let mut prover_transcript = Transcript :: new (b " snark_example" );
140
- let proof = SNARK :: prove (
141
- & inst ,
142
- & comm ,
143
- & decomm ,
144
- assignment_vars ,
145
- & assignment_inputs ,
146
- & gens ,
147
- & mut prover_transcript ,
148
- );
149
-
150
- // verify the proof of satisfiability
151
- let mut verifier_transcript = Transcript :: new (b " snark_example" );
152
- assert! (proof
153
- . verify (& comm , & assignment_inputs , & mut verifier_transcript , & gens )
154
- . is_ok ());
155
- println! (" proof verification successful!" );
156
- }
157
-
158
- fn produce_tiny_r1cs () -> (
159
- usize ,
160
- usize ,
161
- usize ,
162
- usize ,
163
- Instance ,
164
- VarsAssignment ,
165
- InputsAssignment ,
166
- ) {
167
- // We will use the following example, but one could construct any R1CS instance.
168
- // Our R1CS instance is three constraints over five variables and two public inputs
169
- // (Z0 + Z1) * I0 - Z2 = 0
170
- // (Z0 + I1) * Z2 - Z3 = 0
171
- // Z4 * 1 - 0 = 0
172
-
173
- // parameters of the R1CS instance rounded to the nearest power of two
174
- let num_cons = 4 ;
175
- let num_vars = 5 ;
176
- let num_inputs = 2 ;
177
- let num_non_zero_entries = 5 ;
178
-
179
- // We will encode the above constraints into three matrices, where
180
- // the coefficients in the matrix are in the little-endian byte order
181
- let mut A : Vec <(usize , usize , [u8 ; 32 ])> = Vec :: new ();
182
- let mut B : Vec <(usize , usize , [u8 ; 32 ])> = Vec :: new ();
183
- let mut C : Vec <(usize , usize , [u8 ; 32 ])> = Vec :: new ();
184
-
185
- // The constraint system is defined over a finite field, which in our case is
186
- // the scalar field of ristreeto255/curve25519 i.e., p = 2^{252}+27742317777372353535851937790883648493
187
- // To construct these matrices, we will use `curve25519-dalek` but one can use any other method.
188
-
189
- // a variable that holds a byte representation of 1
190
- let one = Scalar :: ONE . to_bytes ();
191
-
192
- // R1CS is a set of three sparse matrices A B C, where is a row for every
193
- // constraint and a column for every entry in z = (vars, 1, inputs)
194
- // An R1CS instance is satisfiable iff:
195
- // Az \circ Bz = Cz, where z = (vars, 1, inputs)
196
-
197
- // constraint 0 entries in (A,B,C)
198
- // constraint 0 is (Z0 + Z1) * I0 - Z2 = 0.
199
- // We set 1 in matrix A for columns that correspond to Z0 and Z1
200
- // We set 1 in matrix B for column that corresponds to I0
201
- // We set 1 in matrix C for column that corresponds to Z2
202
- A . push ((0 , 0 , one ));
203
- A . push ((0 , 1 , one ));
204
- B . push ((0 , num_vars + 1 , one ));
205
- C . push ((0 , 2 , one ));
206
-
207
- // constraint 1 entries in (A,B,C)
208
- A . push ((1 , 0 , one ));
209
- A . push ((1 , num_vars + 2 , one ));
210
- B . push ((1 , 2 , one ));
211
- C . push ((1 , 3 , one ));
212
-
213
- // constraint 3 entries in (A,B,C)
214
- A . push ((2 , 4 , one ));
215
- B . push ((2 , num_vars , one ));
216
-
217
- let inst = Instance :: new (num_cons , num_vars , num_inputs , & A , & B , & C ). unwrap ();
218
-
219
- // compute a satisfying assignment
220
- let mut csprng : OsRng = OsRng ;
221
- let i0 = Scalar :: random (& mut csprng );
222
- let i1 = Scalar :: random (& mut csprng );
223
- let z0 = Scalar :: random (& mut csprng );
224
- let z1 = Scalar :: random (& mut csprng );
225
- let z2 = (z0 + z1 ) * i0 ; // constraint 0
226
- let z3 = (z0 + i1 ) * z2 ; // constraint 1
227
- let z4 = Scalar :: ZERO ; // constraint 2
228
-
229
- // create a VarsAssignment
230
- let mut vars = vec! [Scalar :: ZERO . to_bytes (); num_vars ];
231
- vars [0 ] = z0 . to_bytes ();
232
- vars [1 ] = z1 . to_bytes ();
233
- vars [2 ] = z2 . to_bytes ();
234
- vars [3 ] = z3 . to_bytes ();
235
- vars [4 ] = z4 . to_bytes ();
236
- let assignment_vars = VarsAssignment :: new (& vars ). unwrap ();
237
-
238
- // create an InputsAssignment
239
- let mut inputs = vec! [Scalar :: ZERO . to_bytes (); num_inputs ];
240
- inputs [0 ] = i0 . to_bytes ();
241
- inputs [1 ] = i1 . to_bytes ();
242
- let assignment_inputs = InputsAssignment :: new (& inputs ). unwrap ();
243
-
244
- // check if the instance we created is satisfiable
245
- let res = inst . is_sat (& assignment_vars , & assignment_inputs );
246
- assert_eq! (res . unwrap (), true );
247
-
248
- (
249
- num_cons ,
250
- num_vars ,
251
- num_inputs ,
252
- num_non_zero_entries ,
253
- inst ,
254
- assignment_vars ,
255
- assignment_inputs ,
256
- )
257
- }
258
- ```
259
-
260
- For more examples, see [ ` examples/ ` ] ( examples ) directory in this repo.
39
+ For examples, see [ ` examples/ ` ] ( examples ) directory in this repo.
261
40
262
41
## Building ` libspartan `
263
42
0 commit comments