From fbffd60212601ed5a423eb3ac7d20929a4964009 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 9 Jul 2022 06:21:11 -0400 Subject: [PATCH] arithmetic_u32::tests: Add test_canonicity check. This test should fail because its output is the non-canonical value p = (u32::MAX, 1). However, since the U32ArithmeticGate currently permits non-canonical outputs, this test passes. --- u32/src/gates/arithmetic_u32.rs | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/u32/src/gates/arithmetic_u32.rs b/u32/src/gates/arithmetic_u32.rs index d2a3860e..ccbdcacf 100644 --- a/u32/src/gates/arithmetic_u32.rs +++ b/u32/src/gates/arithmetic_u32.rs @@ -461,4 +461,39 @@ mod tests { "Gate constraints are not satisfied." ); } + + #[test] + fn test_canonicity() { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + type FF = >::FE; + const NUM_U32_ARITHMETIC_OPS: usize = 3; + + let multiplicands_0 = vec![0; NUM_U32_ARITHMETIC_OPS]; + let multiplicands_1 = vec![0; NUM_U32_ARITHMETIC_OPS]; + // A non-canonical addend will produce a non-canonical output using + // get_wires. + let addends = vec![0xFFFFFFFF00000001; NUM_U32_ARITHMETIC_OPS]; + + let gate = U32ArithmeticGate:: { + num_ops: NUM_U32_ARITHMETIC_OPS, + _phantom: PhantomData, + }; + + let vars = EvaluationVars { + local_constants: &[], + local_wires: &get_wires::( + multiplicands_0, + multiplicands_1, + addends, + ), + public_inputs_hash: &HashOut::rand(), + }; + + assert!( + !gate.eval_unfiltered(vars).iter().all(|x| x.is_zero()), + "Non-canonical output should not pass constraints." + ); + } }