@@ -38,41 +38,45 @@ fn main() -> Result<(), ProverError> {
3838 let compress = config:: baby_bear_compression ( ) ;
3939 let mmcs_config = MmcsVerifyConfig :: babybear_quartic_extension_default ( ) ;
4040
41- let mut builder = CircuitBuilder :: new ( ) ;
41+ let mut builder = CircuitBuilder :: < F > :: new ( ) ;
4242 builder. enable_mmcs ( & mmcs_config) ;
4343
4444 // Public inputs: leaf hash and expected root hash
45- let leaf_hash = ( 0 ..mmcs_config. ext_field_digest_elems )
46- . map ( |_| builder. alloc_public_input ( "leaf_hash" ) )
47- . collect :: < Vec < ExprId > > ( ) ;
48- let index = builder. alloc_public_input ( "index" ) ;
45+ // The leaves will contain `mmcs_config.ext_field_digest_elems` wires,
46+ // when the leaf index is odd, and an empty vector otherwise. This means
47+ // we're proving the opening of an Mmcs to matrices of height 2^depth, 2^(depth -1), ...
48+ let leaves: Vec < Vec < ExprId > > = ( 0 ..depth)
49+ . map ( |i| {
50+ ( 0 ..if i % 2 == 0 && i != depth - 1 {
51+ mmcs_config. ext_field_digest_elems
52+ } else {
53+ 0
54+ } )
55+ . map ( |_| builder. alloc_public_input ( "leaf_hash" ) )
56+ . collect :: < Vec < ExprId > > ( )
57+ } )
58+ . collect ( ) ;
59+ let directions: Vec < ExprId > = ( 0 ..depth)
60+ . map ( |_| builder. alloc_public_input ( "directions" ) )
61+ . collect ( ) ;
4962 let expected_root = ( 0 ..mmcs_config. ext_field_digest_elems )
5063 . map ( |_| builder. alloc_public_input ( "expected_root" ) )
5164 . collect :: < Vec < ExprId > > ( ) ;
5265 // Add a Mmcs verification operation
5366 // This declares that leaf_hash and expected_root are connected to witness bus
5467 // The AIR constraints will verify the Mmcs path is valid
55- let mmcs_op_id = builder. add_mmcs_verify ( & leaf_hash , & index , & expected_root) ?;
68+ let mmcs_op_id = builder. add_mmcs_verify ( & leaves , & directions , & expected_root) ?;
5669
5770 builder. dump_allocation_log ( ) ;
5871
5972 let circuit = builder. build ( ) ?;
6073 let mut runner = circuit. runner ( ) ;
6174
6275 // Set public inputs
63- let leaf_value = [
64- F :: ZERO ,
65- F :: ZERO ,
66- F :: ZERO ,
67- F :: ZERO ,
68- F :: ZERO ,
69- F :: ZERO ,
70- F :: ZERO ,
71- F :: from_u64 ( 42 ) ,
72- ] ; // Our leaf value
73- let siblings: Vec < ( Vec < F > , Option < Vec < F > > ) > = ( 0 ..depth)
76+ //
77+ let leaves_value: Vec < Vec < F > > = ( 0 ..depth)
7478 . map ( |i| {
75- (
79+ if i % 2 == 0 && i != depth - 1 {
7680 vec ! [
7781 F :: ZERO ,
7882 F :: ZERO ,
@@ -81,47 +85,50 @@ fn main() -> Result<(), ProverError> {
8185 F :: ZERO ,
8286 F :: ZERO ,
8387 F :: ZERO ,
84- F :: from_u64( ( i + 1 ) * 10 ) ,
85- ] ,
86- // Extra siblings on odd levels, but never on the last level
87- if i % 2 == 0 || i == depth - 1 {
88- None
89- } else {
90- Some ( vec ! [
91- F :: ZERO ,
92- F :: ZERO ,
93- F :: ZERO ,
94- F :: ZERO ,
95- F :: ZERO ,
96- F :: ZERO ,
97- F :: ZERO ,
98- F :: from_u64( i + 1 ) ,
99- ] )
100- } ,
101- )
88+ F :: from_u64( 42 ) ,
89+ ]
90+ } else {
91+ vec ! [ ]
92+ }
10293 } )
103- . collect ( ) ; // The siblings, containing extra siblings every other level (except the last)
104- let directions: Vec < bool > = ( 0 ..depth) . map ( |i| i % 2 == 0 ) . collect ( ) ;
94+ . collect ( ) ; // Our leaf value
95+ let siblings: Vec < Vec < F > > = ( 0 ..depth)
96+ . map ( |i| {
97+ vec ! [
98+ F :: ZERO ,
99+ F :: ZERO ,
100+ F :: ZERO ,
101+ F :: ZERO ,
102+ F :: ZERO ,
103+ F :: ZERO ,
104+ F :: ZERO ,
105+ F :: from_u64( ( i + 1 ) * 10 ) ,
106+ ]
107+ } )
108+ . collect ( ) ;
109+
105110 // the index is 0b1010...
106- let index_value = F :: from_u64 (
107- ( 0 ..32 )
108- . zip ( directions. iter ( ) )
109- . filter ( |( _, dir) | * * dir)
110- . map ( |( i, _) | 1 << i)
111- . sum ( ) ,
112- ) ;
111+ let directions: Vec < bool > = ( 0 ..depth) . map ( |i| i % 2 == 0 ) . collect ( ) ;
112+
113113 let MmcsPrivateData {
114114 path_states : intermediate_states,
115115 ..
116- } = MmcsPrivateData :: new ( & compress, & mmcs_config, & leaf_value, & siblings, & directions) ?;
116+ } = MmcsPrivateData :: new (
117+ & compress,
118+ & mmcs_config,
119+ & leaves_value,
120+ & siblings,
121+ & directions,
122+ ) ?;
117123 let expected_root_value = intermediate_states
118124 . last ( )
119125 . expect ( "There is always at least the leaf hash" )
126+ . 0
120127 . clone ( ) ;
121128
122129 let mut public_inputs = vec ! [ ] ;
123- public_inputs. extend ( leaf_value ) ;
124- public_inputs. push ( index_value ) ;
130+ public_inputs. extend ( leaves_value . iter ( ) . flatten ( ) ) ;
131+ public_inputs. extend ( directions . iter ( ) . map ( |dir| F :: from_bool ( * dir ) ) ) ;
125132 public_inputs. extend ( & expected_root_value) ;
126133
127134 runner. set_public_inputs ( & public_inputs) ?;
@@ -131,12 +138,11 @@ fn main() -> Result<(), ProverError> {
131138 NonPrimitiveOpPrivateData :: MmcsVerify ( MmcsPrivateData :: new (
132139 & compress,
133140 & mmcs_config,
134- & leaf_value ,
141+ & leaves_value ,
135142 & siblings,
136143 & directions,
137144 ) ?) ,
138145 ) ?;
139-
140146 let traces = runner. run ( ) ?;
141147 let multi_prover = MultiTableProver :: new ( config) . with_mmcs_table ( mmcs_config. into ( ) ) ;
142148 let proof = multi_prover. prove_all_tables ( & traces) ?;
0 commit comments