@@ -8,7 +8,7 @@ use std::alloc::Global;
8
8
// - wrapping the proof into SNARK.
9
9
use std:: path:: Path ;
10
10
11
- use clap:: Parser ;
11
+ use clap:: { Parser , Subcommand } ;
12
12
13
13
use bellman:: kate_commitment:: { Crs , CrsForMonomialForm } ;
14
14
use bellman:: worker:: Worker as BellmanWorker ;
@@ -20,7 +20,7 @@ use execution_utils::{
20
20
} ;
21
21
use risc_verifier:: prover:: worker:: Worker ;
22
22
use zkos_wrapper:: circuits:: BinaryCommitment ;
23
- use zkos_wrapper:: { Bn256 , L1_VERIFIER_DOMAIN_SIZE_LOG } ;
23
+ use zkos_wrapper:: { Bn256 , L1_VERIFIER_DOMAIN_SIZE_LOG , calculate_verification_key_hash } ;
24
24
use zkos_wrapper:: {
25
25
circuits:: RiscWrapperWitness , get_compression_setup, get_risc_wrapper_setup,
26
26
get_snark_wrapper_setup, prove_compression, prove_risc_wrapper, prove_snark_wrapper,
@@ -30,16 +30,50 @@ use zkos_wrapper::{
30
30
#[ derive( Parser ) ]
31
31
#[ command( version, about, long_about = None ) ]
32
32
struct Cli {
33
- #[ arg( short, long) ]
34
- input : String ,
35
-
36
- // Binary used to generate the proof.
37
- // If not specified, take the default binary (fibonacci hasher).
38
- #[ arg( long) ]
39
- input_binary : Option < String > ,
33
+ #[ command( subcommand) ]
34
+ command : Commands ,
35
+ }
40
36
41
- #[ arg( short, long) ]
42
- output_dir : String ,
37
+ #[ derive( Subcommand ) ]
38
+ enum Commands {
39
+ /// Take the riscV final proof, and create a SNARK proof.
40
+ Prove {
41
+ #[ arg( short, long) ]
42
+ input : String ,
43
+
44
+ // Binary used to generate the proof.
45
+ // If not specified, take the default binary (fibonacci hasher).
46
+ #[ arg( long) ]
47
+ input_binary : Option < String > ,
48
+
49
+ #[ arg( short, long) ]
50
+ output_dir : String ,
51
+
52
+ /// File with the trusted setup.
53
+ /// If missing - will use the 'fake' trusted setup.
54
+ #[ arg( long) ]
55
+ trusted_setup_file : Option < String > ,
56
+ } ,
57
+ /// Generate verification key for the SNARK proof.
58
+ GenerateVk {
59
+ // Binary used to generate the proof.
60
+ // If not specified, take the default binary (fibonacci hasher).
61
+ #[ arg( long) ]
62
+ input_binary : String ,
63
+
64
+ #[ arg( short, long) ]
65
+ output_dir : String ,
66
+
67
+ /// File with the trusted setup.
68
+ /// If missing - will use the 'fake' trusted setup.
69
+ #[ arg( long) ]
70
+ trusted_setup_file : String ,
71
+
72
+ /// If true, then create VK for universal verifier program.
73
+ /// If false then for the separate verifiers.
74
+ #[ arg( long) ]
75
+ universal_verifier : bool ,
76
+ } ,
43
77
}
44
78
45
79
fn serialize_to_file < T : serde:: ser:: Serialize > ( content : & T , filename : & Path ) {
@@ -52,6 +86,14 @@ fn deserialize_from_file<T: serde::de::DeserializeOwned>(filename: &str) -> T {
52
86
serde_json:: from_reader ( src) . unwrap ( )
53
87
}
54
88
89
+ /// Uploads trusted setup file to the RAM
90
+ pub fn get_trusted_setup ( crs_file_str : & String ) -> Crs < Bn256 , CrsForMonomialForm > {
91
+ let crs_file_path = std:: path:: Path :: new ( crs_file_str) ;
92
+ let crs_file = std:: fs:: File :: open ( & crs_file_path)
93
+ . expect ( format ! ( "Trying to open CRS FILE: {:?}" , crs_file_path) . as_str ( ) ) ;
94
+ Crs :: read ( & crs_file) . expect ( format ! ( "Trying to read CRS FILE: {:?}" , crs_file_path) . as_str ( ) )
95
+ }
96
+
55
97
pub fn create_binary_commitment (
56
98
binary_path : String ,
57
99
expected_end_params : & [ u32 ; 8 ] ,
@@ -103,12 +145,106 @@ pub fn create_binary_commitment(
103
145
fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
104
146
let cli = Cli :: parse ( ) ;
105
147
148
+ match cli. command {
149
+ Commands :: Prove {
150
+ input,
151
+ input_binary,
152
+ output_dir,
153
+ trusted_setup_file,
154
+ } => {
155
+ println ! ( "=== Phase 0: Proving" ) ;
156
+ prove ( input, input_binary, output_dir, trusted_setup_file) ?;
157
+ }
158
+ Commands :: GenerateVk {
159
+ input_binary,
160
+ output_dir,
161
+ trusted_setup_file,
162
+ universal_verifier,
163
+ } => {
164
+ println ! ( "=== Phase 0: Generating the verification key" ) ;
165
+ generate_vk (
166
+ input_binary,
167
+ output_dir,
168
+ trusted_setup_file,
169
+ universal_verifier,
170
+ ) ?;
171
+ }
172
+ }
173
+ Ok ( ( ) )
174
+ }
175
+
176
+ fn generate_vk (
177
+ input_binary : String ,
178
+ output_dir : String ,
179
+ trusted_setup_file : String ,
180
+ universal_verifier : bool ,
181
+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
182
+ let worker = BellmanWorker :: new_with_cpus ( 4 ) ;
183
+ let boojum_worker = boojum:: worker:: Worker :: new_with_num_threads ( 4 ) ;
184
+
185
+ let trusted_setup_file = Some ( trusted_setup_file) ;
186
+
187
+ let crs_mons = match trusted_setup_file {
188
+ Some ( ref crs_file_str) => get_trusted_setup ( crs_file_str) ,
189
+ None => Crs :: < Bn256 , CrsForMonomialForm > :: crs_42 (
190
+ 1 << L1_VERIFIER_DOMAIN_SIZE_LOG ,
191
+ & BellmanWorker :: new ( ) ,
192
+ ) ,
193
+ } ;
194
+ println ! ( "=== Phase 1: Creating the Risc wrapper key" ) ;
195
+
196
+ let verifier_params = if universal_verifier {
197
+ universal_circuit_no_delegation_verifier_vk ( ) . params
198
+ } else {
199
+ final_recursion_layer_verifier_vk ( ) . params
200
+ } ;
201
+
202
+ let binary_commitment = create_binary_commitment ( input_binary, & verifier_params) ;
203
+
204
+ let ( _, _, _, risc_wrapper_vk, _, _, _) =
205
+ get_risc_wrapper_setup ( & boojum_worker, binary_commitment. clone ( ) ) ;
206
+
207
+ println ! ( "=== Phase 2: Creating the Compression key" ) ;
208
+ let ( _, _, _, compression_vk, _, _, _) =
209
+ get_compression_setup ( risc_wrapper_vk. clone ( ) , & boojum_worker) ;
210
+
211
+ println ! ( "=== Phase 3: Creating the SNARK key" ) ;
212
+
213
+ let ( _, snark_wrapper_vk) = get_snark_wrapper_setup ( compression_vk. clone ( ) , & crs_mons, & worker) ;
214
+
215
+ serialize_to_file (
216
+ & snark_wrapper_vk,
217
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "snark_vk_expected.json" ) ,
218
+ ) ;
219
+
220
+ println ! (
221
+ "VK key hash: {:?}" ,
222
+ calculate_verification_key_hash( snark_wrapper_vk)
223
+ ) ;
224
+
225
+ Ok ( ( ) )
226
+ }
227
+
228
+ fn prove (
229
+ input : String ,
230
+ input_binary : Option < String > ,
231
+ output_dir : String ,
232
+ trusted_setup_file : Option < String > ,
233
+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
234
+ let crs_mons = match trusted_setup_file {
235
+ Some ( ref crs_file_str) => get_trusted_setup ( crs_file_str) ,
236
+ None => Crs :: < Bn256 , CrsForMonomialForm > :: crs_42 (
237
+ 1 << L1_VERIFIER_DOMAIN_SIZE_LOG ,
238
+ & BellmanWorker :: new ( ) ,
239
+ ) ,
240
+ } ;
241
+
106
242
println ! ( "=== Phase 1: Creating the Risc wrapper proof" ) ;
107
243
108
244
let worker = boojum:: worker:: Worker :: new_with_num_threads ( 4 ) ;
109
245
110
- let program_proof: zkos_wrapper:: ProgramProof = deserialize_from_file ( & cli . input ) ;
111
- let binary_commitment = match cli . input_binary {
246
+ let program_proof: zkos_wrapper:: ProgramProof = deserialize_from_file ( & input) ;
247
+ let binary_commitment = match input_binary {
112
248
Some ( binary_path) => create_binary_commitment ( binary_path, & program_proof. end_params ) ,
113
249
None => BinaryCommitment :: from_default_binary ( ) ,
114
250
} ;
@@ -143,7 +279,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
143
279
144
280
serialize_to_file (
145
281
& risc_wrapper_proof,
146
- & Path :: new ( & cli . output_dir . clone ( ) ) . join ( "risc_proof.json" ) ,
282
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "risc_proof.json" ) ,
147
283
) ;
148
284
149
285
println ! ( "=== Phase 2: Creating compression proof" ) ;
@@ -175,17 +311,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
175
311
176
312
serialize_to_file (
177
313
& compression_proof,
178
- & Path :: new ( & cli . output_dir . clone ( ) ) . join ( "compression_proof.json" ) ,
314
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "compression_proof.json" ) ,
179
315
) ;
180
316
181
317
println ! ( "=== Phase 3: Creating SNARK proof" ) ;
182
318
183
319
{
184
320
let worker = BellmanWorker :: new_with_cpus ( 4 ) ;
185
321
186
- let crs_mons =
187
- Crs :: < Bn256 , CrsForMonomialForm > :: crs_42 ( 1 << L1_VERIFIER_DOMAIN_SIZE_LOG , & worker) ;
188
-
189
322
let ( snark_setup, snark_wrapper_vk) =
190
323
get_snark_wrapper_setup ( compression_vk. clone ( ) , & crs_mons, & worker) ;
191
324
@@ -203,11 +336,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
203
336
204
337
serialize_to_file (
205
338
& snark_wrapper_proof,
206
- & Path :: new ( & cli . output_dir . clone ( ) ) . join ( "snark_proof.json" ) ,
339
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "snark_proof.json" ) ,
207
340
) ;
208
341
serialize_to_file (
209
342
& snark_wrapper_vk,
210
- & Path :: new ( & cli . output_dir . clone ( ) ) . join ( "snark_vk.json" ) ,
343
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "snark_vk.json" ) ,
211
344
) ;
212
345
}
213
346
0 commit comments