diff --git a/crypto-primitives/src/nizk/constraints.rs b/crypto-primitives/src/nizk/constraints.rs index da75548..61c4cb6 100644 --- a/crypto-primitives/src/nizk/constraints.rs +++ b/crypto-primitives/src/nizk/constraints.rs @@ -20,4 +20,16 @@ pub trait NIZKVerifierGadget { CS: ConstraintSystem, I: Iterator, T: 'a + ToBitsGadget + ?Sized; + + fn conditional_check_verify<'a, CS, I, T>( + cs: CS, + verification_key: &Self::VerificationKeyGadget, + input: I, + proof: &Self::ProofGadget, + condition: &Boolean, + ) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, + I: Iterator, + T: 'a + ToBitsGadget + ?Sized; } diff --git a/crypto-primitives/src/nizk/gm17/constraints.rs b/crypto-primitives/src/nizk/gm17/constraints.rs index 6e9b523..6f09608 100644 --- a/crypto-primitives/src/nizk/gm17/constraints.rs +++ b/crypto-primitives/src/nizk/gm17/constraints.rs @@ -109,10 +109,31 @@ where type ProofGadget = ProofGadget; fn check_verify<'a, CS, I, T>( + cs: CS, + vk: &Self::VerificationKeyGadget, + public_inputs: I, + proof: &Self::ProofGadget, + ) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, + I: Iterator, + T: 'a + ToBitsGadget + ?Sized, + { + , ConstraintF>>::conditional_check_verify( + cs, + vk, + public_inputs, + proof, + &Boolean::constant(true), + ) + } + + fn conditional_check_verify<'a, CS, I, T>( mut cs: CS, vk: &Self::VerificationKeyGadget, mut public_inputs: I, proof: &Self::ProofGadget, + condition: &Boolean, ) -> Result<(), SynthesisError> where CS: ConstraintSystem, @@ -189,8 +210,8 @@ where let test2 = P::final_exponentiation(cs.ns(|| "Final Exp 2"), &test2_exp)?; let one = P::GTGadget::one(cs.ns(|| "GT One"))?; - test1.enforce_equal(cs.ns(|| "Test 1"), &one)?; - test2.enforce_equal(cs.ns(|| "Test 2"), &one)?; + test1.conditional_enforce_equal(cs.ns(|| "Test 1"), &one, condition)?; + test2.conditional_enforce_equal(cs.ns(|| "Test 2"), &one, condition)?; Ok(()) } } diff --git a/crypto-primitives/src/nizk/gm17/mod.rs b/crypto-primitives/src/nizk/gm17/mod.rs index 82c312c..290add9 100644 --- a/crypto-primitives/src/nizk/gm17/mod.rs +++ b/crypto-primitives/src/nizk/gm17/mod.rs @@ -35,10 +35,10 @@ impl, V: ToConstraintField; type VerificationParameters = VerifyingKey; type PreparedVerificationParameters = PreparedVerifyingKey; - type VerifierInput = V; type Proof = Proof; fn setup( diff --git a/crypto-primitives/src/nizk/groth16/constraints.rs b/crypto-primitives/src/nizk/groth16/constraints.rs index 9b8144c..49e07d7 100644 --- a/crypto-primitives/src/nizk/groth16/constraints.rs +++ b/crypto-primitives/src/nizk/groth16/constraints.rs @@ -110,10 +110,31 @@ where type ProofGadget = ProofGadget; fn check_verify<'a, CS, I, T>( + cs: CS, + vk: &Self::VerificationKeyGadget, + public_inputs: I, + proof: &Self::ProofGadget, + ) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, + I: Iterator, + T: 'a + ToBitsGadget + ?Sized, + { + , ConstraintF>>::conditional_check_verify( + cs, + vk, + public_inputs, + proof, + &Boolean::constant(true), + ) + } + + fn conditional_check_verify<'a, CS, I, T>( mut cs: CS, vk: &Self::VerificationKeyGadget, mut public_inputs: I, proof: &Self::ProofGadget, + condition: &Boolean, ) -> Result<(), SynthesisError> where CS: ConstraintSystem, @@ -161,7 +182,7 @@ where let test = P::final_exponentiation(cs.ns(|| "Final Exp"), &test_exp).unwrap(); - test.enforce_equal(cs.ns(|| "Test 1"), &pvk.alpha_g1_beta_g2)?; + test.conditional_enforce_equal(cs.ns(|| "Test 1"), &pvk.alpha_g1_beta_g2, condition)?; Ok(()) } } diff --git a/crypto-primitives/src/nizk/groth16/mod.rs b/crypto-primitives/src/nizk/groth16/mod.rs index 44faec9..c4d6f05 100644 --- a/crypto-primitives/src/nizk/groth16/mod.rs +++ b/crypto-primitives/src/nizk/groth16/mod.rs @@ -35,10 +35,10 @@ impl, V: ToConstraintField; type VerificationParameters = VerifyingKey; type PreparedVerificationParameters = PreparedVerifyingKey; - type VerifierInput = V; type Proof = Proof; fn setup( diff --git a/r1cs-std/src/bits/boolean.rs b/r1cs-std/src/bits/boolean.rs index 23a205f..70759d1 100644 --- a/r1cs-std/src/bits/boolean.rs +++ b/r1cs-std/src/bits/boolean.rs @@ -549,6 +549,22 @@ impl Boolean { Ok(cur) } + pub fn kary_or(mut cs: CS, bits: &[Self]) -> Result + where + ConstraintF: Field, + CS: ConstraintSystem, + { + assert!(!bits.is_empty()); + let mut bits = bits.iter(); + + let mut cur: Self = *bits.next().unwrap(); + for (i, next) in bits.enumerate() { + cur = Boolean::or(cs.ns(|| format!("OR {}", i)), &cur, next)?; + } + + Ok(cur) + } + /// Asserts that at least one operand is false. pub fn enforce_nand(mut cs: CS, bits: &[Self]) -> Result<(), SynthesisError> where diff --git a/r1cs-std/src/bits/mod.rs b/r1cs-std/src/bits/mod.rs index 3829d8b..6bb4747 100644 --- a/r1cs-std/src/bits/mod.rs +++ b/r1cs-std/src/bits/mod.rs @@ -58,6 +58,15 @@ impl ToBitsGadget for Vec { } } +impl ToBitsGadget for UInt8 { + fn to_bits>( + &self, + _cs: CS, + ) -> Result, SynthesisError> { + Ok(self.into_bits_le()) + } +} + impl ToBitsGadget for [UInt8] { fn to_bits>( &self, @@ -71,6 +80,19 @@ impl ToBitsGadget for [UInt8] { } } +impl ToBitsGadget for Vec { + fn to_bits>( + &self, + _cs: CS, + ) -> Result, SynthesisError> { + let mut result = Vec::with_capacity(&self.len() * 8); + for byte in self { + result.extend_from_slice(&byte.into_bits_le()); + } + Ok(result) + } +} + pub trait ToBytesGadget { /// Outputs a canonical byte-wise representation of `self`. ///