From c4cc5dd5161bb2c8ccb4240bb5b5cf827dcbb0fa Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 9 Dec 2021 15:02:51 +0000 Subject: [PATCH] Add operator tests on `Assigned` for cases including `1/0` The tests for addition and subtraction expose a bug in the addition implementation, which does not correctly handle the `1/0 -> 0` map that `inv0` is defined to perform. --- src/plonk/assigned.rs | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/plonk/assigned.rs b/src/plonk/assigned.rs index 4e984bc4..bb3ec94b 100644 --- a/src/plonk/assigned.rs +++ b/src/plonk/assigned.rs @@ -163,3 +163,69 @@ impl Assigned { } } } + +#[cfg(test)] +mod tests { + use pasta_curves::Fp; + + use super::Assigned; + + #[test] + fn add_trivial_to_inv0_rational() { + // a = 2 + // b = inv0(1/0) + let a = Assigned::Trivial(Fp::from(2)); + let b = Assigned::Rational(Fp::one(), Fp::zero()); + + // 2 + inv0(1/0) = 2 + 0 = 1/2 + // This fails if addition is implemented using normal rules for rationals. + assert_eq!((a + b).evaluate(), a.evaluate()); + } + + #[test] + fn add_rational_to_inv0_rational() { + // a = inv0(1/2) + // b = inv0(1/0) + let a = Assigned::Rational(Fp::one(), Fp::from(2)); + let b = Assigned::Rational(Fp::one(), Fp::zero()); + + // inv0(1/2) + inv0(1/0) = 1/2 + 0 = 1/2 + // This fails if addition is implemented using normal rules for rationals. + assert_eq!((a + b).evaluate(), a.evaluate()); + } + + #[test] + fn sub_trivial_from_inv0_rational() { + // a = 2 + // b = inv0(1/0) + let a = Assigned::Trivial(Fp::from(2)); + let b = Assigned::Rational(Fp::one(), Fp::zero()); + + // inv0(1/0) - 2 = 0 - 2 = -2 + // This fails if subtraction is implemented using normal rules for rationals. + assert_eq!((b - a).evaluate(), (-a).evaluate()); + } + + #[test] + fn sub_rational_from_inv0_rational() { + // a = inv0(1/2) + // b = inv0(1/0) + let a = Assigned::Rational(Fp::one(), Fp::from(2)); + let b = Assigned::Rational(Fp::one(), Fp::zero()); + + // inv0(1/0) - inv0(1/2) = 0 - 1/2 = -1/2 + // This fails if subtraction is implemented using normal rules for rationals. + assert_eq!((b - a).evaluate(), (-a).evaluate()); + } + + #[test] + fn mul_rational_by_inv0_rational() { + // a = inv0(1/2) + // b = inv0(1/0) + let a = Assigned::Rational(Fp::one(), Fp::from(2)); + let b = Assigned::Rational(Fp::one(), Fp::zero()); + + // inv0(1/2) * inv0(1/0) = 1/2 * 0 = 0 + assert_eq!((a * b).evaluate(), Fp::zero()); + } +}