From e343ab04afc593774bc1b1426e503147dbe68261 Mon Sep 17 00:00:00 2001 From: Sai Deng Date: Wed, 4 Feb 2026 16:11:15 -0800 Subject: [PATCH] fix: correct bugs in example circuits Fixes several bugs found in example circuits: - and.rs: Fix critical namespace collision where inner loop variable shadowed outer loop variable - and.rs: Fix typo little indian -> little endian - hashchain.rs: Fix incorrect cargo command in documentation - hashchain.rs: Clarify comment about num_elts_per_step - minroot.rs: Add robustness check for empty sequence - minroot.rs: Simplify z_out assignment logic - minroot.rs: Clarify mathematical notation in comment --- examples/and.rs | 10 +++++----- examples/hashchain.rs | 4 ++-- examples/minroot.rs | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/and.rs b/examples/and.rs index 56c89aae..5fce6a54 100644 --- a/examples/and.rs +++ b/examples/and.rs @@ -85,7 +85,7 @@ pub fn u64_into_bit_vec_le>( Ok(bits) } -/// Gets as input the little indian representation of a number and spits out the number +/// Gets as input the little endian representation of a number and spits out the number pub fn le_bits_to_num( mut cs: CS, bits: &[AllocatedBit], @@ -167,11 +167,11 @@ impl StepCircuit for AndCircuit { let mut c_bits = Vec::new(); // perform bitwise AND - for i in 0..64 { + for bit_idx in 0..64 { let c_bit = AllocatedBit::and( - cs.namespace(|| format!("and_bit_{i}")), - &a_bits[i], - &b_bits[i], + cs.namespace(|| format!("and_bit_{}_{}", i, bit_idx)), + &a_bits[bit_idx], + &b_bits[bit_idx], )?; c_bits.push(c_bit); } diff --git a/examples/hashchain.rs b/examples/hashchain.rs index 8ab26bc0..1435fb29 100644 --- a/examples/hashchain.rs +++ b/examples/hashchain.rs @@ -95,7 +95,7 @@ impl StepCircuit for HashChainCircuit { } } -/// cargo run --release --example and +/// cargo run --release --example hashchain fn main() { println!("========================================================="); println!("Nova-based hashchain example"); @@ -103,7 +103,7 @@ fn main() { let num_steps = 10; for num_elts_per_step in [1024, 2048, 4096] { - // number of instances of AND per Nova's recursive step + // number of field elements per hash chain node let circuit = HashChainCircuit::new(num_elts_per_step); // produce public parameters diff --git a/examples/minroot.rs b/examples/minroot.rs index d6e2226f..08b15cfb 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -30,7 +30,8 @@ struct MinRootIteration { impl MinRootIteration { // produces a sample non-deterministic advice, executing one invocation of MinRoot per step fn new(num_iters: usize, x_0: &G::Scalar, y_0: &G::Scalar) -> (Vec, Vec) { - // exp = (p - 3 / 5), where p is the order of the group + // exp = (p - 3) * 5^(-1) mod p, where p is the order of the group + // This computes the exponent such that x^exp ≡ x^(1/5) (mod p) // x^{exp} mod p provides the fifth root of x let exp = { let p = G::group_params().2.to_biguint().unwrap(); @@ -89,8 +90,10 @@ impl StepCircuit for MinRootCircuit { cs: &mut CS, z: &[AllocatedNum], ) -> Result>, SynthesisError> { - let mut z_out: Result>, SynthesisError> = - Err(SynthesisError::AssignmentMissing); + // Handle empty sequence case + if self.seq.is_empty() { + return Ok(z.to_vec()); + } // use the provided inputs let x_0 = z[0].clone(); @@ -121,16 +124,13 @@ impl StepCircuit for MinRootCircuit { |lc| lc + x_i.get_variable() + y_i.get_variable(), ); - if i == self.seq.len() - 1 { - z_out = Ok(vec![x_i_plus_1.clone(), x_i.clone()]); - } - // update x_i and y_i for the next iteration y_i = x_i; x_i = x_i_plus_1; } - z_out + // Return final state + Ok(vec![x_i, y_i]) } }