Assessment reports>Universal Proof Aggregator>Discussion>Additional asserts

Additional asserts

In circuits/src/batch_verify/common/chip.rs, the function scale_pairs implemented for BatchVerifierChip is implemented as follows:

/// Returns `(scalar_i * A_i, B_i)`
pub(crate) fn scale_pairs(
    &self,
    ctx: &mut Context<F>,
    scalars: &[AssignedValue<F>],
    pairs: &[(G1Point<F>, G2Point<F>)],
) -> Vec<(G1Point<F>, G2Point<F>)> {
    let mut result = Vec::with_capacity(pairs.len());
    for ((g1, g2), scalar) in pairs.iter().zip(scalars.iter()) {
        result.push((
            scalar_multiply::<_, FpChip<F, Fq>, G1Affine>(
                self.fp_chip,
                ctx,
                g1.clone(),
                vec![*scalar],
                F::NUM_BITS as usize,
                WINDOW_BITS,
            ),
            g2.clone(),
        ))
    }
    result
}

If the lists scalars and pairs have different lengths, scale_pairs will return a list that is only as long as the shorter of the two lists but will not error. For in-depth defense against future coding errors in callers, we recommend to change usage of zip to zip_eq or otherwise verify that scalars and pairs have the same lengths.

Similarly, the pack function in circuits/src/keccak/utils.rs should not be used with an array bits that is longer than 64 entries. To prevent future mistakes, it could be asserted in the function that bits is at most 64 entries long:

fn pack<F>(
    ctx: &mut Context<F>,
    chip: &RangeChip<F>,
    bits: &[AssignedValue<F>],
) -> AssignedValue<F>
where
    F: EccPrimeField,
{
+     assert_eq!(bits.len(), 64, "Number of bits to be packed should be 64");
    let base = ctx.load_constant(F::from(8u64));
    let initial_value = ctx.load_constant(F::zero());
    bits.iter().rev().fold(initial_value, |acc, bit| {
        chip.gate.mul_add(ctx, acc, base, *bit)
    })
}

The two asserts discussed above were inserted in commit

Zellic © 2024Back to top ↑