noir-lang/noir

Modulus in brillig bigint is checked but never written

Closed this issue · 0 comments

Aim

Use bigint in brillig

Expected Behavior

Moduli should be checked correctly on operations

Bug

Modulus is half implemented in brillig, it's checked by manually emitting opcodes to check it, but it's never written to, so it fails randomly when the stack offset reserved for it was used for different things previously.

To Reproduce

This code fails to execute since the stack offset of modulus of a and b was reused, and since it's never written to, it contains old non-matching values.

unconstrained fn add_unconstrained(values: [[u8; 32]; 2], modulus: [[u8; 32]; 2]) -> [u8; 32] {
    let a = BigInt::from_le_bytes(values[0].as_slice(), modulus[0].as_slice());
    // dep::std::println(a.modulus);

    let b = BigInt::from_le_bytes(values[1].as_slice(), modulus[1].as_slice());
    // dep::std::println(b.modulus);

    a.bigint_add(b).to_le_bytes()
}

fn main() {
    let values = [27, 3];
    let moduli = [256, 256];

    let values_as_bytes = values.map(|value: Field| value.to_le_bytes(32).as_array());
    let moduli_as_bytes = moduli.map(|modulus: Field| modulus.to_le_bytes(32).as_array());

    let result = add_unconstrained(values_as_bytes, moduli_as_bytes);

    assert_eq(result, 30.to_le_bytes(32).as_array());
}

Project Impact

None

Impact Context

No response

Workaround

None

Workaround Description

No response

Additional Context

No response

Installation Method

None

Nargo Version

No response

NoirJS Version

No response

Would you like to submit a PR for this Issue?

None

Support Needs

No response