@@ -440,15 +440,19 @@ pub(crate) fn compute_commit_bus_offset(
440440 let bus_id = FieldElement :: < E > :: from ( BusId :: Commit as u64 ) ;
441441 let alpha_sq = alpha * alpha;
442442
443- let mut total = FieldElement :: < E > :: zero ( ) ;
444- for ( i, & value) in public_output. iter ( ) . enumerate ( ) {
445- let linear_combination = bus_id
446- + ( FieldElement :: < E > :: from ( i as u64 ) * alpha)
447- + ( FieldElement :: < E > :: from ( value as u64 ) * alpha_sq) ;
448- let fingerprint = z - linear_combination;
449- total += fingerprint. inv ( ) . ok ( ) ?;
450- }
451- Some ( total)
443+ let mut fingerprints: Vec < FieldElement < E > > = public_output
444+ . iter ( )
445+ . enumerate ( )
446+ . map ( |( i, & value) | {
447+ let lc = & bus_id
448+ + & ( FieldElement :: < E > :: from ( i as u64 ) * alpha)
449+ + & ( FieldElement :: < E > :: from ( value as u64 ) * & alpha_sq) ;
450+ z - & lc
451+ } )
452+ . collect ( ) ;
453+
454+ FieldElement :: inplace_batch_inverse ( & mut fingerprints) . ok ( ) ?;
455+ Some ( fingerprints. iter ( ) . fold ( FieldElement :: zero ( ) , |acc, inv| acc + inv) )
452456}
453457
454458/// Compute the bus balance offset for the REGISTER table on the Memory bus.
@@ -497,42 +501,49 @@ pub(crate) fn compute_register_bus_offset(
497501 let ts_hi = FieldElement :: < E > :: from ( 0xFFFF_FFFFu64 ) ;
498502 let fini_ts_contrib = & ( & ts_lo * & alpha4) + & ( & ts_hi * & alpha5) ;
499503
500- let mut total = FieldElement :: < E > :: zero ( ) ;
501-
502504 let addr_list = register:: register_word_address_list ( ) ;
505+ let n = addr_list. len ( ) ;
506+
507+ // Build all 2*n fingerprints (init + fini per address), then batch-invert.
508+ // signs[i] = -1 for init (receiver), +1 for fini (sender).
509+ let mut fingerprints: Vec < FieldElement < E > > = Vec :: with_capacity ( 2 * n) ;
510+ let mut signs: Vec < i8 > = Vec :: with_capacity ( 2 * n) ;
503511
504512 for & addr in & addr_list {
505- let addr_fe = FieldElement :: < E > :: from ( addr) ;
506- let addr_contrib = & addr_fe * & alpha2;
513+ let addr_contrib = FieldElement :: < E > :: from ( addr) * & alpha2;
507514
508- // Init value: deterministic from entry_point
509515 let init_value = register:: init_value_for_address ( addr, entry_point) ;
510-
511- // Fini value: deterministic after HALT finalization
512- // HALT writes 0 to all registers except x255 which gets value=1.
513- // x255 lo word (addr 510) → fini=1, x255 hi word (addr 511) → fini=0.
514516 let fini_value: u32 = if addr == 510 { 1 } else { 0 } ;
515517
516- // REG-C1 (receiver, sign=-1): init token with ts=0
517- // lc = base_lc + addr * α^2 + 0*α^3 + 0*α^4 + 0*α^5 + init_value * α^6
518+ // REG-C1 (receiver): init token with ts=0
518519 let lc_init = & base_lc
519520 + & addr_contrib
520521 + & ( FieldElement :: < E > :: from ( init_value as u64 ) * & alpha6) ;
521- let fp_init = z - & lc_init;
522- let inv_init = fp_init. inv ( ) . ok ( ) ?;
523- total = total - inv_init; // receiver: -1/fp
522+ fingerprints. push ( z - & lc_init) ;
523+ signs. push ( -1 ) ;
524524
525- // REG-C2 (sender, sign=+1): fini token with ts=MAX
526- // lc = base_lc + addr * α^2 + 0*α^3 + MAX_LO*α^4 + MAX_HI*α^5 + fini_value * α^6
525+ // REG-C2 (sender): fini token with ts=MAX
527526 let lc_fini = & base_lc
528527 + & addr_contrib
529528 + & fini_ts_contrib
530529 + & ( FieldElement :: < E > :: from ( fini_value as u64 ) * & alpha6) ;
531- let fp_fini = z - & lc_fini;
532- let inv_fini = fp_fini. inv ( ) . ok ( ) ?;
533- total = total + inv_fini; // sender: +1/fp
530+ fingerprints. push ( z - & lc_fini) ;
531+ signs. push ( 1 ) ;
534532 }
535533
534+ FieldElement :: inplace_batch_inverse ( & mut fingerprints) . ok ( ) ?;
535+
536+ let total = fingerprints
537+ . iter ( )
538+ . zip ( signs. iter ( ) )
539+ . fold ( FieldElement :: < E > :: zero ( ) , |acc, ( inv, & sign) | {
540+ if sign > 0 {
541+ acc + inv
542+ } else {
543+ acc - inv
544+ }
545+ } ) ;
546+
536547 Some ( total)
537548}
538549
0 commit comments