From eb8803f9ebf96f81f46a370b682ae9a32d0dac0d Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 17 Dec 2017 09:31:33 -0700 Subject: [PATCH] Implementation of `into_bits_strict` for `Num`. --- src/circuit/num.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/circuit/num.rs b/src/circuit/num.rs index 2c244e3..73eca1a 100644 --- a/src/circuit/num.rs +++ b/src/circuit/num.rs @@ -48,6 +48,18 @@ impl AllocatedNum { }) } + pub fn into_bits_strict( + &self, + mut cs: CS + ) -> Result>, SynthesisError> + where CS: ConstraintSystem + { + let bits = self.into_bits(&mut cs)?; + Boolean::enforce_in_field::<_, _, E::Fr>(&mut cs, &bits)?; + + Ok(bits) + } + pub fn into_bits( &self, mut cs: CS @@ -302,6 +314,35 @@ mod test { } } + #[test] + fn test_into_bits_strict() { + let mut negone = Fr::one(); + negone.negate(); + + let mut cs = TestConstraintSystem::::new(); + + let n = AllocatedNum::alloc(&mut cs, || Ok(negone)).unwrap(); + n.into_bits_strict(&mut cs).unwrap(); + + assert!(cs.is_satisfied()); + + // make the bit representation the characteristic + cs.set("bit 254/boolean", Fr::one()); + + // this makes the unpacking constraint fail + assert_eq!(cs.which_is_unsatisfied().unwrap(), "unpacking constraint"); + + // fix it by making the number zero (congruent to the characteristic) + cs.set("num", Fr::zero()); + + // and constraint is disturbed during enforce in field check + assert_eq!(cs.which_is_unsatisfied().unwrap(), "nand 121/AND 0/and constraint"); + cs.set("nand 121/AND 0/and result", Fr::one()); + + // now the nand should fail (enforce in field is working) + assert_eq!(cs.which_is_unsatisfied().unwrap(), "nand 121/enforce nand"); + } + #[test] fn test_into_bits() { let mut rng = XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);