@@ -207,13 +207,7 @@ pub trait MmcsOps<F> {
207207 root_expr : & [ ExprId ] ,
208208 ) -> Result < NonPrimitiveOpId , CircuitBuilderError > ;
209209
210- /// Allocate root outputs as witness hints and add MMCS verify that will set-or-verify them.
211- fn add_mmcs_verify_allocating_root (
212- & mut self ,
213- leaf_expr : & [ ExprId ] ,
214- index_expr : & ExprId ,
215- root_len : usize ,
216- ) -> Result < ( NonPrimitiveOpId , Vec < ExprId > ) , CircuitBuilderError > ;
210+ // Deprecated: MMCS is an assert op and does not write outputs.
217211}
218212
219213impl < F > MmcsOps < F > for CircuitBuilder < F >
@@ -237,27 +231,7 @@ where
237231 Ok ( self . push_non_primitive_op ( NonPrimitiveOpType :: MmcsVerify , inputs, "mmcs_verify" ) )
238232 }
239233
240- fn add_mmcs_verify_allocating_root (
241- & mut self ,
242- leaf_expr : & [ ExprId ] ,
243- index_expr : & ExprId ,
244- root_len : usize ,
245- ) -> Result < ( NonPrimitiveOpId , Vec < ExprId > ) , CircuitBuilderError > {
246- self . ensure_op_enabled ( NonPrimitiveOpType :: MmcsVerify ) ?;
247-
248- let root_expr: Vec < ExprId > = self . alloc_witness_hints ( root_len, "mmcs_root" ) ;
249-
250- // Push op with inputs including root exprs (they are outputs conceptually, but part of op spec)
251- let mut inputs = vec ! [ ] ;
252- inputs. extend ( leaf_expr) ;
253- inputs. push ( * index_expr) ;
254- inputs. extend ( & root_expr) ;
255-
256- let op_id =
257- self . push_non_primitive_op ( NonPrimitiveOpType :: MmcsVerify , inputs, "mmcs_verify" ) ;
258-
259- Ok ( ( op_id, root_expr) )
260- }
234+ // Deprecated: MMCS is an assert op and does not write outputs.
261235}
262236
263237/// Executor for MMCS verification operations
@@ -288,7 +262,7 @@ impl<F: Field> NonPrimitiveExecutor<F> for MmcsVerifyExecutor {
288262 fn execute (
289263 & self ,
290264 inputs : & [ WitnessId ] ,
291- outputs : & [ WitnessId ] ,
265+ _outputs : & [ WitnessId ] ,
292266 ctx : & mut ExecutionContext < F > ,
293267 ) -> Result < ( ) , CircuitError > {
294268 // Get the configuration
@@ -304,30 +278,21 @@ impl<F: Field> NonPrimitiveExecutor<F> for MmcsVerifyExecutor {
304278 // Get private data
305279 let NonPrimitiveOpPrivateData :: MmcsVerify ( private_data) = ctx. get_private_data ( ) ?;
306280
307- // Validate input size matches configuration
308- let expected_input_size = config. input_size ( ) ;
309- if inputs. len ( ) != expected_input_size {
281+ // Validate input size: leaf(ext) + index(1) + root(ext)
282+ let ext_digest_elems = config. ext_field_digest_elems ;
283+ let min_inputs = ext_digest_elems + 1 + ext_digest_elems;
284+ if inputs. len ( ) < min_inputs {
310285 return Err ( CircuitError :: IncorrectNonPrimitiveOpPrivateDataSize {
311286 op : self . op_type . clone ( ) ,
312- expected : expected_input_size ,
287+ expected : min_inputs ,
313288 got : inputs. len ( ) ,
314289 } ) ;
315290 }
316291
317- // Extract leaf, index from inputs; root from outputs
318- let ext_digest_elems = config. ext_field_digest_elems ;
292+ // Extract leaf, index, and root from inputs
319293 let leaf_wids = & inputs[ ..ext_digest_elems] ;
320294 let index_wid = inputs[ ext_digest_elems] ;
321-
322- // Root comes from outputs (the value we're verifying against)
323- if outputs. len ( ) < ext_digest_elems {
324- return Err ( CircuitError :: IncorrectNonPrimitiveOpPrivateDataSize {
325- op : self . op_type . clone ( ) ,
326- expected : ext_digest_elems,
327- got : outputs. len ( ) ,
328- } ) ;
329- }
330- let root_wids = & outputs[ ..ext_digest_elems] ;
295+ let root_wids = & inputs[ ext_digest_elems + 1 ..ext_digest_elems + 1 + ext_digest_elems] ;
331296
332297 // Validate leaf values match private data
333298 let witness_leaf: Vec < F > = leaf_wids
@@ -365,7 +330,7 @@ impl<F: Field> NonPrimitiveExecutor<F> for MmcsVerifyExecutor {
365330 } ) ;
366331 }
367332
368- // Set-or-verify for roots: if unset, set; if set, verify equality.
333+ // Verify roots match exactly (assert op; do not write)
369334 let private_data_root = private_data
370335 . path_states
371336 . last ( )
@@ -384,20 +349,14 @@ impl<F: Field> NonPrimitiveExecutor<F> for MmcsVerifyExecutor {
384349 }
385350
386351 for ( i, & wid) in root_wids. iter ( ) . enumerate ( ) {
387- match ctx. get_witness ( wid) {
388- Ok ( existing) => {
389- if existing != private_data_root[ i] {
390- return Err ( CircuitError :: IncorrectNonPrimitiveOpPrivateData {
391- op : self . op_type . clone ( ) ,
392- operation_index : ctx. operation_id ( ) ,
393- expected : alloc:: format!( "root: {private_data_root:?}" ) ,
394- got : alloc:: format!( "root: existing witness value at {wid:?}" ) ,
395- } ) ;
396- }
397- }
398- Err ( _) => {
399- ctx. set_witness ( wid, private_data_root[ i] ) ?;
400- }
352+ let existing = ctx. get_witness ( wid) ?;
353+ if existing != private_data_root[ i] {
354+ return Err ( CircuitError :: IncorrectNonPrimitiveOpPrivateData {
355+ op : self . op_type . clone ( ) ,
356+ operation_index : ctx. operation_id ( ) ,
357+ expected : alloc:: format!( "root: {:?}" , private_data_root) ,
358+ got : alloc:: format!( "root witness at {:?}" , wid) ,
359+ } ) ;
401360 }
402361 }
403362
0 commit comments