arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
Implement `conditional_check_verify` for `NIZK`s (#195)

* Implement `ToBitsGadget` for `UInt8` and `Vec<UInt8>`
* Add `kary_or` function to `Boolean`.
Bruno França 43445067+brunoffranca@users.noreply.github.com
Wed, 22 Apr 2020 21:30:33 +0100
commit

bbb7d75ec8d338e40f7e69f809fa8c5cba31afe6

parent

5cc094be6b29e11acb718edbfdc2c67dc287fabf

M crypto-primitives/src/nizk/constraints.rs → crypto-primitives/src/nizk/constraints.rs

@@ -20,4 +20,16 @@ where

CS: ConstraintSystem<ConstraintF>, I: Iterator<Item = &'a T>, T: 'a + ToBitsGadget<ConstraintF> + ?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<ConstraintF>, + I: Iterator<Item = &'a T>, + T: 'a + ToBitsGadget<ConstraintF> + ?Sized; }
M crypto-primitives/src/nizk/gm17/constraints.rs → crypto-primitives/src/nizk/gm17/constraints.rs

@@ -109,10 +109,31 @@ type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>;

type ProofGadget = ProofGadget<PairingE, ConstraintF, P>; fn check_verify<'a, CS, I, T>( + cs: CS, + vk: &Self::VerificationKeyGadget, + public_inputs: I, + proof: &Self::ProofGadget, + ) -> Result<(), SynthesisError> + where + CS: ConstraintSystem<ConstraintF>, + I: Iterator<Item = &'a T>, + T: 'a + ToBitsGadget<ConstraintF> + ?Sized, + { + <Self as NIZKVerifierGadget<Gm17<PairingE, C, V>, 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<ConstraintF>,

@@ -189,8 +210,8 @@ };

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(()) } }
M crypto-primitives/src/nizk/gm17/mod.rs → crypto-primitives/src/nizk/gm17/mod.rs

@@ -35,10 +35,10 @@ for Gm17<E, C, V>

{ type Circuit = C; type AssignedCircuit = C; + type VerifierInput = V; type ProvingParameters = Parameters<E>; type VerificationParameters = VerifyingKey<E>; type PreparedVerificationParameters = PreparedVerifyingKey<E>; - type VerifierInput = V; type Proof = Proof<E>; fn setup<R: Rng>(
M crypto-primitives/src/nizk/groth16/constraints.rs → crypto-primitives/src/nizk/groth16/constraints.rs

@@ -110,10 +110,31 @@ type VerificationKeyGadget = VerifyingKeyGadget<PairingE, ConstraintF, P>;

type ProofGadget = ProofGadget<PairingE, ConstraintF, P>; fn check_verify<'a, CS, I, T>( + cs: CS, + vk: &Self::VerificationKeyGadget, + public_inputs: I, + proof: &Self::ProofGadget, + ) -> Result<(), SynthesisError> + where + CS: ConstraintSystem<ConstraintF>, + I: Iterator<Item = &'a T>, + T: 'a + ToBitsGadget<ConstraintF> + ?Sized, + { + <Self as NIZKVerifierGadget<Groth16<PairingE, C, V>, 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<ConstraintF>,

@@ -161,7 +182,7 @@ };

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(()) } }
M crypto-primitives/src/nizk/groth16/mod.rs → crypto-primitives/src/nizk/groth16/mod.rs

@@ -35,10 +35,10 @@ for Groth16<E, C, V>

{ type Circuit = C; type AssignedCircuit = C; + type VerifierInput = V; type ProvingParameters = Parameters<E>; type VerificationParameters = VerifyingKey<E>; type PreparedVerificationParameters = PreparedVerifyingKey<E>; - type VerifierInput = V; type Proof = Proof<E>; fn setup<R: Rng>(
M r1cs-std/src/bits/boolean.rs → r1cs-std/src/bits/boolean.rs

@@ -549,6 +549,22 @@

Ok(cur) } + pub fn kary_or<ConstraintF, CS>(mut cs: CS, bits: &[Self]) -> Result<Self, SynthesisError> + where + ConstraintF: Field, + CS: ConstraintSystem<ConstraintF>, + { + 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<ConstraintF, CS>(mut cs: CS, bits: &[Self]) -> Result<(), SynthesisError> where
M r1cs-std/src/bits/mod.rs → r1cs-std/src/bits/mod.rs

@@ -58,7 +58,29 @@ Ok(self.clone())

} } +impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for UInt8 { + fn to_bits<CS: ConstraintSystem<ConstraintF>>( + &self, + _cs: CS, + ) -> Result<Vec<Boolean>, SynthesisError> { + Ok(self.into_bits_le()) + } +} + impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for [UInt8] { + fn to_bits<CS: ConstraintSystem<ConstraintF>>( + &self, + _cs: CS, + ) -> Result<Vec<Boolean>, SynthesisError> { + let mut result = Vec::with_capacity(&self.len() * 8); + for byte in self { + result.extend_from_slice(&byte.into_bits_le()); + } + Ok(result) + } +} + +impl<ConstraintF: Field> ToBitsGadget<ConstraintF> for Vec<UInt8> { fn to_bits<CS: ConstraintSystem<ConstraintF>>( &self, _cs: CS,