arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
Merge branch 'master' into inline-asm
jon-chuang 9093549+jon-chuang@users.noreply.github.com
Thu, 23 Apr 2020 08:26:20 +0800
commit

b1f4c50fd88686afcbbeec68d1d57df0bde9185e

parent

535f93d3784e0fdd11dbba4ee224ab9cf6aed682

M crypto-primitives/src/commitment/blake2s/constraints.rs → crypto-primitives/src/commitment/blake2s/constraints.rs

@@ -3,7 +3,7 @@

use crate::{ commitment::blake2s::Blake2sCommitment, prf::blake2s::constraints::{blake2s_gadget, Blake2sOutputGadget}, - CommitmentGadget, + CommitmentGadget, Vec, }; use algebra_core::{Field, PrimeField}; use r1cs_std::prelude::*;

@@ -48,6 +48,16 @@ }

} impl<ConstraintF: Field> AllocGadget<(), ConstraintF> for Blake2sParametersGadget { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<()>, + { + Self::alloc(cs, || Ok(val)) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(_: CS, _: F) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>,

@@ -69,6 +79,22 @@ }

} impl<ConstraintF: PrimeField> AllocGadget<[u8; 32], ConstraintF> for Blake2sRandomnessGadget { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<[u8; 32]>, + { + let mut bytes = vec![]; + for (i, b) in val.borrow().iter().enumerate() { + bytes.push(UInt8::alloc_constant(cs.ns(|| format!("value {}", i)), b)?) + } + + Ok(Blake2sRandomnessGadget(bytes)) + } + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( cs: CS,
M crypto-primitives/src/commitment/pedersen/constraints.rs → crypto-primitives/src/commitment/pedersen/constraints.rs

@@ -1,6 +1,7 @@

use crate::{ commitment::pedersen::{PedersenCommitment, PedersenParameters, PedersenRandomness}, crh::pedersen::PedersenWindow, + Vec, }; use algebra_core::{ fields::{Field, PrimeField},

@@ -97,16 +98,14 @@ G: Group,

W: PedersenWindow, ConstraintF: PrimeField, { - fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( _cs: CS, - value_gen: F, + val: T, ) -> Result<Self, SynthesisError> where - F: FnOnce() -> Result<T, SynthesisError>, T: Borrow<PedersenParameters<G>>, { - let temp = value_gen()?; - let parameters = temp.borrow().clone(); + let parameters = val.borrow().clone(); Ok(PedersenCommitmentGadgetParameters { params: parameters,

@@ -116,6 +115,18 @@ _window: PhantomData,

}) } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + value_gen: F, + ) -> Result<Self, SynthesisError> + where + F: FnOnce() -> Result<T, SynthesisError>, + T: Borrow<PedersenParameters<G>>, + { + let temp = value_gen()?; + Self::alloc_constant(cs, temp) + } + fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>( _cs: CS, value_gen: F,

@@ -141,6 +152,21 @@ where

G: Group, ConstraintF: PrimeField, { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<PedersenRandomness<G>>, + { + let mut result_bytes = vec![]; + for (i, byte) in to_bytes![val.borrow().0].unwrap().into_iter().enumerate() { + let cur = UInt8::alloc_constant(cs.ns(|| format!("byte {}", i)), byte)?; + result_bytes.push(cur); + } + Ok(PedersenRandomnessGadget(result_bytes)) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( cs: CS, value_gen: F,
M crypto-primitives/src/crh/bowe_hopwood/constraints.rs → crypto-primitives/src/crh/bowe_hopwood/constraints.rs

@@ -1,9 +1,12 @@

use core::{borrow::Borrow, hash::Hash, marker::PhantomData}; -use crate::crh::{ - bowe_hopwood::{BoweHopwoodPedersenCRH, BoweHopwoodPedersenParameters, CHUNK_SIZE}, - pedersen::PedersenWindow, - FixedLengthCRHGadget, +use crate::{ + crh::{ + bowe_hopwood::{BoweHopwoodPedersenCRH, BoweHopwoodPedersenParameters, CHUNK_SIZE}, + pedersen::PedersenWindow, + FixedLengthCRHGadget, + }, + Vec, }; use algebra_core::{groups::Group, Field}; use r1cs_core::{ConstraintSystem, SynthesisError};

@@ -86,21 +89,32 @@ impl<G: Group, W: PedersenWindow, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>>

AllocGadget<BoweHopwoodPedersenParameters<G>, ConstraintF> for BoweHopwoodPedersenCRHGadgetParameters<G, W, ConstraintF, GG> { - fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( _cs: CS, - value_gen: F, + val: T, ) -> Result<Self, SynthesisError> where - F: FnOnce() -> Result<T, SynthesisError>, T: Borrow<BoweHopwoodPedersenParameters<G>>, { - let params = value_gen()?.borrow().clone(); + let params = val.borrow().clone(); Ok(BoweHopwoodPedersenCRHGadgetParameters { params, _group_g: PhantomData, _engine: PhantomData, _window: PhantomData, }) + } + + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + value_gen: F, + ) -> Result<Self, SynthesisError> + where + F: FnOnce() -> Result<T, SynthesisError>, + T: Borrow<BoweHopwoodPedersenParameters<G>>, + { + let params = value_gen()?.borrow().clone(); + Self::alloc_constant(cs, params) } fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
M crypto-primitives/src/crh/pedersen/constraints.rs → crypto-primitives/src/crh/pedersen/constraints.rs

@@ -1,6 +1,9 @@

-use crate::crh::{ - pedersen::{PedersenCRH, PedersenParameters, PedersenWindow}, - FixedLengthCRHGadget, +use crate::{ + crh::{ + pedersen::{PedersenCRH, PedersenParameters, PedersenWindow}, + FixedLengthCRHGadget, + }, + Vec, }; use algebra_core::{Field, Group}; use r1cs_core::{ConstraintSystem, SynthesisError};

@@ -77,21 +80,32 @@ impl<G: Group, W: PedersenWindow, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>>

AllocGadget<PedersenParameters<G>, ConstraintF> for PedersenCRHGadgetParameters<G, W, ConstraintF, GG> { - fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( _cs: CS, - value_gen: F, + val: T, ) -> Result<Self, SynthesisError> where - F: FnOnce() -> Result<T, SynthesisError>, T: Borrow<PedersenParameters<G>>, { - let params = value_gen()?.borrow().clone(); + let params = val.borrow().clone(); Ok(PedersenCRHGadgetParameters { params, _group_g: PhantomData, _engine: PhantomData, _window: PhantomData, }) + } + + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + value_gen: F, + ) -> Result<Self, SynthesisError> + where + F: FnOnce() -> Result<T, SynthesisError>, + T: Borrow<PedersenParameters<G>>, + { + let params = value_gen()?.borrow().clone(); + Self::alloc_constant(cs, params) } fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
M crypto-primitives/src/merkle_tree/constraints.rs → crypto-primitives/src/merkle_tree/constraints.rs

@@ -128,6 +128,28 @@ P: MerkleTreeConfig,

HGadget: FixedLengthCRHGadget<P::H, ConstraintF>, ConstraintF: Field, { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<MerkleTreePath<P>>, + { + let mut path = Vec::new(); + for (i, &(ref l, ref r)) in val.borrow().path.iter().enumerate() { + let l_hash = HGadget::OutputGadget::alloc_constant( + &mut cs.ns(|| format!("l_child_{}", i)), + l.clone(), + )?; + let r_hash = HGadget::OutputGadget::alloc_constant( + &mut cs.ns(|| format!("r_child_{}", i)), + r.clone(), + )?; + path.push((l_hash, r_hash)); + } + Ok(MerkleTreePathGadget { path }) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
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

@@ -1,4 +1,7 @@

-use crate::nizk::{gm17::Gm17, NIZKVerifierGadget}; +use crate::{ + nizk::{gm17::Gm17, NIZKVerifierGadget}, + Vec, +}; use algebra_core::{AffineCurve, Field, PairingEngine, ToConstraintField}; use r1cs_core::{ConstraintSynthesizer, ConstraintSystem, SynthesisError}; use r1cs_std::prelude::*;

@@ -106,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>,

@@ -186,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(()) } }

@@ -200,6 +224,54 @@ ConstraintF: Field,

P: PairingGadget<PairingE, ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<VerifyingKey<PairingE>>, + { + let VerifyingKey { + h_g2, + g_alpha_g1, + h_beta_g2, + g_gamma_g1, + h_gamma_g2, + query, + } = val.borrow().clone(); + let h_g2 = P::G2Gadget::alloc_constant(cs.ns(|| "h_g2"), h_g2.into_projective())?; + let g_alpha_g1 = + P::G1Gadget::alloc_constant(cs.ns(|| "g_alpha"), g_alpha_g1.into_projective())?; + let h_beta_g2 = + P::G2Gadget::alloc_constant(cs.ns(|| "h_beta"), h_beta_g2.into_projective())?; + let g_gamma_g1 = + P::G1Gadget::alloc_constant(cs.ns(|| "g_gamma_g1"), g_gamma_g1.into_projective())?; + let h_gamma_g2 = + P::G2Gadget::alloc_constant(cs.ns(|| "h_gamma_g2"), h_gamma_g2.into_projective())?; + + let query = query + .into_iter() + .enumerate() + .map(|(i, query_i)| { + P::G1Gadget::alloc_constant( + cs.ns(|| format!("query_{}", i)), + query_i.into_projective(), + ) + }) + .collect::<Vec<_>>() + .into_iter() + .collect::<Result<_, _>>()?; + Ok(Self { + h_g2, + g_alpha_g1, + h_beta_g2, + g_gamma_g1, + h_gamma_g2, + query, + }) + } + + #[inline] fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: FN,

@@ -309,6 +381,21 @@ PairingE: PairingEngine,

ConstraintF: Field, P: PairingGadget<PairingE, ConstraintF>, { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Proof<PairingE>>, + { + let Proof { a, b, c } = val.borrow().clone(); + let a = P::G1Gadget::alloc_constant(cs.ns(|| "a"), a.into_projective())?; + let b = P::G2Gadget::alloc_constant(cs.ns(|| "b"), b.into_projective())?; + let c = P::G1Gadget::alloc_constant(cs.ns(|| "c"), c.into_projective())?; + Ok(Self { a, b, c }) + } + #[inline] fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS,
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

@@ -1,4 +1,7 @@

-use crate::nizk::{groth16::Groth16, NIZKVerifierGadget}; +use crate::{ + nizk::{groth16::Groth16, NIZKVerifierGadget}, + Vec, +}; use algebra_core::{AffineCurve, Field, PairingEngine, ToConstraintField}; use r1cs_core::{ConstraintSynthesizer, ConstraintSystem, SynthesisError}; use r1cs_std::prelude::*;

@@ -107,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>,

@@ -158,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(()) } }

@@ -171,6 +195,50 @@ ConstraintF: Field,

P: PairingGadget<PairingE, ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<VerifyingKey<PairingE>>, + { + let VerifyingKey { + alpha_g1, + beta_g2, + gamma_g2, + delta_g2, + gamma_abc_g1, + } = val.borrow().clone(); + let alpha_g1 = + P::G1Gadget::alloc_constant(cs.ns(|| "alpha_g1"), alpha_g1.into_projective())?; + let beta_g2 = P::G2Gadget::alloc_constant(cs.ns(|| "beta_g2"), beta_g2.into_projective())?; + let gamma_g2 = + P::G2Gadget::alloc_constant(cs.ns(|| "gamma_g2"), gamma_g2.into_projective())?; + let delta_g2 = + P::G2Gadget::alloc_constant(cs.ns(|| "delta_g2"), delta_g2.into_projective())?; + + let gamma_abc_g1 = gamma_abc_g1 + .into_iter() + .enumerate() + .map(|(i, gamma_abc_i)| { + P::G1Gadget::alloc_constant( + cs.ns(|| format!("gamma_abc_{}", i)), + gamma_abc_i.into_projective(), + ) + }) + .collect::<Vec<_>>() + .into_iter() + .collect::<Result<_, _>>()?; + Ok(Self { + alpha_g1, + beta_g2, + gamma_g2, + delta_g2, + gamma_abc_g1, + }) + } + + #[inline] fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: FN,

@@ -273,6 +341,21 @@ PairingE: PairingEngine,

ConstraintF: Field, P: PairingGadget<PairingE, ConstraintF>, { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Proof<PairingE>>, + { + let Proof { a, b, c } = val.borrow().clone(); + let a = P::G1Gadget::alloc_constant(cs.ns(|| "a"), a.into_projective())?; + let b = P::G2Gadget::alloc_constant(cs.ns(|| "b"), b.into_projective())?; + let c = P::G1Gadget::alloc_constant(cs.ns(|| "c"), c.into_projective())?; + Ok(Self { a, b, c }) + } + #[inline] fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS,
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 crypto-primitives/src/prf/blake2s/constraints.rs → crypto-primitives/src/prf/blake2s/constraints.rs

@@ -1,7 +1,7 @@

use algebra_core::PrimeField; use r1cs_core::{ConstraintSystem, SynthesisError}; -use crate::prf::PRFGadget; +use crate::{prf::PRFGadget, Vec}; use r1cs_std::prelude::*; use core::borrow::Borrow;

@@ -450,6 +450,22 @@ }

} impl<ConstraintF: PrimeField> AllocGadget<[u8; 32], ConstraintF> for Blake2sOutputGadget { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<[u8; 32]>, + { + let mut bytes = vec![]; + for (i, b) in val.borrow().iter().enumerate() { + bytes.push(UInt8::alloc_constant(cs.ns(|| format!("value {}", i)), b)?) + } + + Ok(Blake2sOutputGadget(bytes)) + } + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( cs: CS,
M crypto-primitives/src/prf/constraints.rs → crypto-primitives/src/prf/constraints.rs

@@ -1,7 +1,7 @@

use algebra_core::Field; use core::fmt::Debug; -use crate::prf::PRF; +use crate::{prf::PRF, Vec}; use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_std::prelude::*;
M crypto-primitives/src/signature/schnorr/constraints.rs → crypto-primitives/src/signature/schnorr/constraints.rs

@@ -1,3 +1,4 @@

+use crate::Vec; use algebra_core::{groups::Group, Field}; use r1cs_core::{ConstraintSystem, SynthesisError}; use r1cs_std::prelude::*;

@@ -95,6 +96,21 @@ ConstraintF: Field,

GG: GroupGadget<G, ConstraintF>, D: Digest, { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<SchnorrSigParameters<G, D>>, + { + let generator = GG::alloc_constant(cs, val.borrow().generator)?; + Ok(Self { + generator, + _engine: PhantomData, + _group: PhantomData, + }) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, f: F) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>,

@@ -132,6 +148,21 @@ G: Group,

ConstraintF: Field, GG: GroupGadget<G, ConstraintF>, { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + val: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<SchnorrPublicKey<G>>, + { + let pub_key = GG::alloc_constant(cs, val.borrow())?; + Ok(Self { + pub_key, + _engine: PhantomData, + _group: PhantomData, + }) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, f: F) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>,
M r1cs-std/src/alloc.rs → r1cs-std/src/alloc.rs

@@ -8,6 +8,13 @@ where

Self: Sized, V: ?Sized, { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<V>; + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, f: F) -> Result<Self, SynthesisError> where F: FnOnce() -> Result<T, SynthesisError>,

@@ -47,6 +54,21 @@

impl<I, ConstraintF: Field, A: AllocGadget<I, ConstraintF>> AllocGadget<[I], ConstraintF> for Vec<A> { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<[I]>, + { + let mut vec = Vec::new(); + for (i, value) in t.borrow().iter().enumerate() { + vec.push(A::alloc_constant(cs.ns(|| format!("value_{}", i)), value)?); + } + Ok(vec) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, f: F,
M r1cs-std/src/bits/boolean.rs → r1cs-std/src/bits/boolean.rs

@@ -235,6 +235,16 @@

impl Eq for AllocatedBit {} impl<ConstraintF: Field> AllocGadget<bool, ConstraintF> for AllocatedBit { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + _cs: CS, + _t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<bool>, + { + unimplemented!(); + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,

@@ -539,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

@@ -715,6 +741,16 @@ }

} impl<ConstraintF: Field> AllocGadget<bool, ConstraintF> for Boolean { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + _cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<bool>, + { + Ok(Boolean::constant(*t.borrow())) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( cs: CS, value_gen: F,
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,
M r1cs-std/src/bits/uint64.rs → r1cs-std/src/bits/uint64.rs

@@ -14,7 +14,7 @@ /// unsigned integer.

#[derive(Clone, Debug)] pub struct UInt64 { // Least significant bit_gadget first - bits: Vec<Boolean>, + bits: Vec<Boolean>, value: Option<u64>, }

@@ -56,7 +56,7 @@ val >>= 1;

} v - }, + } None => vec![None; 64], };

@@ -95,19 +95,19 @@ &Boolean::Constant(b) => {

if b { value.as_mut().map(|v| *v |= 1); } - }, + } &Boolean::Is(ref b) => match b.get_value() { Some(true) => { value.as_mut().map(|v| *v |= 1); - }, - Some(false) => {}, + } + Some(false) => {} None => value = None, }, &Boolean::Not(ref b) => match b.get_value() { Some(false) => { value.as_mut().map(|v| *v |= 1); - }, - Some(true) => {}, + } + Some(true) => {} None => value = None, }, }

@@ -129,7 +129,7 @@ .cloned()

.collect(); UInt64 { - bits: new_bits, + bits: new_bits, value: self.value.map(|v| v.rotate_right(by as u32)), } }

@@ -194,12 +194,12 @@ // Accumulate the value

match op.value { Some(val) => { result_value.as_mut().map(|v| *v += u128::from(val)); - }, + } None => { // If any of our operands have unknown value, we won't // know the value of the result result_value = None; - }, + } } // Iterate over each bit_gadget of the operand and add the operand to

@@ -212,18 +212,18 @@ all_constants = false;

// Add coeff * bit_gadget lc += (coeff, bit.get_variable()); - }, + } Boolean::Not(ref bit) => { all_constants = false; // Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget lc = lc + (coeff, CS::one()) - (coeff, bit.get_variable()); - }, + } Boolean::Constant(bit) => { if bit { lc += (coeff, CS::one()); } - }, + } } coeff.double_in_place();

@@ -270,13 +270,23 @@ // Discard carry bits that we don't care about

result_bits.truncate(64); Ok(UInt64 { - bits: result_bits, + bits: result_bits, value: modular_value, }) } } impl<ConstraintF: Field> AllocGadget<u64, ConstraintF> for UInt64 { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + _cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<u64>, + { + Ok(UInt64::constant(*t.borrow())) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,

@@ -330,7 +340,7 @@ };

let mut bytes = Vec::new(); for (i, chunk8) in self.to_bits_le().chunks(8).enumerate() { let byte = UInt8 { - bits: chunk8.to_vec(), + bits: chunk8.to_vec(), value: value_chunks[i], }; bytes.push(byte);

@@ -397,7 +407,7 @@ for (i, bit_gadget) in b.bits.iter().enumerate() {

match bit_gadget { &Boolean::Constant(bit_gadget) => { assert!(bit_gadget == ((b.value.unwrap() >> i) & 1 == 1)); - }, + } _ => unreachable!(), } }

@@ -406,8 +416,8 @@ let expected_to_be_same = b.to_bits_le();

for x in v.iter().zip(expected_to_be_same.iter()) { match x { - (&Boolean::Constant(true), &Boolean::Constant(true)) => {}, - (&Boolean::Constant(false), &Boolean::Constant(false)) => {}, + (&Boolean::Constant(true), &Boolean::Constant(true)) => {} + (&Boolean::Constant(false), &Boolean::Constant(false)) => {} _ => unreachable!(), } }

@@ -442,13 +452,13 @@ for b in r.bits.iter() {

match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(b) => { assert!(b == (expected & 1 == 1)); - }, + } } expected >>= 1;

@@ -483,7 +493,7 @@ &Boolean::Is(_) => panic!(),

&Boolean::Not(_) => panic!(), &Boolean::Constant(b) => { assert!(b == (expected & 1 == 1)); - }, + } } expected >>= 1;

@@ -521,10 +531,10 @@ for b in r.bits.iter() {

match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(_) => unreachable!(), }

@@ -560,7 +570,7 @@ for b in &b.bits {

match b { &Boolean::Constant(b) => { assert_eq!(b, tmp & 1 == 1); - }, + } _ => unreachable!(), }
M r1cs-std/src/bits/uint8.rs → r1cs-std/src/bits/uint8.rs

@@ -214,6 +214,16 @@

impl<ConstraintF: Field> EqGadget<ConstraintF> for UInt8 {} impl<ConstraintF: Field> AllocGadget<u8, ConstraintF> for UInt8 { + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + _cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<u8>, + { + Ok(UInt8::constant(*t.borrow())) + } + fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp/mod.rs → r1cs-std/src/fields/fp/mod.rs

@@ -585,6 +585,18 @@ }

impl<F: PrimeField> AllocGadget<F, F> for FpGadget<F> { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<F>>(_cs: CS, t: T) -> Result<Self, SynthesisError> + where + T: Borrow<F>, + { + let value = t.borrow().clone(); + Ok(Self { + value: Some(value), + variable: LinearCombination::from((value, CS::one())).into(), + }) + } + + #[inline] fn alloc<FN, T, CS: ConstraintSystem<F>>( mut cs: CS, value_gen: FN,
M r1cs-std/src/fields/fp12.rs → r1cs-std/src/fields/fp12.rs

@@ -835,6 +835,17 @@ P: Fp12Parameters,

<P::Fp6Params as Fp6Parameters>::Fp2Params: Fp2Parameters<Fp = ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp12<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp2.rs → r1cs-std/src/fields/fp2.rs

@@ -612,6 +612,17 @@ impl<P: Fp2Parameters<Fp = ConstraintF>, ConstraintF: PrimeField> AllocGadget<Fp2<P>, ConstraintF>

for Fp2Gadget<P, ConstraintF> { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp2<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp3.rs → r1cs-std/src/fields/fp3.rs

@@ -868,6 +868,17 @@ impl<P: Fp3Parameters<Fp = ConstraintF>, ConstraintF: PrimeField + SquareRootField>

AllocGadget<Fp3<P>, ConstraintF> for Fp3Gadget<P, ConstraintF> { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp3<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp4.rs → r1cs-std/src/fields/fp4.rs

@@ -674,6 +674,17 @@ P: Fp4Parameters,

P::Fp2Params: Fp2Parameters<Fp = ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp4<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp6_2over3.rs → r1cs-std/src/fields/fp6_2over3.rs

@@ -665,6 +665,17 @@ P: Fp6Parameters,

P::Fp3Params: Fp3Parameters<Fp = ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp6<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/fields/fp6_3over2.rs → r1cs-std/src/fields/fp6_3over2.rs

@@ -965,6 +965,17 @@ P: Fp6Parameters,

P::Fp2Params: Fp2Parameters<Fp = ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<Fp6<P>>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + + #[inline] fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: F,
M r1cs-std/src/groups/curves/short_weierstrass/mod.rs → r1cs-std/src/groups/curves/short_weierstrass/mod.rs

@@ -438,6 +438,24 @@ ConstraintF: PrimeField,

F: FieldGadget<P::BaseField, ConstraintF>, { #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<SWProjective<P>>, + { + let p = t.borrow().into_affine(); + Ok(Self { + x: F::alloc_constant(cs.ns(|| "x"), &p.x)?, + y: F::alloc_constant(cs.ns(|| "y"), &p.y)?, + infinity: Boolean::constant(p.infinity), + _params: PhantomData, + _engine: PhantomData, + }) + } + + #[inline] fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: FN,

@@ -661,3 +679,113 @@

Ok(x_bytes) } } + +#[cfg(test)] +#[allow(dead_code)] +pub(crate) fn test<ConstraintF, P, GG>() +where + ConstraintF: Field, + P: SWModelParameters, + GG: GroupGadget<SWProjective<P>, ConstraintF, Value = SWProjective<P>>, +{ + use crate::{boolean::AllocatedBit, prelude::*, test_constraint_system::TestConstraintSystem}; + use algebra::{test_rng, Group, UniformRand}; + use rand::Rng; + + // Incomplete addition doesn't allow us to call the group_test. + // group_test::<ConstraintF, SWProjective<P>, GG>(); + + let mut rng = test_rng(); + + let mut cs = TestConstraintSystem::<ConstraintF>::new(); + + let a = SWProjective::<P>::rand(&mut rng); + let b = SWProjective::<P>::rand(&mut rng); + let a_affine = a.into_affine(); + let b_affine = b.into_affine(); + let mut gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); + let gadget_b = GG::alloc_checked(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); + assert_eq!(gadget_a.get_value().unwrap().x, a_affine.x); + assert_eq!(gadget_a.get_value().unwrap().y, a_affine.y); + assert_eq!(gadget_b.get_value().unwrap().x, b_affine.x); + assert_eq!(gadget_b.get_value().unwrap().y, b_affine.y); + + // Check addition + let ab = a + &b; + let ab_affine = ab.into_affine(); + let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); + let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); + gadget_ba + .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) + .unwrap(); + + let ab_val = gadget_ab + .get_value() + .expect("Doubling should be successful") + .into_affine(); + assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); + + // Check doubling + let aa = Group::double(&a); + let aa_affine = aa.into_affine(); + gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); + let aa_val = gadget_a + .get_value() + .expect("Doubling should be successful") + .into_affine(); + assert_eq!( + aa_val, aa_affine, + "Gadget and native values are unequal after double." + ); + + // Check mul_bits + let scalar = P::ScalarField::rand(&mut rng); + let native_result = aa.into_affine().mul(scalar) + &b; + let native_result = native_result.into_affine(); + + let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); + // Get the scalar bits into little-endian form. + scalar.reverse(); + let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); + let result = gadget_a + .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) + .unwrap(); + let result_val = result.get_value().unwrap().into_affine(); + assert_eq!( + result_val, native_result, + "gadget & native values are diff. after scalar mul" + ); + + if !cs.is_satisfied() { + println!("{:?}", cs.which_is_unsatisfied().unwrap()); + } + + assert!(cs.is_satisfied()); + + // Constraint cost etc. + let mut cs = TestConstraintSystem::<ConstraintF>::new(); + + let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) + .unwrap() + .into(); + + let mut rng = test_rng(); + let a: SWProjective<P> = rng.gen(); + let b: SWProjective<P> = rng.gen(); + let gadget_a = GG::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); + let gadget_b = GG::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); + let alloc_cost = cs.num_constraints(); + let _ = + GG::conditionally_select(&mut cs.ns(|| "cond_select"), &bit, &gadget_a, &gadget_b).unwrap(); + let cond_select_cost = cs.num_constraints() - alloc_cost; + + let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); + let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; + + assert!(cs.is_satisfied()); + assert_eq!( + cond_select_cost, + <GG as CondSelectGadget<ConstraintF>>::cost() + ); + assert_eq!(add_cost, GG::cost_of_add()); +}
M r1cs-std/src/groups/curves/twisted_edwards/mod.rs → r1cs-std/src/groups/curves/twisted_edwards/mod.rs

@@ -492,6 +492,23 @@ ConstraintF: Field,

F: FieldGadget<P::BaseField, ConstraintF>, Self: GroupGadget<TEAffine<P>, ConstraintF>, { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<TEAffine<P>>, + { + let p = t.borrow(); + Ok(Self { + x: F::alloc_constant(cs.ns(|| "x"), &p.x)?, + y: F::alloc_constant(cs.ns(|| "y"), &p.y)?, + _params: PhantomData, + _engine: PhantomData, + }) + } + fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: FN,

@@ -1089,6 +1106,23 @@ ConstraintF: Field,

F: FieldGadget<P::BaseField, ConstraintF>, Self: GroupGadget<TEProjective<P>, ConstraintF>, { + #[inline] + fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>( + mut cs: CS, + t: T, + ) -> Result<Self, SynthesisError> + where + T: Borrow<TEProjective<P>>, + { + let p = t.borrow().into_affine(); + Ok(Self { + x: F::alloc_constant(cs.ns(|| "x"), &p.x)?, + y: F::alloc_constant(cs.ns(|| "y"), &p.y)?, + _params: PhantomData, + _engine: PhantomData, + }) + } + fn alloc<FN, T, CS: ConstraintSystem<ConstraintF>>( mut cs: CS, value_gen: FN,
M r1cs-std/src/instantiated/bls12_377/curves.rs → r1cs-std/src/instantiated/bls12_377/curves.rs

@@ -7,192 +7,17 @@

pub type G1PreparedGadget = bls12::G1PreparedGadget<Parameters>; pub type G2PreparedGadget = bls12::G2PreparedGadget<Parameters>; -#[cfg(test)] -mod test { - use rand::Rng; - - use super::{G1Gadget, G2Gadget}; - use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec}; - use algebra::{bls12_377::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve}; - use r1cs_core::ConstraintSystem; - - #[test] - fn bls12_g1_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G1Projective = rng.gen(); - let b: G1Projective = rng.gen(); - let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G1Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G1Gadget::cost_of_add()); - } - - #[test] - fn bls12_g2_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G2Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G2Gadget::cost_of_add()); - } - - #[test] - fn bls12_g1_gadget_test() { - use algebra::UniformRand; - use rand::SeedableRng; - use rand_xorshift::XorShiftRng; - let mut rng = XorShiftRng::seed_from_u64(1231275789u64); - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let a = G1Projective::rand(&mut rng); - let b = G1Projective::rand(&mut rng); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.value.unwrap(), a_affine.x); - assert_eq!(gadget_a.y.value.unwrap(), a_affine.y); - assert_eq!(gadget_b.x.value.unwrap(), b_affine.x); - assert_eq!(gadget_b.y.value.unwrap(), b_affine.y); - - // Check addition - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - - let ab_val = gadget_ab - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); - - // Check doubling - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - let aa_val = gadget_a - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!( - aa_val, aa_affine, - "Gadget and native values are unequal after double." - ); - - // Check mul_bits - let scalar = Fr::rand(&mut rng); - let native_result = aa.into_affine().mul(scalar) + &b; - let native_result = native_result.into_affine(); - - let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); - // Get the scalar bits into little-endian form. - scalar.reverse(); - let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); - let result = gadget_a - .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) - .unwrap(); - let result_val = result.get_value().unwrap().into_affine(); - assert_eq!( - result_val, native_result, - "gadget & native values are diff. after scalar mul" - ); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } - - #[test] - fn bls12_g2_gadget_test() { - let mut cs = TestConstraintSystem::<Fq>::new(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - - let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y); - assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x); - assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y); - - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x); - assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y); - - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - - assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } +#[test] +fn test() { + use algebra::curves::models::bls12::Bls12Parameters; + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as Bls12Parameters>::G1Parameters, + G1Gadget, + >(); + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as Bls12Parameters>::G2Parameters, + G2Gadget, + >(); }
M r1cs-std/src/instantiated/mnt4_298/curves.rs → r1cs-std/src/instantiated/mnt4_298/curves.rs

@@ -7,192 +7,17 @@

pub type G1PreparedGadget = mnt4::G1PreparedGadget<Parameters>; pub type G2PreparedGadget = mnt4::G2PreparedGadget<Parameters>; -#[cfg(test)] -mod test { - use rand::Rng; - - use super::{G1Gadget, G2Gadget}; - use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec}; - use algebra::{mnt4_298::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve}; - use r1cs_core::ConstraintSystem; - - #[test] - fn mnt4_298_g1_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G1Projective = rng.gen(); - let b: G1Projective = rng.gen(); - let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G1Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G1Gadget::cost_of_add()); - } - - #[test] - fn mnt4_298_g2_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G2Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G2Gadget::cost_of_add()); - } - - #[test] - fn mnt4_298_g1_gadget_test() { - use algebra::UniformRand; - use rand::SeedableRng; - use rand_xorshift::XorShiftRng; - let mut rng = XorShiftRng::seed_from_u64(1231275789u64); - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let a = G1Projective::rand(&mut rng); - let b = G1Projective::rand(&mut rng); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.value.unwrap(), a_affine.x); - assert_eq!(gadget_a.y.value.unwrap(), a_affine.y); - assert_eq!(gadget_b.x.value.unwrap(), b_affine.x); - assert_eq!(gadget_b.y.value.unwrap(), b_affine.y); - - // Check addition - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - - let ab_val = gadget_ab - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); - - // Check doubling - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - let aa_val = gadget_a - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!( - aa_val, aa_affine, - "Gadget and native values are unequal after double." - ); - - // Check mul_bits - let scalar = Fr::rand(&mut rng); - let native_result = aa.into_affine().mul(scalar) + &b; - let native_result = native_result.into_affine(); - - let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); - // Get the scalar bits into little-endian form. - scalar.reverse(); - let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); - let result = gadget_a - .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) - .unwrap(); - let result_val = result.get_value().unwrap().into_affine(); - assert_eq!( - result_val, native_result, - "gadget & native values are diff. after scalar mul" - ); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } - - #[test] - fn mnt4_298_g2_gadget_test() { - let mut cs = TestConstraintSystem::<Fq>::new(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - - let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y); - assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x); - assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y); - - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x); - assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y); - - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - - assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } +#[test] +fn test() { + use algebra::curves::models::mnt4::MNT4Parameters; + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT4Parameters>::G1Parameters, + G1Gadget, + >(); + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT4Parameters>::G2Parameters, + G2Gadget, + >(); }
M r1cs-std/src/instantiated/mnt4_753/curves.rs → r1cs-std/src/instantiated/mnt4_753/curves.rs

@@ -7,192 +7,17 @@

pub type G1PreparedGadget = mnt4::G1PreparedGadget<Parameters>; pub type G2PreparedGadget = mnt4::G2PreparedGadget<Parameters>; -#[cfg(test)] -mod test { - use rand::Rng; - - use super::{G1Gadget, G2Gadget}; - use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec}; - use algebra::{mnt4_753::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve}; - use r1cs_core::ConstraintSystem; - - #[test] - fn mnt4_753_g1_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G1Projective = rng.gen(); - let b: G1Projective = rng.gen(); - let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G1Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G1Gadget::cost_of_add()); - } - - #[test] - fn mnt4_753_g2_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G2Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G2Gadget::cost_of_add()); - } - - #[test] - fn mnt4_753_g1_gadget_test() { - use algebra::UniformRand; - use rand::SeedableRng; - use rand_xorshift::XorShiftRng; - let mut rng = XorShiftRng::seed_from_u64(1231275789u64); - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let a = G1Projective::rand(&mut rng); - let b = G1Projective::rand(&mut rng); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.value.unwrap(), a_affine.x); - assert_eq!(gadget_a.y.value.unwrap(), a_affine.y); - assert_eq!(gadget_b.x.value.unwrap(), b_affine.x); - assert_eq!(gadget_b.y.value.unwrap(), b_affine.y); - - // Check addition - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - - let ab_val = gadget_ab - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); - - // Check doubling - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - let aa_val = gadget_a - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!( - aa_val, aa_affine, - "Gadget and native values are unequal after double." - ); - - // Check mul_bits - let scalar = Fr::rand(&mut rng); - let native_result = aa.into_affine().mul(scalar) + &b; - let native_result = native_result.into_affine(); - - let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); - // Get the scalar bits into little-endian form. - scalar.reverse(); - let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); - let result = gadget_a - .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) - .unwrap(); - let result_val = result.get_value().unwrap().into_affine(); - assert_eq!( - result_val, native_result, - "gadget & native values are diff. after scalar mul" - ); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } - - #[test] - fn mnt4_753_g2_gadget_test() { - let mut cs = TestConstraintSystem::<Fq>::new(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - - let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y); - assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x); - assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y); - - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x); - assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y); - - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - - assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } +#[test] +fn test() { + use algebra::curves::models::mnt4::MNT4Parameters; + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT4Parameters>::G1Parameters, + G1Gadget, + >(); + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT4Parameters>::G2Parameters, + G2Gadget, + >(); }
M r1cs-std/src/instantiated/mnt6_298/curves.rs → r1cs-std/src/instantiated/mnt6_298/curves.rs

@@ -7,192 +7,17 @@

pub type G1PreparedGadget = mnt6::G1PreparedGadget<Parameters>; pub type G2PreparedGadget = mnt6::G2PreparedGadget<Parameters>; -#[cfg(test)] -mod test { - use rand::Rng; - - use super::{G1Gadget, G2Gadget}; - use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec}; - use algebra::{mnt6_298::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve}; - use r1cs_core::ConstraintSystem; - - #[test] - fn mnt6_298_g1_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G1Projective = rng.gen(); - let b: G1Projective = rng.gen(); - let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G1Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G1Gadget::cost_of_add()); - } - - #[test] - fn mnt6_298_g2_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G2Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G2Gadget::cost_of_add()); - } - - #[test] - fn mnt6_298_g1_gadget_test() { - use algebra::UniformRand; - use rand::SeedableRng; - use rand_xorshift::XorShiftRng; - let mut rng = XorShiftRng::seed_from_u64(1231275789u64); - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let a = G1Projective::rand(&mut rng); - let b = G1Projective::rand(&mut rng); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.value.unwrap(), a_affine.x); - assert_eq!(gadget_a.y.value.unwrap(), a_affine.y); - assert_eq!(gadget_b.x.value.unwrap(), b_affine.x); - assert_eq!(gadget_b.y.value.unwrap(), b_affine.y); - - // Check addition - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - - let ab_val = gadget_ab - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); - - // Check doubling - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - let aa_val = gadget_a - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!( - aa_val, aa_affine, - "Gadget and native values are unequal after double." - ); - - // Check mul_bits - let scalar = Fr::rand(&mut rng); - let native_result = aa.into_affine().mul(scalar) + &b; - let native_result = native_result.into_affine(); - - let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); - // Get the scalar bits into little-endian form. - scalar.reverse(); - let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); - let result = gadget_a - .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) - .unwrap(); - let result_val = result.get_value().unwrap().into_affine(); - assert_eq!( - result_val, native_result, - "gadget & native values are diff. after scalar mul" - ); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } - - #[test] - fn mnt6_298_g2_gadget_test() { - let mut cs = TestConstraintSystem::<Fq>::new(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - - let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y); - assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x); - assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y); - - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x); - assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y); - - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - - assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } +#[test] +fn test() { + use algebra::curves::models::mnt6::MNT6Parameters; + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT6Parameters>::G1Parameters, + G1Gadget, + >(); + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT6Parameters>::G2Parameters, + G2Gadget, + >(); }
M r1cs-std/src/instantiated/mnt6_753/curves.rs → r1cs-std/src/instantiated/mnt6_753/curves.rs

@@ -7,192 +7,17 @@

pub type G1PreparedGadget = mnt6::G1PreparedGadget<Parameters>; pub type G2PreparedGadget = mnt6::G2PreparedGadget<Parameters>; -#[cfg(test)] -mod test { - use rand::Rng; - - use super::{G1Gadget, G2Gadget}; - use crate::{prelude::*, test_constraint_system::TestConstraintSystem, Vec}; - use algebra::{mnt6_753::*, test_rng, AffineCurve, BitIterator, PrimeField, ProjectiveCurve}; - use r1cs_core::ConstraintSystem; - - #[test] - fn mnt6_753_g1_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G1Projective = rng.gen(); - let b: G1Projective = rng.gen(); - let gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G1Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G1Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G1Gadget::cost_of_add()); - } - - #[test] - fn mnt6_753_g2_constraint_costs() { - use crate::boolean::AllocatedBit; - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let bit = AllocatedBit::alloc(&mut cs.ns(|| "bool"), || Ok(true)) - .unwrap() - .into(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - let alloc_cost = cs.num_constraints(); - let _ = G2Gadget::conditionally_select( - &mut cs.ns(|| "cond_select"), - &bit, - &gadget_a, - &gadget_b, - ) - .unwrap(); - let cond_select_cost = cs.num_constraints() - alloc_cost; - - let _ = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let add_cost = cs.num_constraints() - cond_select_cost - alloc_cost; - - assert!(cs.is_satisfied()); - assert_eq!(cond_select_cost, <G2Gadget as CondSelectGadget<Fq>>::cost()); - assert_eq!(add_cost, G2Gadget::cost_of_add()); - } - - #[test] - fn mnt6_753_g1_gadget_test() { - use algebra::UniformRand; - use rand::SeedableRng; - use rand_xorshift::XorShiftRng; - let mut rng = XorShiftRng::seed_from_u64(1231275789u64); - - let mut cs = TestConstraintSystem::<Fq>::new(); - - let a = G1Projective::rand(&mut rng); - let b = G1Projective::rand(&mut rng); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - let mut gadget_a = G1Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G1Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.value.unwrap(), a_affine.x); - assert_eq!(gadget_a.y.value.unwrap(), a_affine.y); - assert_eq!(gadget_b.x.value.unwrap(), b_affine.x); - assert_eq!(gadget_b.y.value.unwrap(), b_affine.y); - - // Check addition - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - - let ab_val = gadget_ab - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!(ab_val, ab_affine, "Result of addition is unequal"); - - // Check doubling - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - let aa_val = gadget_a - .get_value() - .expect("Doubling should be successful") - .into_affine(); - assert_eq!( - aa_val, aa_affine, - "Gadget and native values are unequal after double." - ); - - // Check mul_bits - let scalar = Fr::rand(&mut rng); - let native_result = aa.into_affine().mul(scalar) + &b; - let native_result = native_result.into_affine(); - - let mut scalar: Vec<bool> = BitIterator::new(scalar.into_repr()).collect(); - // Get the scalar bits into little-endian form. - scalar.reverse(); - let input = Vec::<Boolean>::alloc(cs.ns(|| "Input"), || Ok(scalar)).unwrap(); - let result = gadget_a - .mul_bits(cs.ns(|| "mul_bits"), &gadget_b, input.iter()) - .unwrap(); - let result_val = result.get_value().unwrap().into_affine(); - assert_eq!( - result_val, native_result, - "gadget & native values are diff. after scalar mul" - ); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } - - #[test] - fn mnt6_753_g2_gadget_test() { - let mut cs = TestConstraintSystem::<Fq>::new(); - - let mut rng = test_rng(); - let a: G2Projective = rng.gen(); - let b: G2Projective = rng.gen(); - let a_affine = a.into_affine(); - let b_affine = b.into_affine(); - - let mut gadget_a = G2Gadget::alloc(&mut cs.ns(|| "a"), || Ok(a)).unwrap(); - let gadget_b = G2Gadget::alloc(&mut cs.ns(|| "b"), || Ok(b)).unwrap(); - assert_eq!(gadget_a.x.get_value().unwrap(), a_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), a_affine.y); - assert_eq!(gadget_b.x.get_value().unwrap(), b_affine.x); - assert_eq!(gadget_b.y.get_value().unwrap(), b_affine.y); - - let ab = a + &b; - let ab_affine = ab.into_affine(); - let gadget_ab = gadget_a.add(&mut cs.ns(|| "ab"), &gadget_b).unwrap(); - let gadget_ba = gadget_b.add(&mut cs.ns(|| "ba"), &gadget_a).unwrap(); - gadget_ba - .enforce_equal(&mut cs.ns(|| "b + a == a + b?"), &gadget_ab) - .unwrap(); - assert_eq!(gadget_ab.x.get_value().unwrap(), ab_affine.x); - assert_eq!(gadget_ab.y.get_value().unwrap(), ab_affine.y); - - let aa = a.double(); - let aa_affine = aa.into_affine(); - gadget_a.double_in_place(&mut cs.ns(|| "2a")).unwrap(); - - assert_eq!(gadget_a.x.get_value().unwrap(), aa_affine.x); - assert_eq!(gadget_a.y.get_value().unwrap(), aa_affine.y); - - if !cs.is_satisfied() { - println!("{:?}", cs.which_is_unsatisfied().unwrap()); - } - - assert!(cs.is_satisfied()); - } +#[test] +fn test() { + use algebra::curves::models::mnt6::MNT6Parameters; + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT6Parameters>::G1Parameters, + G1Gadget, + >(); + crate::groups::curves::short_weierstrass::test::< + _, + <Parameters as MNT6Parameters>::G2Parameters, + G2Gadget, + >(); }
M r1cs-std/src/test_constraint_counter.rs → r1cs-std/src/test_constraint_counter.rs

@@ -4,16 +4,16 @@ use r1cs_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};

/// Constraint counter for testing purposes. pub struct ConstraintCounter { - pub num_inputs: usize, - pub num_aux: usize, + pub num_inputs: usize, + pub num_aux: usize, pub num_constraints: usize, } impl ConstraintCounter { pub fn new() -> Self { Self { - num_aux: 0, - num_inputs: 0, + num_aux: 0, + num_inputs: 0, num_constraints: 0, } }