diff --git a/crypto-primitives/src/commitment/blake2s/constraints.rs b/crypto-primitives/src/commitment/blake2s/constraints.rs index 660a2fd..1fbeff5 100644 --- a/crypto-primitives/src/commitment/blake2s/constraints.rs +++ b/crypto-primitives/src/commitment/blake2s/constraints.rs @@ -48,6 +48,16 @@ impl CommitmentGadget } impl AllocGadget<(), ConstraintF> for Blake2sParametersGadget { + fn alloc_constant>( + cs: CS, + val: T, + ) -> Result + where + T: Borrow<()>, + { + Self::alloc(cs, || Ok(val)) + } + fn alloc>(_: CS, _: F) -> Result where F: FnOnce() -> Result, @@ -69,6 +79,22 @@ impl AllocGadget<(), ConstraintF> for Blake2sParametersGadge } impl AllocGadget<[u8; 32], ConstraintF> for Blake2sRandomnessGadget { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + 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>( cs: CS, diff --git a/crypto-primitives/src/commitment/pedersen/constraints.rs b/crypto-primitives/src/commitment/pedersen/constraints.rs index ffa54b9..f408b9c 100644 --- a/crypto-primitives/src/commitment/pedersen/constraints.rs +++ b/crypto-primitives/src/commitment/pedersen/constraints.rs @@ -98,16 +98,14 @@ where W: PedersenWindow, ConstraintF: PrimeField, { - fn alloc>( + fn alloc_constant>( _cs: CS, - value_gen: F, + val: T, ) -> Result where - F: FnOnce() -> Result, T: Borrow>, { - let temp = value_gen()?; - let parameters = temp.borrow().clone(); + let parameters = val.borrow().clone(); Ok(PedersenCommitmentGadgetParameters { params: parameters, @@ -117,6 +115,18 @@ where }) } + fn alloc>( + cs: CS, + value_gen: F, + ) -> Result + where + F: FnOnce() -> Result, + T: Borrow>, + { + let temp = value_gen()?; + Self::alloc_constant(cs, temp) + } + fn alloc_input>( _cs: CS, value_gen: F, @@ -142,6 +152,21 @@ where G: Group, ConstraintF: PrimeField, { + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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>( cs: CS, value_gen: F, diff --git a/crypto-primitives/src/crh/bowe_hopwood/constraints.rs b/crypto-primitives/src/crh/bowe_hopwood/constraints.rs index b16f1a3..5afc543 100644 --- a/crypto-primitives/src/crh/bowe_hopwood/constraints.rs +++ b/crypto-primitives/src/crh/bowe_hopwood/constraints.rs @@ -89,15 +89,14 @@ impl, ConstraintF> for BoweHopwoodPedersenCRHGadgetParameters { - fn alloc>( + fn alloc_constant>( _cs: CS, - value_gen: F, + val: T, ) -> Result where - F: FnOnce() -> Result, T: Borrow>, { - let params = value_gen()?.borrow().clone(); + let params = val.borrow().clone(); Ok(BoweHopwoodPedersenCRHGadgetParameters { params, _group_g: PhantomData, @@ -106,6 +105,18 @@ impl>( + cs: CS, + value_gen: F, + ) -> Result + where + F: FnOnce() -> Result, + T: Borrow>, + { + let params = value_gen()?.borrow().clone(); + Self::alloc_constant(cs, params) + } + fn alloc_input>( _cs: CS, value_gen: F, diff --git a/crypto-primitives/src/crh/pedersen/constraints.rs b/crypto-primitives/src/crh/pedersen/constraints.rs index 6048adc..bb3f6a2 100644 --- a/crypto-primitives/src/crh/pedersen/constraints.rs +++ b/crypto-primitives/src/crh/pedersen/constraints.rs @@ -80,15 +80,14 @@ impl, ConstraintF> for PedersenCRHGadgetParameters { - fn alloc>( + fn alloc_constant>( _cs: CS, - value_gen: F, + val: T, ) -> Result where - F: FnOnce() -> Result, T: Borrow>, { - let params = value_gen()?.borrow().clone(); + let params = val.borrow().clone(); Ok(PedersenCRHGadgetParameters { params, _group_g: PhantomData, @@ -97,6 +96,18 @@ impl>( + cs: CS, + value_gen: F, + ) -> Result + where + F: FnOnce() -> Result, + T: Borrow>, + { + let params = value_gen()?.borrow().clone(); + Self::alloc_constant(cs, params) + } + fn alloc_input>( _cs: CS, value_gen: F, diff --git a/crypto-primitives/src/merkle_tree/constraints.rs b/crypto-primitives/src/merkle_tree/constraints.rs index 5136c40..58b242e 100644 --- a/crypto-primitives/src/merkle_tree/constraints.rs +++ b/crypto-primitives/src/merkle_tree/constraints.rs @@ -128,6 +128,28 @@ where HGadget: FixedLengthCRHGadget, ConstraintF: Field, { + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, value_gen: F, diff --git a/crypto-primitives/src/nizk/gm17/constraints.rs b/crypto-primitives/src/nizk/gm17/constraints.rs index 1604be0..6e9b523 100644 --- a/crypto-primitives/src/nizk/gm17/constraints.rs +++ b/crypto-primitives/src/nizk/gm17/constraints.rs @@ -202,6 +202,54 @@ where ConstraintF: Field, P: PairingGadget, { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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::>() + .into_iter() + .collect::>()?; + Ok(Self { + h_g2, + g_alpha_g1, + h_beta_g2, + g_gamma_g1, + h_gamma_g2, + query, + }) + } + #[inline] fn alloc>( mut cs: CS, @@ -312,6 +360,21 @@ where ConstraintF: Field, P: PairingGadget, { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, diff --git a/crypto-primitives/src/nizk/groth16/constraints.rs b/crypto-primitives/src/nizk/groth16/constraints.rs index 71907dd..9b8144c 100644 --- a/crypto-primitives/src/nizk/groth16/constraints.rs +++ b/crypto-primitives/src/nizk/groth16/constraints.rs @@ -173,6 +173,50 @@ where ConstraintF: Field, P: PairingGadget, { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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::>() + .into_iter() + .collect::>()?; + Ok(Self { + alpha_g1, + beta_g2, + gamma_g2, + delta_g2, + gamma_abc_g1, + }) + } + #[inline] fn alloc>( mut cs: CS, @@ -276,6 +320,21 @@ where ConstraintF: Field, P: PairingGadget, { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, diff --git a/crypto-primitives/src/prf/blake2s/constraints.rs b/crypto-primitives/src/prf/blake2s/constraints.rs index cd1d3b2..68576eb 100644 --- a/crypto-primitives/src/prf/blake2s/constraints.rs +++ b/crypto-primitives/src/prf/blake2s/constraints.rs @@ -450,6 +450,22 @@ impl ToBytesGadget for Blake2sOutputGadget } impl AllocGadget<[u8; 32], ConstraintF> for Blake2sOutputGadget { + #[inline] + fn alloc_constant>( + mut cs: CS, + val: T, + ) -> Result + 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>( cs: CS, diff --git a/crypto-primitives/src/signature/schnorr/constraints.rs b/crypto-primitives/src/signature/schnorr/constraints.rs index f9d8ad8..f3395dc 100644 --- a/crypto-primitives/src/signature/schnorr/constraints.rs +++ b/crypto-primitives/src/signature/schnorr/constraints.rs @@ -96,6 +96,21 @@ where GG: GroupGadget, D: Digest, { + fn alloc_constant>( + cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + let generator = GG::alloc_constant(cs, val.borrow().generator)?; + Ok(Self { + generator, + _engine: PhantomData, + _group: PhantomData, + }) + } + fn alloc>(cs: CS, f: F) -> Result where F: FnOnce() -> Result, @@ -133,6 +148,21 @@ where ConstraintF: Field, GG: GroupGadget, { + fn alloc_constant>( + cs: CS, + val: T, + ) -> Result + where + T: Borrow>, + { + let pub_key = GG::alloc_constant(cs, val.borrow())?; + Ok(Self { + pub_key, + _engine: PhantomData, + _group: PhantomData, + }) + } + fn alloc>(cs: CS, f: F) -> Result where F: FnOnce() -> Result, diff --git a/r1cs-std/src/alloc.rs b/r1cs-std/src/alloc.rs index 139820e..47a43f9 100644 --- a/r1cs-std/src/alloc.rs +++ b/r1cs-std/src/alloc.rs @@ -8,6 +8,13 @@ where Self: Sized, V: ?Sized, { + fn alloc_constant>( + cs: CS, + t: T, + ) -> Result + where + T: Borrow; + fn alloc>(cs: CS, f: F) -> Result where F: FnOnce() -> Result, @@ -47,6 +54,21 @@ where impl> AllocGadget<[I], ConstraintF> for Vec { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + 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>( mut cs: CS, f: F, diff --git a/r1cs-std/src/bits/boolean.rs b/r1cs-std/src/bits/boolean.rs index b696055..23a205f 100644 --- a/r1cs-std/src/bits/boolean.rs +++ b/r1cs-std/src/bits/boolean.rs @@ -235,6 +235,16 @@ impl PartialEq for AllocatedBit { impl Eq for AllocatedBit {} impl AllocGadget for AllocatedBit { + fn alloc_constant>( + _cs: CS, + _t: T, + ) -> Result + where + T: Borrow, + { + unimplemented!(); + } + fn alloc>( mut cs: CS, value_gen: F, @@ -715,6 +725,16 @@ impl From for Boolean { } impl AllocGadget for Boolean { + fn alloc_constant>( + _cs: CS, + t: T, + ) -> Result + where + T: Borrow, + { + Ok(Boolean::constant(*t.borrow())) + } + fn alloc>( cs: CS, value_gen: F, diff --git a/r1cs-std/src/bits/uint64.rs b/r1cs-std/src/bits/uint64.rs index babc1f1..67698d8 100644 --- a/r1cs-std/src/bits/uint64.rs +++ b/r1cs-std/src/bits/uint64.rs @@ -277,6 +277,16 @@ impl UInt64 { } impl AllocGadget for UInt64 { + fn alloc_constant>( + _cs: CS, + t: T, + ) -> Result + where + T: Borrow, + { + Ok(UInt64::constant(*t.borrow())) + } + fn alloc>( mut cs: CS, value_gen: F, diff --git a/r1cs-std/src/bits/uint8.rs b/r1cs-std/src/bits/uint8.rs index 6cb67e0..3783cca 100644 --- a/r1cs-std/src/bits/uint8.rs +++ b/r1cs-std/src/bits/uint8.rs @@ -214,6 +214,16 @@ impl ConditionalEqGadget for UInt8 { impl EqGadget for UInt8 {} impl AllocGadget for UInt8 { + fn alloc_constant>( + _cs: CS, + t: T, + ) -> Result + where + T: Borrow, + { + Ok(UInt8::constant(*t.borrow())) + } + fn alloc>( mut cs: CS, value_gen: F, diff --git a/r1cs-std/src/fields/fp/mod.rs b/r1cs-std/src/fields/fp/mod.rs index 2f8c937..6648864 100644 --- a/r1cs-std/src/fields/fp/mod.rs +++ b/r1cs-std/src/fields/fp/mod.rs @@ -584,6 +584,18 @@ impl Clone for FpGadget { } impl AllocGadget for FpGadget { + #[inline] + fn alloc_constant>(_cs: CS, t: T) -> Result + where + T: Borrow, + { + let value = t.borrow().clone(); + Ok(Self { + value: Some(value), + variable: LinearCombination::from((value, CS::one())).into(), + }) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp12.rs b/r1cs-std/src/fields/fp12.rs index 7131676..4ead2b5 100644 --- a/r1cs-std/src/fields/fp12.rs +++ b/r1cs-std/src/fields/fp12.rs @@ -834,6 +834,17 @@ where P: Fp12Parameters, ::Fp2Params: Fp2Parameters, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp2.rs b/r1cs-std/src/fields/fp2.rs index 5dbc369..476ecc5 100644 --- a/r1cs-std/src/fields/fp2.rs +++ b/r1cs-std/src/fields/fp2.rs @@ -611,6 +611,17 @@ impl, ConstraintF: PrimeField> impl, ConstraintF: PrimeField> AllocGadget, ConstraintF> for Fp2Gadget { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp3.rs b/r1cs-std/src/fields/fp3.rs index 39c6006..6ab72c7 100644 --- a/r1cs-std/src/fields/fp3.rs +++ b/r1cs-std/src/fields/fp3.rs @@ -867,6 +867,17 @@ impl, ConstraintF: PrimeField + SquareRootFie impl, ConstraintF: PrimeField + SquareRootField> AllocGadget, ConstraintF> for Fp3Gadget { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp4.rs b/r1cs-std/src/fields/fp4.rs index 8c05cb7..91c0da6 100644 --- a/r1cs-std/src/fields/fp4.rs +++ b/r1cs-std/src/fields/fp4.rs @@ -673,6 +673,17 @@ where P: Fp4Parameters, P::Fp2Params: Fp2Parameters, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp6_2over3.rs b/r1cs-std/src/fields/fp6_2over3.rs index 29ec485..5c4a79a 100644 --- a/r1cs-std/src/fields/fp6_2over3.rs +++ b/r1cs-std/src/fields/fp6_2over3.rs @@ -664,6 +664,17 @@ where P: Fp6Parameters, P::Fp3Params: Fp3Parameters, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/fields/fp6_3over2.rs b/r1cs-std/src/fields/fp6_3over2.rs index a7f3b49..f4b25e7 100644 --- a/r1cs-std/src/fields/fp6_3over2.rs +++ b/r1cs-std/src/fields/fp6_3over2.rs @@ -964,6 +964,17 @@ where P: Fp6Parameters, P::Fp2Params: Fp2Parameters, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + Self::zero(cs.ns(|| "zero"))?.add_constant(cs.ns(|| "add constant"), t.borrow()) + } + #[inline] fn alloc>( mut cs: CS, diff --git a/r1cs-std/src/groups/curves/short_weierstrass/mod.rs b/r1cs-std/src/groups/curves/short_weierstrass/mod.rs index 59f998a..4c2e725 100644 --- a/r1cs-std/src/groups/curves/short_weierstrass/mod.rs +++ b/r1cs-std/src/groups/curves/short_weierstrass/mod.rs @@ -437,6 +437,24 @@ where ConstraintF: PrimeField, F: FieldGadget, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, diff --git a/r1cs-std/src/groups/curves/twisted_edwards/mod.rs b/r1cs-std/src/groups/curves/twisted_edwards/mod.rs index ed071b8..e926ddf 100644 --- a/r1cs-std/src/groups/curves/twisted_edwards/mod.rs +++ b/r1cs-std/src/groups/curves/twisted_edwards/mod.rs @@ -492,6 +492,23 @@ mod affine_impl { F: FieldGadget, Self: GroupGadget, ConstraintF>, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, value_gen: FN, @@ -1089,6 +1106,23 @@ mod projective_impl { F: FieldGadget, Self: GroupGadget, ConstraintF>, { + #[inline] + fn alloc_constant>( + mut cs: CS, + t: T, + ) -> Result + where + T: Borrow>, + { + 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>( mut cs: CS, value_gen: FN,