Skip to content

Commit 6004a64

Browse files
committed
perf: use batch inversion for verifier bus offset computation
1 parent e8d728f commit 6004a64

1 file changed

Lines changed: 39 additions & 28 deletions

File tree

prover/src/lib.rs

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)