@@ -19,11 +19,11 @@ extern crate criterion;
1919use snarkvm_algorithms:: snark:: varuna:: VarunaVersion ;
2020use snarkvm_circuit:: { AleoV0 , Eject , Environment , Inject , Mode , collections:: kary_merkle_tree:: * } ;
2121use snarkvm_console:: {
22- algorithms:: Sha3_256 ,
22+ algorithms:: Poseidon8 ,
2323 collections:: kary_merkle_tree:: KaryMerkleTree ,
2424 network:: {
2525 MainnetV0 ,
26- prelude:: { TestRng , ToBits , Uniform } ,
26+ prelude:: { Rng , TestRng , Uniform } ,
2727 } ,
2828 types:: Field ,
2929} ;
@@ -34,78 +34,119 @@ use criterion::Criterion;
3434type CurrentNetwork = MainnetV0 ;
3535type CurrentAleo = AleoV0 ;
3636
37- type NativePathHasher = Sha3_256 ;
38- type NativeLeafHasher = Sha3_256 ;
39- type CircuitPathHasher = snarkvm_circuit:: Sha3_256 < AleoV0 > ;
40- type CircuitLeafHasher = snarkvm_circuit:: Sha3_256 < AleoV0 > ;
37+ type NativePathHasher = Poseidon8 < CurrentNetwork > ;
38+ type NativeLeafHasher = Poseidon8 < CurrentNetwork > ;
39+ type CircuitPathHasher = snarkvm_circuit:: Poseidon8 < AleoV0 > ;
40+ type CircuitLeafHasher = snarkvm_circuit:: Poseidon8 < AleoV0 > ;
4141
42- const DEPTH : u8 = 8 ;
42+ const DEPTH : u8 = 7 ;
4343const ARITY : u8 = 8 ;
4444
4545/// Generates the specified number of random Merkle tree leaves.
4646macro_rules! generate_leaves {
47- ( $num_leaves: expr, $rng: expr) => { { ( 0 ..$num_leaves) . map( |_| Field :: <MainnetV0 >:: rand( $rng) . to_bits_le( ) ) . collect:: <Vec <_>>( ) } } ;
47+ ( "bits" , $num_leaves: expr, $rng: expr) => { {
48+ use snarkvm_console:: network:: prelude:: ToBits ;
49+ // Generate leaf bits.
50+ ( 0 ..$num_leaves) . map( |_| Field :: <CurrentNetwork >:: rand( $rng) . to_bits_le( ) ) . collect:: <Vec <_>>( )
51+ } } ;
52+ ( "fields" , $num_leaves: expr, $rng: expr) => { {
53+ use rand:: SeedableRng ;
54+ use rayon:: prelude:: * ;
55+ // Generate leaf fields in parallel.
56+ ( 0 ..$num_leaves)
57+ . map( |_| u64 :: rand( $rng) )
58+ . collect:: <Vec <u64 >>( )
59+ . into_par_iter( )
60+ . map( |seed| vec![ Field :: <CurrentNetwork >:: rand( & mut rand:: rngs:: StdRng :: seed_from_u64( seed) ) ] )
61+ . collect:: <Vec <_>>( )
62+ } } ;
4863}
4964
5065fn batch_prove ( c : & mut Criterion ) {
5166 let mut rng = TestRng :: default ( ) ;
5267
68+ // Start the timer.
69+ let timer = std:: time:: Instant :: now ( ) ;
70+
5371 // Initialize the hashers.
54- let native_path_hasher = NativePathHasher :: default ( ) ;
55- let native_leaf_hasher = NativeLeafHasher :: default ( ) ;
56- let circuit_path_hasher = CircuitPathHasher :: new ( ) ;
57- let circuit_leaf_hasher = CircuitLeafHasher :: new ( ) ;
72+ let native_path_hasher = NativePathHasher :: setup ( "test" ) . unwrap ( ) ;
73+ let native_leaf_hasher = NativeLeafHasher :: setup ( "test" ) . unwrap ( ) ;
74+ let circuit_path_hasher = CircuitPathHasher :: new ( Mode :: Private , native_path_hasher . clone ( ) ) ;
75+ let circuit_leaf_hasher = CircuitLeafHasher :: new ( Mode :: Private , native_leaf_hasher . clone ( ) ) ;
5876
5977 // Determine the maximum number of leaves.
60- let max_num_leaves = ( ARITY as u32 ) . pow ( DEPTH as u32 ) ;
78+ let max_num_leaves = ( ARITY as u64 ) . pow ( DEPTH as u32 ) ;
6179 // Initialize the leaves.
62- let leaves = generate_leaves ! ( max_num_leaves, & mut rng) ;
63-
80+ let leaves = generate_leaves ! ( "fields" , max_num_leaves, & mut rng) ;
6481 // Initialize the tree.
6582 let merkle_tree =
6683 KaryMerkleTree :: < _ , _ , DEPTH , ARITY > :: new ( & native_leaf_hasher, & native_path_hasher, & leaves) . unwrap ( ) ;
67- // Initialize the leaf.
68- let merkle_leaf = leaves[ 0 ] . clone ( ) ;
69- // Initialize the Merkle path.
70- let merkle_path = merkle_tree. prove ( 0 , & merkle_leaf) . unwrap ( ) ;
7184
72- // Start the timer.
85+ // Log the current time elapsed.
86+ println ! ( " • Synthesized the Merkle tree in: {} secs" , timer. elapsed( ) . as_secs( ) ) ;
7387 let timer = std:: time:: Instant :: now ( ) ;
7488
75- // Construct the circuit.
76- CurrentAleo :: reset ( ) ;
89+ // Construct the assignment closure.
90+ let generate_assignment = |rng : & mut TestRng | {
91+ // Construct the circuit.
92+ CurrentAleo :: reset ( ) ;
93+
94+ // Select the leaf index to prove.
95+ let leaf_index = rng. gen_range ( 0 ..max_num_leaves as usize ) ;
96+ // Initialize the leaf.
97+ let merkle_leaf = leaves[ leaf_index] . clone ( ) ;
98+ // Initialize the Merkle path.
99+ let merkle_path = merkle_tree. prove ( leaf_index, & merkle_leaf) . unwrap ( ) ;
77100
78- // Initialize the Merkle path circuit.
79- let path = KaryMerklePath :: < CurrentAleo , snarkvm_circuit:: Sha3_256 < CurrentAleo > , DEPTH , ARITY > :: new (
80- Mode :: Private ,
81- merkle_path,
82- ) ;
83- // Initialize the Merkle root.
84- let root = <CircuitPathHasher as PathHash < CurrentAleo > >:: Hash :: new ( Mode :: Private , * merkle_tree. root ( ) ) ;
85- // Initialize the Merkle leaf.
86- let leaf: Vec < _ > = Inject :: new ( Mode :: Private , merkle_leaf) ;
101+ // Uncomment me to enable logging.
102+ // println!("\t• Proving leaf index: {leaf_index}");
87103
88- // Verify the merkle path.
89- let candidate = path. verify ( & circuit_leaf_hasher, & circuit_path_hasher, & root, & leaf) ;
90- assert ! ( candidate. eject_value( ) ) ;
104+ // Initialize the Merkle path circuit.
105+ let path = KaryMerklePath :: < CurrentAleo , CircuitPathHasher , DEPTH , ARITY > :: new ( Mode :: Private , merkle_path) ;
106+ // Initialize the Merkle leaf circuit.
107+ let leaf: Vec < _ > = Inject :: new ( Mode :: Private , merkle_leaf) ;
108+ // Initialize the Merkle root circuit.
109+ let root = <CircuitPathHasher as PathHash < CurrentAleo > >:: Hash :: new ( Mode :: Private , * merkle_tree. root ( ) ) ;
91110
92- // Construct the assignment.
93- let assignment = CurrentAleo :: eject_assignment_and_reset ( ) ;
111+ // Verify the Merkle path circuit.
112+ let candidate = path. verify ( & circuit_leaf_hasher, & circuit_path_hasher, & root, & leaf) ;
113+ assert ! ( candidate. eject_value( ) ) ;
94114
115+ // Eject the assignment.
116+ CurrentAleo :: eject_assignment_and_reset ( )
117+ } ;
118+
119+ // Synthesize a single assignment.
120+ let assignment = generate_assignment ( & mut rng) ;
121+
122+ // Log the current time elapsed.
95123 println ! ( " • Synthesized the circuit in: {} ms" , timer. elapsed( ) . as_millis( ) ) ;
124+ let timer = std:: time:: Instant :: now ( ) ;
96125
97126 // Load the universal srs.
98127 let universal_srs = UniversalSRS :: < CurrentNetwork > :: load ( ) . unwrap ( ) ;
99128 // Construct the proving key.
100129 let ( proving_key, _) = universal_srs. to_circuit_key ( "KaryMerklePathVerification" , & assignment) . unwrap ( ) ;
101130
131+ // Log the current time elapsed.
132+ println ! ( " • Generated the proving key in: {} ms" , timer. elapsed( ) . as_millis( ) ) ;
133+ println ! ( "\t • Number of public & private variables: {:?}" , ( assignment. num_public( ) , assignment. num_private( ) ) ) ;
134+ println ! ( "\t • Number of constraints: {}" , assignment. num_constraints( ) ) ;
135+ println ! ( "\t • Number of nonzeros: {:?}" , assignment. num_nonzeros( ) ) ;
136+
102137 // Bench the proof construction.
103- for num_assignments in & [ 1 , 2 , 4 , 8 ] {
138+ for num_assignments in & [ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 ] {
139+ // Reset the timer.
140+ let timer = std:: time:: Instant :: now ( ) ;
141+
104142 // Construct the assignments.
105143 let assignments =
106- [ ( proving_key. clone ( ) , ( 0 ..* num_assignments) . map ( |_| assignment. clone ( ) ) . collect :: < Vec < _ > > ( ) ) ] ;
144+ [ ( proving_key. clone ( ) , ( 0 ..* num_assignments) . map ( |_| generate_assignment ( & mut rng) ) . collect :: < Vec < _ > > ( ) ) ] ;
145+
146+ // Log the current time elapsed.
147+ println ! ( " • Generated {num_assignments} assignments in: {} ms" , timer. elapsed( ) . as_millis( ) ) ;
107148
108- let varuna_version = VarunaVersion :: V1 ;
149+ let varuna_version = VarunaVersion :: V2 ;
109150 c. bench_function ( & format ! ( "KaryMerkleTree batch prove {num_assignments} assignments" ) , |b| {
110151 b. iter ( || {
111152 let _proof =
0 commit comments