@@ -11,6 +11,8 @@ pub mod wrapper_utils;
11
11
#[ cfg( test) ]
12
12
mod tests;
13
13
14
+ use std:: alloc:: Global ;
15
+ use std:: path:: Path ;
14
16
use boojum:: algebraic_props:: round_function:: AbsorptionModeOverwrite ;
15
17
use boojum:: algebraic_props:: sponge:: GoldilocksPoseidon2Sponge ;
16
18
use boojum:: config:: { DevCSConfig , ProvingCSConfig , SetupCSConfig } ;
@@ -93,7 +95,7 @@ pub type SnarkWrapperTranscript =
93
95
bellman:: plonk:: commitments:: transcript:: keccak_transcript:: RollingKeccakTranscript < Fr > ;
94
96
95
97
pub use execution_utils:: ProgramProof ;
96
-
98
+ use execution_utils :: { final_recursion_layer_verifier_vk , recursion_layer_no_delegation_verifier_vk , recursion_layer_verifier_vk , universal_circuit_no_delegation_verifier_vk , universal_circuit_verifier_vk } ;
97
99
//CircuitAlgebraicSpongeBasedTranscript<GoldilocksField, 8, 12, 4, R>,
98
100
99
101
// RiscV -> Stark Wrapper
@@ -459,3 +461,191 @@ pub fn calculate_verification_key_hash(verification_key: SnarkWrapperVK) -> H256
459
461
460
462
H256 :: from_slice ( & computed_vk_hash)
461
463
}
464
+
465
+ /// Uploads trusted setup file to the RAM
466
+ pub fn get_trusted_setup ( crs_file_str : & String ) -> Crs < Bn256 , CrsForMonomialForm > {
467
+ let crs_file_path = std:: path:: Path :: new ( crs_file_str) ;
468
+ let crs_file = std:: fs:: File :: open ( & crs_file_path)
469
+ . expect ( format ! ( "Trying to open CRS FILE: {:?}" , crs_file_path) . as_str ( ) ) ;
470
+ Crs :: read ( & crs_file) . expect ( format ! ( "Trying to read CRS FILE: {:?}" , crs_file_path) . as_str ( ) )
471
+ }
472
+
473
+ pub fn serialize_to_file < T : serde:: ser:: Serialize > ( content : & T , filename : & Path ) {
474
+ let src = std:: fs:: File :: create ( filename) . unwrap ( ) ;
475
+ serde_json:: to_writer_pretty ( src, content) . unwrap ( ) ;
476
+ }
477
+
478
+ fn deserialize_from_file < T : serde:: de:: DeserializeOwned > ( filename : & str ) -> T {
479
+ let src = std:: fs:: File :: open ( filename) . unwrap ( ) ;
480
+ serde_json:: from_reader ( src) . unwrap ( )
481
+ }
482
+
483
+ pub fn create_binary_commitment (
484
+ binary_path : String ,
485
+ expected_end_params : & [ u32 ; 8 ] ,
486
+ ) -> BinaryCommitment {
487
+ let bin = std:: fs:: read ( binary_path) . unwrap ( ) ;
488
+
489
+ let worker = risc_verifier:: prover:: worker:: Worker :: new_with_num_threads ( 8 ) ;
490
+
491
+ let expected_final_pc = execution_utils:: find_binary_exit_point ( & bin) ;
492
+ let binary: Vec < u32 > = execution_utils:: get_padded_binary ( & bin) ;
493
+
494
+ let base_params = execution_utils:: compute_end_parameters (
495
+ expected_final_pc,
496
+ & setups:: get_main_riscv_circuit_setup :: < Global , Global > ( & binary, & worker) ,
497
+ ) ;
498
+
499
+ // Check which verifier was used.
500
+ if universal_circuit_no_delegation_verifier_vk ( ) . params == * expected_end_params {
501
+ let layers = vec ! [
502
+ [ 0u32 ; 8 ] ,
503
+ base_params,
504
+ universal_circuit_verifier_vk( ) . params,
505
+ universal_circuit_no_delegation_verifier_vk( ) . params,
506
+ ] ;
507
+ BinaryCommitment {
508
+ end_params : universal_circuit_no_delegation_verifier_vk ( ) . params ,
509
+ aux_params : execution_utils:: compute_chain_encoding ( layers) ,
510
+ }
511
+ } else if final_recursion_layer_verifier_vk ( ) . params == * expected_end_params {
512
+ let layers = vec ! [
513
+ [ 0u32 ; 8 ] ,
514
+ base_params,
515
+ recursion_layer_verifier_vk( ) . params,
516
+ recursion_layer_no_delegation_verifier_vk( ) . params,
517
+ final_recursion_layer_verifier_vk( ) . params,
518
+ ] ;
519
+ BinaryCommitment {
520
+ end_params : final_recursion_layer_verifier_vk ( ) . params ,
521
+ aux_params : execution_utils:: compute_chain_encoding ( layers) ,
522
+ }
523
+ } else {
524
+ panic ! (
525
+ "Cannot find a verifier for the proof end parameters: {:?}" ,
526
+ expected_end_params
527
+ ) ;
528
+ }
529
+ }
530
+
531
+ pub fn prove (
532
+ input : String ,
533
+ input_binary : Option < String > ,
534
+ output_dir : String ,
535
+ trusted_setup_file : Option < String > ,
536
+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
537
+ let crs_mons = match trusted_setup_file {
538
+ Some ( ref crs_file_str) => get_trusted_setup ( crs_file_str) ,
539
+ None => Crs :: < Bn256 , CrsForMonomialForm > :: crs_42 (
540
+ 1 << L1_VERIFIER_DOMAIN_SIZE_LOG ,
541
+ & BellmanWorker :: new ( ) ,
542
+ ) ,
543
+ } ;
544
+
545
+ println ! ( "=== Phase 1: Creating the Risc wrapper proof" ) ;
546
+
547
+ let worker = boojum:: worker:: Worker :: new_with_num_threads ( 4 ) ;
548
+
549
+ let program_proof: crate :: ProgramProof = deserialize_from_file ( & input) ;
550
+ let binary_commitment = match input_binary {
551
+ Some ( binary_path) => create_binary_commitment ( binary_path, & program_proof. end_params ) ,
552
+ None => BinaryCommitment :: from_default_binary ( ) ,
553
+ } ;
554
+ let risc_wrapper_witness =
555
+ RiscWrapperWitness :: from_full_proof ( program_proof, & binary_commitment) ;
556
+
557
+ let (
558
+ finalization_hint,
559
+ setup_base,
560
+ setup,
561
+ risc_wrapper_vk,
562
+ setup_tree,
563
+ vars_hint,
564
+ witness_hints,
565
+ ) = get_risc_wrapper_setup ( & worker, binary_commitment. clone ( ) ) ;
566
+
567
+ let risc_wrapper_proof = prove_risc_wrapper (
568
+ risc_wrapper_witness,
569
+ & finalization_hint,
570
+ & setup_base,
571
+ & setup,
572
+ & risc_wrapper_vk,
573
+ & setup_tree,
574
+ & vars_hint,
575
+ & witness_hints,
576
+ & worker,
577
+ binary_commitment,
578
+ ) ;
579
+ let is_valid = verify_risc_wrapper_proof ( & risc_wrapper_proof, & risc_wrapper_vk) ;
580
+
581
+ assert ! ( is_valid) ;
582
+
583
+ serialize_to_file (
584
+ & risc_wrapper_proof,
585
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "risc_proof.json" ) ,
586
+ ) ;
587
+
588
+ println ! ( "=== Phase 2: Creating compression proof" ) ;
589
+
590
+ let (
591
+ finalization_hint,
592
+ setup_base,
593
+ setup,
594
+ compression_vk,
595
+ setup_tree,
596
+ vars_hint,
597
+ witness_hints,
598
+ ) = get_compression_setup ( risc_wrapper_vk. clone ( ) , & worker) ;
599
+ let compression_proof = prove_compression (
600
+ risc_wrapper_proof,
601
+ risc_wrapper_vk,
602
+ & finalization_hint,
603
+ & setup_base,
604
+ & setup,
605
+ & compression_vk,
606
+ & setup_tree,
607
+ & vars_hint,
608
+ & witness_hints,
609
+ & worker,
610
+ ) ;
611
+ let is_valid = verify_compression_proof ( & compression_proof, & compression_vk) ;
612
+
613
+ assert ! ( is_valid) ;
614
+
615
+ serialize_to_file (
616
+ & compression_proof,
617
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "compression_proof.json" ) ,
618
+ ) ;
619
+
620
+ println ! ( "=== Phase 3: Creating SNARK proof" ) ;
621
+
622
+ {
623
+ let worker = BellmanWorker :: new_with_cpus ( 4 ) ;
624
+
625
+ let ( snark_setup, snark_wrapper_vk) =
626
+ get_snark_wrapper_setup ( compression_vk. clone ( ) , & crs_mons, & worker) ;
627
+
628
+ let snark_wrapper_proof = prove_snark_wrapper (
629
+ compression_proof,
630
+ compression_vk,
631
+ & snark_setup,
632
+ & crs_mons,
633
+ & worker,
634
+ ) ;
635
+
636
+ let is_valid = verify_snark_wrapper_proof ( & snark_wrapper_proof, & snark_wrapper_vk) ;
637
+
638
+ assert ! ( is_valid) ;
639
+
640
+ serialize_to_file (
641
+ & snark_wrapper_proof,
642
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "snark_proof.json" ) ,
643
+ ) ;
644
+ serialize_to_file (
645
+ & snark_wrapper_vk,
646
+ & Path :: new ( & output_dir. clone ( ) ) . join ( "snark_vk.json" ) ,
647
+ ) ;
648
+ }
649
+
650
+ Ok ( ( ) )
651
+ }
0 commit comments