mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-11 00:11:29 +01:00
Switch to tracing-based constraint debugging
This commit is contained in:
@@ -38,6 +38,7 @@ r1cs-std = { path = "../r1cs-std", optional = true, default-features = false }
|
||||
rand = { version = "0.7", default-features = false }
|
||||
rayon = { version = "1.0", optional = true }
|
||||
derivative = { version = "2.0", features = ["use_core"] }
|
||||
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
|
||||
|
||||
[features]
|
||||
default = ["std", "r1cs"]
|
||||
|
||||
@@ -24,6 +24,7 @@ impl<F: PrimeField> CommitmentGadget<blake2s::Commitment, F> for CommGadget {
|
||||
type ParametersVar = ParametersVar;
|
||||
type RandomnessVar = RandomnessVar<F>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(input, r))]
|
||||
fn commit(
|
||||
_: &Self::ParametersVar,
|
||||
input: &[UInt8<F>],
|
||||
@@ -43,6 +44,7 @@ impl<F: PrimeField> CommitmentGadget<blake2s::Commitment, F> for CommGadget {
|
||||
}
|
||||
|
||||
impl<ConstraintF: Field> AllocVar<(), ConstraintF> for ParametersVar {
|
||||
#[tracing::instrument(target = "r1cs", skip(_cs, _f))]
|
||||
fn new_variable<T: Borrow<()>>(
|
||||
_cs: impl Into<Namespace<ConstraintF>>,
|
||||
_f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -53,6 +55,7 @@ impl<ConstraintF: Field> AllocVar<(), ConstraintF> for ParametersVar {
|
||||
}
|
||||
|
||||
impl<ConstraintF: PrimeField> AllocVar<[u8; 32], ConstraintF> for RandomnessVar<ConstraintF> {
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<[u8; 32]>>(
|
||||
cs: impl Into<Namespace<ConstraintF>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -111,7 +114,7 @@ mod test {
|
||||
|
||||
let parameters_var =
|
||||
<TestCOMMGadget as CommitmentGadget<TestCOMM, Fr>>::ParametersVar::new_witness(
|
||||
cs.ns("gadget_parameters"),
|
||||
r1cs_core::ns!(cs, "gadget_parameters"),
|
||||
|| Ok(¶meters),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -53,6 +53,7 @@ where
|
||||
type ParametersVar = ParametersVar<C, GG>;
|
||||
type RandomnessVar = RandomnessVar<ConstraintF<C>>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(parameters, r))]
|
||||
fn commit(
|
||||
parameters: &Self::ParametersVar,
|
||||
input: &[UInt8<ConstraintF<C>>],
|
||||
@@ -183,13 +184,13 @@ mod test {
|
||||
|
||||
let randomness_var =
|
||||
<TestCOMMGadget as CommitmentGadget<TestCOMM, Fq>>::RandomnessVar::new_witness(
|
||||
cs.ns("gadget_randomness"),
|
||||
r1cs_core::ns!(cs, "gadget_randomness"),
|
||||
|| Ok(&randomness),
|
||||
)
|
||||
.unwrap();
|
||||
let parameters_var =
|
||||
<TestCOMMGadget as CommitmentGadget<TestCOMM, Fq>>::ParametersVar::new_witness(
|
||||
cs.ns("gadget_parameters"),
|
||||
r1cs_core::ns!(cs, "gadget_parameters"),
|
||||
|| Ok(¶meters),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -51,6 +51,7 @@ where
|
||||
type OutputVar = AffineVar<P, F>;
|
||||
type ParametersVar = ParametersVar<P, W>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(parameters, input))]
|
||||
fn evaluate(
|
||||
parameters: &Self::ParametersVar,
|
||||
input: &[UInt8<ConstraintF<P>>],
|
||||
@@ -91,6 +92,7 @@ where
|
||||
P: TEModelParameters,
|
||||
W: Window,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(_cs, f))]
|
||||
fn new_variable<T: Borrow<Parameters<P>>>(
|
||||
_cs: impl Into<Namespace<ConstraintF<P>>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -158,7 +160,7 @@ mod test {
|
||||
|
||||
let parameters_var =
|
||||
<TestCRHGadget as FixedLengthCRHGadget<TestCRH, Fr>>::ParametersVar::new_witness(
|
||||
cs.ns("parameters_var"),
|
||||
r1cs_core::ns!(cs, "parameters_var"),
|
||||
|| Ok(¶meters),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -87,6 +87,7 @@ where
|
||||
type OutputVar = IG::OutputVar;
|
||||
type ParametersVar = ped_constraints::CRHParametersVar<C, GG>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(parameters, input))]
|
||||
fn evaluate(
|
||||
parameters: &Self::ParametersVar,
|
||||
input: &[UInt8<ConstraintF<C>>],
|
||||
|
||||
@@ -45,6 +45,7 @@ where
|
||||
type OutputVar = GG;
|
||||
type ParametersVar = CRHParametersVar<C, GG>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(parameters, input))]
|
||||
fn evaluate(
|
||||
parameters: &Self::ParametersVar,
|
||||
input: &[UInt8<ConstraintF<C>>],
|
||||
@@ -78,6 +79,7 @@ where
|
||||
GG: CurveVar<C, ConstraintF<C>>,
|
||||
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(_cs, f))]
|
||||
fn new_variable<T: Borrow<Parameters<C>>>(
|
||||
_cs: impl Into<Namespace<ConstraintF<C>>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -138,7 +140,8 @@ mod test {
|
||||
let primitive_result = TestCRH::evaluate(¶meters, &input).unwrap();
|
||||
|
||||
let parameters_var =
|
||||
CRHParametersVar::new_constant(cs.ns("CRH Parameters"), ¶meters).unwrap();
|
||||
CRHParametersVar::new_constant(r1cs_core::ns!(cs, "CRH Parameters"), ¶meters)
|
||||
.unwrap();
|
||||
|
||||
let result_var = TestCRHGadget::evaluate(¶meters_var, &input_var).unwrap();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ where
|
||||
CRHGadget: FixedLengthCRHGadget<P::H, ConstraintF>,
|
||||
<CRHGadget::OutputVar as R1CSVar<ConstraintF>>::Value: PartialEq,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(self, parameters, root, leaf))]
|
||||
pub fn check_membership(
|
||||
&self,
|
||||
parameters: &CRHGadget::ParametersVar,
|
||||
@@ -39,7 +40,7 @@ where
|
||||
let cs = leaf_hash.cs().or(root.cs()).unwrap();
|
||||
|
||||
// Check if leaf is one of the bottom-most siblings.
|
||||
let leaf_is_left = Boolean::new_witness(cs.ns("leaf_is_left"), || {
|
||||
let leaf_is_left = Boolean::new_witness(r1cs_core::ns!(cs, "leaf_is_left"), || {
|
||||
Ok(leaf_hash.value()?.eq(&self.path[0].0.value()?))
|
||||
})?;
|
||||
|
||||
@@ -48,24 +49,20 @@ where
|
||||
|
||||
// Check levels between leaf level and root.
|
||||
let mut previous_hash = leaf_hash;
|
||||
let mut i = 0;
|
||||
for &(ref left_hash, ref right_hash) in &self.path {
|
||||
// Check if the previous_hash matches the correct current hash.
|
||||
let previous_is_left = Boolean::new_witness(cs.ns("previous_is_left"), || {
|
||||
Ok(previous_hash.value()?.eq(&left_hash.value()?))
|
||||
})?;
|
||||
let previous_is_left =
|
||||
Boolean::new_witness(r1cs_core::ns!(cs, "previous_is_left"), || {
|
||||
Ok(previous_hash.value()?.eq(&left_hash.value()?))
|
||||
})?;
|
||||
|
||||
let ns = cs.ns(format!(
|
||||
"enforcing that inner hash is correct at i-th level{}",
|
||||
i
|
||||
));
|
||||
let ns = r1cs_core::ns!(cs, "enforcing that inner hash is correct");
|
||||
let equality_cmp = previous_is_left.select(left_hash, right_hash)?;
|
||||
result = result.and(&previous_hash.is_eq(&equality_cmp)?)?;
|
||||
drop(ns);
|
||||
|
||||
previous_hash =
|
||||
hash_inner_node::<P::H, CRHGadget, ConstraintF>(parameters, left_hash, right_hash)?;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
result.and(&root.is_eq(&previous_hash)?)
|
||||
@@ -106,8 +103,16 @@ where
|
||||
f().and_then(|val| {
|
||||
let mut path = Vec::new();
|
||||
for &(ref l, ref r) in val.borrow().path.iter() {
|
||||
let l_hash = HGadget::OutputVar::new_variable(cs.ns("l_child"), || Ok(l), mode)?;
|
||||
let r_hash = HGadget::OutputVar::new_variable(cs.ns("r_child"), || Ok(r), mode)?;
|
||||
let l_hash = HGadget::OutputVar::new_variable(
|
||||
r1cs_core::ns!(cs, "l_child"),
|
||||
|| Ok(l),
|
||||
mode,
|
||||
)?;
|
||||
let r_hash = HGadget::OutputVar::new_variable(
|
||||
r1cs_core::ns!(cs, "r_child"),
|
||||
|| Ok(r),
|
||||
mode,
|
||||
)?;
|
||||
path.push((l_hash, r_hash));
|
||||
}
|
||||
Ok(PathVar { path })
|
||||
@@ -157,15 +162,14 @@ mod test {
|
||||
let crh_parameters = H::setup(&mut rng).unwrap();
|
||||
let tree = JubJubMerkleTree::new(crh_parameters.clone(), leaves).unwrap();
|
||||
let root = tree.root();
|
||||
let mut satisfied = true;
|
||||
let cs = ConstraintSystem::<Fq>::new_ref();
|
||||
for (i, leaf) in leaves.iter().enumerate() {
|
||||
let cs = ConstraintSystem::<Fq>::new_ref();
|
||||
let proof = tree.generate_proof(i, &leaf).unwrap();
|
||||
assert!(proof.verify(&crh_parameters, &root, &leaf).unwrap());
|
||||
|
||||
// Allocate Merkle Tree Root
|
||||
let root = <HG as FixedLengthCRHGadget<H, _>>::OutputVar::new_witness(
|
||||
cs.ns("new_digest"),
|
||||
r1cs_core::ns!(cs, "new_digest"),
|
||||
|| {
|
||||
if use_bad_root {
|
||||
Ok(<H as FixedLengthCRH>::Output::default())
|
||||
@@ -181,7 +185,7 @@ mod test {
|
||||
|
||||
// Allocate Parameters for CRH
|
||||
let crh_parameters = <HG as FixedLengthCRHGadget<H, Fq>>::ParametersVar::new_constant(
|
||||
cs.ns("new_parameter"),
|
||||
r1cs_core::ns!(cs, "new_parameter"),
|
||||
&crh_parameters,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -200,7 +204,9 @@ mod test {
|
||||
println!("constraints from leaf: {}", constraints_from_leaf);
|
||||
|
||||
// Allocate Merkle Tree Path
|
||||
let cw = PathVar::<_, HG, _>::new_witness(cs.ns("new_witness"), || Ok(&proof)).unwrap();
|
||||
let cw =
|
||||
PathVar::<_, HG, _>::new_witness(r1cs_core::ns!(cs, "new_witness"), || Ok(&proof))
|
||||
.unwrap();
|
||||
for (i, (l, r)) in cw.path.iter().enumerate() {
|
||||
assert_eq!(l.value().unwrap(), proof.path[i].0);
|
||||
assert_eq!(r.value().unwrap(), proof.path[i].1);
|
||||
@@ -216,13 +222,6 @@ mod test {
|
||||
.unwrap()
|
||||
.enforce_equal(&Boolean::TRUE)
|
||||
.unwrap();
|
||||
if !cs.is_satisfied().unwrap() {
|
||||
satisfied = false;
|
||||
println!(
|
||||
"Unsatisfied constraint: {}",
|
||||
cs.which_is_unsatisfied().unwrap()
|
||||
);
|
||||
}
|
||||
let setup_constraints = constraints_from_leaf
|
||||
+ constraints_from_digest
|
||||
+ constraints_from_parameters
|
||||
@@ -233,7 +232,7 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
assert!(satisfied);
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -15,6 +15,7 @@ pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
||||
/// subgroup checks.
|
||||
///
|
||||
/// The default implementation doesn't omit these checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_proof_unchecked<T: Borrow<N::Proof>>(
|
||||
cs: impl Into<Namespace<ConstraintF>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -27,6 +28,7 @@ pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
||||
/// without performing subgroup checks.
|
||||
///
|
||||
/// The default implementation doesn't omit these checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_verification_key_unchecked<T: Borrow<N::VerificationParameters>>(
|
||||
cs: impl Into<Namespace<ConstraintF>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
|
||||
@@ -32,6 +32,7 @@ pub struct VerifyingKeyVar<E: PairingEngine, P: PairingVar<E>> {
|
||||
}
|
||||
|
||||
impl<E: PairingEngine, P: PairingVar<E>> VerifyingKeyVar<E, P> {
|
||||
#[tracing::instrument(target = "r1cs", skip(self))]
|
||||
pub fn prepare(&self) -> Result<PreparedVerifyingKeyVar<E, P>, SynthesisError> {
|
||||
let g_alpha_pc = P::prepare_g1(&self.g_alpha_g1)?;
|
||||
let h_beta_pc = P::prepare_g2(&self.h_beta_g2)?;
|
||||
@@ -89,6 +90,7 @@ where
|
||||
|
||||
/// Allocates `N::Proof` in `cs` without performing
|
||||
/// subgroup checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_proof_unchecked<T: Borrow<Proof<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -99,17 +101,17 @@ where
|
||||
f().and_then(|proof| {
|
||||
let proof = proof.borrow();
|
||||
let a = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.a"),
|
||||
r1cs_core::ns!(cs, "Proof.a"),
|
||||
|| Ok(proof.a.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let b = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.b"),
|
||||
r1cs_core::ns!(cs, "Proof.b"),
|
||||
|| Ok(proof.b.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let c = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.c"),
|
||||
r1cs_core::ns!(cs, "Proof.c"),
|
||||
|| Ok(proof.c.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
@@ -119,6 +121,7 @@ where
|
||||
|
||||
/// Allocates `N::Proof` in `cs` without performing
|
||||
/// subgroup checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_verification_key_unchecked<T: Borrow<VerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -129,27 +132,27 @@ where
|
||||
f().and_then(|vk| {
|
||||
let vk = vk.borrow();
|
||||
let g_alpha_g1 = P::G1Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("g_alpha"),
|
||||
r1cs_core::ns!(cs, "g_alpha"),
|
||||
|| Ok(vk.g_alpha_g1.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let h_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("h"),
|
||||
r1cs_core::ns!(cs, "h"),
|
||||
|| Ok(vk.h_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let h_beta_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("h_beta"),
|
||||
r1cs_core::ns!(cs, "h_beta"),
|
||||
|| Ok(vk.h_beta_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let g_gamma_g1 = P::G1Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("g_gamma"),
|
||||
r1cs_core::ns!(cs, "g_gamma"),
|
||||
|| Ok(vk.g_gamma_g1.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let h_gamma_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("h_gamma"),
|
||||
r1cs_core::ns!(cs, "h_gamma"),
|
||||
|| Ok(vk.h_gamma_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
@@ -159,7 +162,7 @@ where
|
||||
.iter()
|
||||
.map(|g| {
|
||||
P::G1Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("g"),
|
||||
r1cs_core::ns!(cs, "g"),
|
||||
|| Ok(g.into_projective()),
|
||||
mode,
|
||||
)
|
||||
@@ -176,6 +179,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(vk, input, proof))]
|
||||
fn verify<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
vk: &Self::VerificationKeyVar,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
@@ -185,6 +189,7 @@ where
|
||||
<Self as NIZKVerifierGadget<Gm17<E, C, V>, E::Fq>>::verify_prepared(&pvk, input, proof)
|
||||
}
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(pvk, input, proof))]
|
||||
fn verify_prepared<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
pvk: &Self::PreparedVerificationKeyVar,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
@@ -263,6 +268,7 @@ where
|
||||
P::G1PreparedVar: AllocVar<E::G1Prepared, E::Fq>,
|
||||
P::G2PreparedVar: AllocVar<E::G2Prepared, E::Fq>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<PreparedVerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -273,21 +279,34 @@ where
|
||||
|
||||
f().and_then(|pvk| {
|
||||
let pvk = pvk.borrow();
|
||||
let g_alpha = P::G1Var::new_variable(cs.ns("g_alpha"), || Ok(pvk.g_alpha), mode)?;
|
||||
let h_beta = P::G2Var::new_variable(cs.ns("h_beta"), || Ok(pvk.h_beta), mode)?;
|
||||
let g_alpha =
|
||||
P::G1Var::new_variable(r1cs_core::ns!(cs, "g_alpha"), || Ok(pvk.g_alpha), mode)?;
|
||||
let h_beta =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "h_beta"), || Ok(pvk.h_beta), mode)?;
|
||||
let g_alpha_pc = P::G1PreparedVar::new_variable(
|
||||
cs.ns("g_alpha_pc"),
|
||||
r1cs_core::ns!(cs, "g_alpha_pc"),
|
||||
|| Ok(pvk.g_alpha.into()),
|
||||
mode,
|
||||
)?;
|
||||
let h_beta_pc =
|
||||
P::G2PreparedVar::new_variable(cs.ns("h_beta_pc"), || Ok(pvk.h_beta.into()), mode)?;
|
||||
let g_gamma_pc =
|
||||
P::G1PreparedVar::new_variable(cs.ns("g_gamma_pc"), || Ok(&pvk.g_gamma_pc), mode)?;
|
||||
let h_gamma_pc =
|
||||
P::G2PreparedVar::new_variable(cs.ns("h_gamma_pc"), || Ok(&pvk.h_gamma_pc), mode)?;
|
||||
let h_pc = P::G2PreparedVar::new_variable(cs.ns("h_pc"), || Ok(&pvk.h_pc), mode)?;
|
||||
let query = Vec::new_variable(cs.ns("query"), || Ok(pvk.query.clone()), mode)?;
|
||||
let h_beta_pc = P::G2PreparedVar::new_variable(
|
||||
r1cs_core::ns!(cs, "h_beta_pc"),
|
||||
|| Ok(pvk.h_beta.into()),
|
||||
mode,
|
||||
)?;
|
||||
let g_gamma_pc = P::G1PreparedVar::new_variable(
|
||||
r1cs_core::ns!(cs, "g_gamma_pc"),
|
||||
|| Ok(&pvk.g_gamma_pc),
|
||||
mode,
|
||||
)?;
|
||||
let h_gamma_pc = P::G2PreparedVar::new_variable(
|
||||
r1cs_core::ns!(cs, "h_gamma_pc"),
|
||||
|| Ok(&pvk.h_gamma_pc),
|
||||
mode,
|
||||
)?;
|
||||
let h_pc =
|
||||
P::G2PreparedVar::new_variable(r1cs_core::ns!(cs, "h_pc"), || Ok(&pvk.h_pc), mode)?;
|
||||
let query =
|
||||
Vec::new_variable(r1cs_core::ns!(cs, "query"), || Ok(pvk.query.clone()), mode)?;
|
||||
|
||||
Ok(Self {
|
||||
g_alpha,
|
||||
@@ -309,6 +328,7 @@ where
|
||||
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<VerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -319,12 +339,17 @@ where
|
||||
|
||||
f().and_then(|vk| {
|
||||
let vk = vk.borrow();
|
||||
let g_alpha_g1 = P::G1Var::new_variable(cs.ns("g_alpha"), || Ok(vk.g_alpha_g1), mode)?;
|
||||
let h_g2 = P::G2Var::new_variable(cs.ns("h"), || Ok(vk.h_g2), mode)?;
|
||||
let h_beta_g2 = P::G2Var::new_variable(cs.ns("h_beta"), || Ok(vk.h_beta_g2), mode)?;
|
||||
let g_gamma_g1 = P::G1Var::new_variable(cs.ns("g_gamma"), || Ok(&vk.g_gamma_g1), mode)?;
|
||||
let h_gamma_g2 = P::G2Var::new_variable(cs.ns("h_gamma"), || Ok(&vk.h_gamma_g2), mode)?;
|
||||
let query = Vec::new_variable(cs.ns("query"), || Ok(vk.query.clone()), mode)?;
|
||||
let g_alpha_g1 =
|
||||
P::G1Var::new_variable(r1cs_core::ns!(cs, "g_alpha"), || Ok(vk.g_alpha_g1), mode)?;
|
||||
let h_g2 = P::G2Var::new_variable(r1cs_core::ns!(cs, "h"), || Ok(vk.h_g2), mode)?;
|
||||
let h_beta_g2 =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "h_beta"), || Ok(vk.h_beta_g2), mode)?;
|
||||
let g_gamma_g1 =
|
||||
P::G1Var::new_variable(r1cs_core::ns!(cs, "g_gamma"), || Ok(&vk.g_gamma_g1), mode)?;
|
||||
let h_gamma_g2 =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "h_gamma"), || Ok(&vk.h_gamma_g2), mode)?;
|
||||
let query =
|
||||
Vec::new_variable(r1cs_core::ns!(cs, "query"), || Ok(vk.query.clone()), mode)?;
|
||||
Ok(Self {
|
||||
h_g2,
|
||||
g_alpha_g1,
|
||||
@@ -344,6 +369,7 @@ where
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[inline]
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<Proof<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -354,9 +380,9 @@ where
|
||||
|
||||
f().and_then(|proof| {
|
||||
let Proof { a, b, c } = proof.borrow().clone();
|
||||
let a = P::G1Var::new_variable(cs.ns("a"), || Ok(a), mode)?;
|
||||
let b = P::G2Var::new_variable(cs.ns("b"), || Ok(b), mode)?;
|
||||
let c = P::G1Var::new_variable(cs.ns("c"), || Ok(c), mode)?;
|
||||
let a = P::G1Var::new_variable(cs.clone(), || Ok(a), mode)?;
|
||||
let b = P::G2Var::new_variable(cs.clone(), || Ok(b), mode)?;
|
||||
let c = P::G1Var::new_variable(r1cs_core::ns!(cs, "c"), || Ok(c), mode)?;
|
||||
Ok(Self { a, b, c })
|
||||
})
|
||||
}
|
||||
@@ -428,8 +454,7 @@ mod test {
|
||||
let result_var = cs.new_witness_variable(|| {
|
||||
result_val.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
cs.enforce_named_constraint(
|
||||
format!("Enforce constraint {}", i),
|
||||
cs.enforce_constraint(
|
||||
lc!() + input_1_var,
|
||||
lc!() + input_2_var,
|
||||
lc!() + result_var,
|
||||
@@ -480,10 +505,10 @@ mod test {
|
||||
let mut input_gadgets = Vec::new();
|
||||
|
||||
{
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
for input in inputs.into_iter() {
|
||||
let input_bits: Vec<_> = BitIteratorLE::new(input.into_repr()).collect();
|
||||
let input_bits =
|
||||
Vec::<Boolean<Fq>>::new_input(cs.ns(format!("Input {}", i)), || {
|
||||
Vec::<Boolean<Fq>>::new_input(r1cs_core::ns!(cs, "Input"), || {
|
||||
Ok(input_bits)
|
||||
})
|
||||
.unwrap();
|
||||
@@ -491,9 +516,11 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar::new_input(cs.ns("Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let vk_gadget =
|
||||
TestVkVar::new_input(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let proof_gadget =
|
||||
TestProofVar::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget as NIZKVerifierGadget<TestProofSystem, Fq>>::verify(
|
||||
&vk_gadget,
|
||||
@@ -573,8 +600,7 @@ mod test_recursive {
|
||||
let result_var = cs.new_witness_variable(|| {
|
||||
result_val.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
cs.enforce_named_constraint(
|
||||
format!("Enforce constraint {}", i),
|
||||
cs.enforce_constraint(
|
||||
lc!() + input_1_var,
|
||||
lc!() + input_2_var,
|
||||
lc!() + result_var,
|
||||
@@ -624,7 +650,8 @@ mod test_recursive {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Allocate this byte array as input packed into field elements.
|
||||
let input_bytes = UInt8::new_input_vec(cs.ns("Input"), &input_bytes[..])?;
|
||||
let input_bytes =
|
||||
UInt8::new_input_vec(r1cs_core::ns!(cs, "Input"), &input_bytes[..])?;
|
||||
// 40 byte
|
||||
let element_size = <MNT4FqParameters as FftParameters>::BigInt::NUM_LIMBS * 8;
|
||||
input_gadgets = input_bytes
|
||||
@@ -638,9 +665,10 @@ mod test_recursive {
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar1::new_witness(cs.ns("Vk"), || Ok(¶ms.vk))?;
|
||||
let vk_gadget = TestVkVar1::new_witness(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk))?;
|
||||
let proof_gadget =
|
||||
TestProofVar1::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar1::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
<TestVerifierGadget1 as NIZKVerifierGadget<TestProofSystem1, MNT6Fq>>::verify(
|
||||
&vk_gadget,
|
||||
&input_gadgets,
|
||||
@@ -714,9 +742,9 @@ mod test_recursive {
|
||||
{
|
||||
let bigint_size = <MNT4FqParameters as FftParameters>::BigInt::NUM_LIMBS * 64;
|
||||
let mut input_bits = Vec::new();
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
for input in inputs.into_iter() {
|
||||
let input_gadget =
|
||||
FpVar::new_input(cs.ns(format!("Input {}", i)), || Ok(input)).unwrap();
|
||||
FpVar::new_input(r1cs_core::ns!(cs, "Input"), || Ok(input)).unwrap();
|
||||
let mut fp_bits = input_gadget.to_bits_le().unwrap();
|
||||
|
||||
// Use 320 bits per element.
|
||||
@@ -741,9 +769,11 @@ mod test_recursive {
|
||||
// assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar2::new_input(cs.ns("Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let vk_gadget =
|
||||
TestVkVar2::new_input(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let proof_gadget =
|
||||
TestProofVar2::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar2::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget2 as NIZKVerifierGadget<TestProofSystem2, MNT4Fq>>::verify(
|
||||
&vk_gadget,
|
||||
|
||||
@@ -83,6 +83,7 @@ where
|
||||
|
||||
/// Allocates `N::Proof` in `cs` without performing
|
||||
/// subgroup checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_proof_unchecked<T: Borrow<Proof<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -93,17 +94,17 @@ where
|
||||
f().and_then(|proof| {
|
||||
let proof = proof.borrow();
|
||||
let a = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.a"),
|
||||
r1cs_core::ns!(cs, "Proof.a"),
|
||||
|| Ok(proof.a.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let b = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.b"),
|
||||
r1cs_core::ns!(cs, "Proof.b"),
|
||||
|| Ok(proof.b.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let c = CurveVar::new_variable_omit_prime_order_check(
|
||||
cs.ns("Proof.c"),
|
||||
r1cs_core::ns!(cs, "Proof.c"),
|
||||
|| Ok(proof.c.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
@@ -113,6 +114,7 @@ where
|
||||
|
||||
/// Allocates `N::Proof` in `cs` without performing
|
||||
/// subgroup checks.
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_verification_key_unchecked<T: Borrow<VerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -123,22 +125,22 @@ where
|
||||
f().and_then(|vk| {
|
||||
let vk = vk.borrow();
|
||||
let alpha_g1 = P::G1Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("alpha_g1"),
|
||||
r1cs_core::ns!(cs, "alpha_g1"),
|
||||
|| Ok(vk.alpha_g1.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let beta_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("beta_g2"),
|
||||
r1cs_core::ns!(cs, "beta_g2"),
|
||||
|| Ok(vk.beta_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let gamma_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("gamma_g2"),
|
||||
r1cs_core::ns!(cs, "gamma_g2"),
|
||||
|| Ok(vk.gamma_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
let delta_g2 = P::G2Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("delta_g2"),
|
||||
r1cs_core::ns!(cs, "delta_g2"),
|
||||
|| Ok(vk.delta_g2.into_projective()),
|
||||
mode,
|
||||
)?;
|
||||
@@ -148,7 +150,7 @@ where
|
||||
.iter()
|
||||
.map(|g| {
|
||||
P::G1Var::new_variable_omit_prime_order_check(
|
||||
cs.ns("g"),
|
||||
r1cs_core::ns!(cs, "g"),
|
||||
|| Ok(g.into_projective()),
|
||||
mode,
|
||||
)
|
||||
@@ -164,6 +166,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(vk, input, proof))]
|
||||
fn verify<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
vk: &Self::VerificationKeyVar,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
@@ -173,6 +176,7 @@ where
|
||||
<Self as NIZKVerifierGadget<Groth16<E, C, V>, E::Fq>>::verify_prepared(&pvk, input, proof)
|
||||
}
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(pvk, public_inputs, proof))]
|
||||
fn verify_prepared<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
pvk: &Self::PreparedVerificationKeyVar,
|
||||
public_inputs: impl IntoIterator<Item = &'a T>,
|
||||
@@ -222,6 +226,7 @@ where
|
||||
E: PairingEngine,
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<PreparedVerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -233,25 +238,28 @@ where
|
||||
f().and_then(|pvk| {
|
||||
let pvk = pvk.borrow();
|
||||
let alpha_g1_beta_g2 = P::GTVar::new_variable(
|
||||
cs.ns("alpha_g1_beta_g2"),
|
||||
r1cs_core::ns!(cs, "alpha_g1_beta_g2"),
|
||||
|| Ok(pvk.alpha_g1_beta_g2),
|
||||
mode,
|
||||
)?;
|
||||
|
||||
let gamma_g2_neg_pc = P::G2PreparedVar::new_variable(
|
||||
cs.ns("gamma_g2_neg_pc"),
|
||||
r1cs_core::ns!(cs, "gamma_g2_neg_pc"),
|
||||
|| Ok(pvk.gamma_g2_neg_pc.clone()),
|
||||
mode,
|
||||
)?;
|
||||
|
||||
let delta_g2_neg_pc = P::G2PreparedVar::new_variable(
|
||||
cs.ns("delta_g2_neg_pc"),
|
||||
r1cs_core::ns!(cs, "delta_g2_neg_pc"),
|
||||
|| Ok(pvk.delta_g2_neg_pc.clone()),
|
||||
mode,
|
||||
)?;
|
||||
|
||||
let gamma_abc_g1 =
|
||||
Vec::new_variable(cs.ns("gamma_abc_g1"), || Ok(pvk.gamma_abc_g1.clone()), mode)?;
|
||||
let gamma_abc_g1 = Vec::new_variable(
|
||||
r1cs_core::ns!(cs, "gamma_abc_g1"),
|
||||
|| Ok(pvk.gamma_abc_g1.clone()),
|
||||
mode,
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
alpha_g1_beta_g2,
|
||||
@@ -269,6 +277,7 @@ where
|
||||
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<VerifyingKey<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -285,10 +294,14 @@ where
|
||||
delta_g2,
|
||||
gamma_abc_g1,
|
||||
} = vk.borrow().clone();
|
||||
let alpha_g1 = P::G1Var::new_variable(cs.ns("alpha_g1"), || Ok(alpha_g1), mode)?;
|
||||
let beta_g2 = P::G2Var::new_variable(cs.ns("beta_g2"), || Ok(beta_g2), mode)?;
|
||||
let gamma_g2 = P::G2Var::new_variable(cs.ns("gamma_g2"), || Ok(gamma_g2), mode)?;
|
||||
let delta_g2 = P::G2Var::new_variable(cs.ns("delta_g2"), || Ok(delta_g2), mode)?;
|
||||
let alpha_g1 =
|
||||
P::G1Var::new_variable(r1cs_core::ns!(cs, "alpha_g1"), || Ok(alpha_g1), mode)?;
|
||||
let beta_g2 =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "beta_g2"), || Ok(beta_g2), mode)?;
|
||||
let gamma_g2 =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "gamma_g2"), || Ok(gamma_g2), mode)?;
|
||||
let delta_g2 =
|
||||
P::G2Var::new_variable(r1cs_core::ns!(cs, "delta_g2"), || Ok(delta_g2), mode)?;
|
||||
|
||||
let gamma_abc_g1 = Vec::new_variable(cs.clone(), || Ok(gamma_abc_g1), mode)?;
|
||||
Ok(Self {
|
||||
@@ -307,6 +320,7 @@ where
|
||||
E: PairingEngine,
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<Proof<E>>>(
|
||||
cs: impl Into<Namespace<E::Fq>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -317,9 +331,9 @@ where
|
||||
|
||||
f().and_then(|proof| {
|
||||
let Proof { a, b, c } = proof.borrow().clone();
|
||||
let a = P::G1Var::new_variable(cs.ns("a"), || Ok(a), mode)?;
|
||||
let b = P::G2Var::new_variable(cs.ns("b"), || Ok(b), mode)?;
|
||||
let c = P::G1Var::new_variable(cs.ns("c"), || Ok(c), mode)?;
|
||||
let a = P::G1Var::new_variable(r1cs_core::ns!(cs, "a"), || Ok(a), mode)?;
|
||||
let b = P::G2Var::new_variable(r1cs_core::ns!(cs, "b"), || Ok(b), mode)?;
|
||||
let c = P::G1Var::new_variable(r1cs_core::ns!(cs, "c"), || Ok(c), mode)?;
|
||||
Ok(Self { a, b, c })
|
||||
})
|
||||
}
|
||||
@@ -331,6 +345,7 @@ where
|
||||
P: PairingVar<E>,
|
||||
{
|
||||
#[inline]
|
||||
#[tracing::instrument(target = "r1cs", skip(self))]
|
||||
fn to_bytes(&self) -> Result<Vec<UInt8<E::Fq>>, SynthesisError> {
|
||||
let mut bytes = Vec::new();
|
||||
bytes.extend_from_slice(&self.alpha_g1.to_bytes()?);
|
||||
@@ -389,8 +404,7 @@ mod test {
|
||||
let result_var = cs.new_witness_variable(|| {
|
||||
result_val.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
cs.enforce_named_constraint(
|
||||
format!("Enforce constraint {}", i),
|
||||
cs.enforce_constraint(
|
||||
lc!() + input_1_var,
|
||||
lc!() + input_2_var,
|
||||
lc!() + result_var,
|
||||
@@ -441,11 +455,11 @@ mod test {
|
||||
let mut input_gadgets = Vec::new();
|
||||
|
||||
{
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
for input in inputs.into_iter() {
|
||||
let input_bits = BitIteratorLE::new(input.into_repr()).collect::<Vec<_>>();
|
||||
|
||||
let input_bits =
|
||||
Vec::<Boolean<Fq>>::new_input(cs.ns(format!("Input {}", i)), || {
|
||||
Vec::<Boolean<Fq>>::new_input(r1cs_core::ns!(cs, "Input"), || {
|
||||
Ok(input_bits)
|
||||
})
|
||||
.unwrap();
|
||||
@@ -453,9 +467,11 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar::new_input(cs.ns("Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let vk_gadget =
|
||||
TestVkVar::new_input(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let proof_gadget =
|
||||
TestProofVar::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget as NIZKVerifierGadget<TestProofSystem, Fq>>::verify(
|
||||
&vk_gadget,
|
||||
@@ -534,8 +550,7 @@ mod test_recursive {
|
||||
let result_var = cs.new_witness_variable(|| {
|
||||
result_val.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?;
|
||||
cs.enforce_named_constraint(
|
||||
format!("Enforce constraint {}", i),
|
||||
cs.enforce_constraint(
|
||||
lc!() + input_1_var,
|
||||
lc!() + input_2_var,
|
||||
lc!() + result_var,
|
||||
@@ -585,7 +600,8 @@ mod test_recursive {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Allocate this byte array as input packed into field elements.
|
||||
let input_bytes = UInt8::new_input_vec(cs.ns("Input"), &input_bytes[..])?;
|
||||
let input_bytes =
|
||||
UInt8::new_input_vec(r1cs_core::ns!(cs, "Input"), &input_bytes[..])?;
|
||||
// 40 byte
|
||||
let element_size = <MNT4FqParameters as FftParameters>::BigInt::NUM_LIMBS * 8;
|
||||
input_gadgets = input_bytes
|
||||
@@ -599,9 +615,10 @@ mod test_recursive {
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar1::new_witness(cs.ns("Vk"), || Ok(¶ms.vk))?;
|
||||
let vk_gadget = TestVkVar1::new_witness(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk))?;
|
||||
let proof_gadget =
|
||||
TestProofVar1::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar1::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
<TestVerifierGadget1 as NIZKVerifierGadget<TestProofSystem1, MNT6Fq>>::verify(
|
||||
&vk_gadget,
|
||||
&input_gadgets,
|
||||
@@ -675,9 +692,9 @@ mod test_recursive {
|
||||
{
|
||||
let bigint_size = <MNT4FqParameters as FftParameters>::BigInt::NUM_LIMBS * 64;
|
||||
let mut input_bits = Vec::new();
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
for input in inputs.into_iter() {
|
||||
let input_gadget =
|
||||
FpVar::new_input(cs.ns(format!("Input {}", i)), || Ok(input)).unwrap();
|
||||
FpVar::new_input(r1cs_core::ns!(cs, "Input"), || Ok(input)).unwrap();
|
||||
let mut fp_bits = input_gadget.to_bits_le().unwrap();
|
||||
|
||||
// Use 320 bits per element.
|
||||
@@ -702,9 +719,11 @@ mod test_recursive {
|
||||
// assert!(!verify_proof(&pvk, &proof, &[a]).unwrap());
|
||||
}
|
||||
|
||||
let vk_gadget = TestVkVar2::new_input(cs.ns("Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let vk_gadget =
|
||||
TestVkVar2::new_input(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk)).unwrap();
|
||||
let proof_gadget =
|
||||
TestProofVar2::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
TestProofVar2::new_witness(r1cs_core::ns!(cs, "Proof"), || Ok(proof.clone()))
|
||||
.unwrap();
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget2 as NIZKVerifierGadget<TestProofSystem2, MNT4Fq>>::verify(
|
||||
&vk_gadget,
|
||||
|
||||
@@ -91,12 +91,7 @@ mod test {
|
||||
let sum = cs.new_input_variable(|| Ok(self.sum.unwrap()))?;
|
||||
let witness = cs.new_witness_variable(|| Ok(self.w.unwrap()))?;
|
||||
|
||||
cs.enforce_named_constraint(
|
||||
"enforce sum",
|
||||
lc!() + sum,
|
||||
lc!() + Variable::One,
|
||||
lc!() + input + witness,
|
||||
)?;
|
||||
cs.enforce_constraint(lc!() + sum, lc!() + Variable::One, lc!() + input + witness)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,12 +294,14 @@ pub struct Blake2sGadget;
|
||||
pub struct OutputVar<ConstraintF: PrimeField>(pub Vec<UInt8<ConstraintF>>);
|
||||
|
||||
impl<ConstraintF: PrimeField> EqGadget<ConstraintF> for OutputVar<ConstraintF> {
|
||||
#[tracing::instrument(target = "r1cs")]
|
||||
fn is_eq(&self, other: &Self) -> Result<Boolean<ConstraintF>, SynthesisError> {
|
||||
self.0.is_eq(&other.0)
|
||||
}
|
||||
|
||||
/// If `should_enforce == true`, enforce that `self` and `other` are equal; else,
|
||||
/// enforce a vacuously true statement.
|
||||
#[tracing::instrument(target = "r1cs")]
|
||||
fn conditional_enforce_equal(
|
||||
&self,
|
||||
other: &Self,
|
||||
@@ -310,6 +312,7 @@ impl<ConstraintF: PrimeField> EqGadget<ConstraintF> for OutputVar<ConstraintF> {
|
||||
|
||||
/// If `should_enforce == true`, enforce that `self` and `other` are not equal; else,
|
||||
/// enforce a vacuously true statement.
|
||||
#[tracing::instrument(target = "r1cs")]
|
||||
fn conditional_enforce_not_equal(
|
||||
&self,
|
||||
other: &Self,
|
||||
@@ -329,6 +332,7 @@ impl<ConstraintF: PrimeField> ToBytesGadget<ConstraintF> for OutputVar<Constrain
|
||||
}
|
||||
|
||||
impl<ConstraintF: PrimeField> AllocVar<[u8; 32], ConstraintF> for OutputVar<ConstraintF> {
|
||||
#[tracing::instrument(target = "r1cs", skip(cs, f))]
|
||||
fn new_variable<T: Borrow<[u8; 32]>>(
|
||||
cs: impl Into<Namespace<ConstraintF>>,
|
||||
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
@@ -362,10 +366,14 @@ impl<F: PrimeField> R1CSVar<F> for OutputVar<F> {
|
||||
impl<F: PrimeField> PRFGadget<Blake2s, F> for Blake2sGadget {
|
||||
type OutputVar = OutputVar<F>;
|
||||
|
||||
fn new_seed(cs: ConstraintSystemRef<F>, seed: &[u8; 32]) -> Vec<UInt8<F>> {
|
||||
UInt8::new_witness_vec(cs.ns("New Blake2s seed"), seed).unwrap()
|
||||
#[tracing::instrument(target = "r1cs", skip(cs))]
|
||||
fn new_seed(cs: impl Into<Namespace<F>>, seed: &[u8; 32]) -> Vec<UInt8<F>> {
|
||||
let ns = cs.into();
|
||||
let cs = ns.cs();
|
||||
UInt8::new_witness_vec(r1cs_core::ns!(cs, "New Blake2s seed"), seed).unwrap()
|
||||
}
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(seed, input))]
|
||||
fn evaluate(seed: &[UInt8<F>], input: &[UInt8<F>]) -> Result<Self::OutputVar, SynthesisError> {
|
||||
assert_eq!(seed.len(), 32);
|
||||
let input: Vec<_> = seed
|
||||
@@ -398,7 +406,7 @@ mod test {
|
||||
fn test_blake2s_constraints() {
|
||||
let cs = ConstraintSystem::<Fr>::new_ref();
|
||||
let input_bits: Vec<_> = (0..512)
|
||||
.map(|i| Boolean::new_witness(cs.ns(format!("input bit {}", i)), || Ok(true)).unwrap())
|
||||
.map(|_| Boolean::new_witness(r1cs_core::ns!(cs, "input bit"), || Ok(true)).unwrap())
|
||||
.collect();
|
||||
evaluate_blake2s(&input_bits).unwrap();
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
@@ -420,10 +428,11 @@ mod test {
|
||||
rng.fill(&mut input);
|
||||
|
||||
let seed_var = Blake2sGadget::new_seed(cs.clone(), &seed);
|
||||
let input_var = UInt8::new_witness_vec(cs.ns("declare_input"), &input).unwrap();
|
||||
let input_var =
|
||||
UInt8::new_witness_vec(r1cs_core::ns!(cs, "declare_input"), &input).unwrap();
|
||||
let out = B2SPRF::evaluate(&seed, &input).unwrap();
|
||||
let actual_out_var = <Blake2sGadget as PRFGadget<_, Fr>>::OutputVar::new_witness(
|
||||
cs.ns("declare_output"),
|
||||
r1cs_core::ns!(cs, "declare_output"),
|
||||
|| Ok(out),
|
||||
)
|
||||
.unwrap();
|
||||
@@ -449,8 +458,8 @@ mod test {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
let input_bits: Vec<_> = (0..512)
|
||||
.map(|_| Boolean::constant(rng.gen()))
|
||||
.chain((0..512).map(|i| {
|
||||
Boolean::new_witness(cs.ns(format!("input bit {}", i)), || Ok(true)).unwrap()
|
||||
.chain((0..512).map(|_| {
|
||||
Boolean::new_witness(r1cs_core::ns!(cs, "input bit"), || Ok(true)).unwrap()
|
||||
}))
|
||||
.collect();
|
||||
evaluate_blake2s(&input_bits).unwrap();
|
||||
@@ -488,9 +497,9 @@ mod test {
|
||||
|
||||
let mut input_bits = vec![];
|
||||
|
||||
for (byte_i, input_byte) in data.into_iter().enumerate() {
|
||||
for input_byte in data.into_iter() {
|
||||
for bit_i in 0..8 {
|
||||
let cs = cs.ns(format!("input bit {} {}", byte_i, bit_i));
|
||||
let cs = r1cs_core::ns!(cs, "input bit");
|
||||
|
||||
input_bits.push(
|
||||
Boolean::new_witness(cs, || Ok((input_byte >> bit_i) & 1u8 == 1u8))
|
||||
|
||||
@@ -2,7 +2,7 @@ use algebra_core::Field;
|
||||
use core::fmt::Debug;
|
||||
|
||||
use crate::{prf::PRF, Vec};
|
||||
use r1cs_core::{ConstraintSystemRef, SynthesisError};
|
||||
use r1cs_core::{Namespace, SynthesisError};
|
||||
|
||||
use r1cs_std::prelude::*;
|
||||
|
||||
@@ -14,7 +14,7 @@ pub trait PRFGadget<P: PRF, F: Field> {
|
||||
+ Clone
|
||||
+ Debug;
|
||||
|
||||
fn new_seed(cs: ConstraintSystemRef<F>, seed: &P::Seed) -> Vec<UInt8<F>>;
|
||||
fn new_seed(cs: impl Into<Namespace<F>>, seed: &P::Seed) -> Vec<UInt8<F>>;
|
||||
|
||||
fn evaluate(seed: &[UInt8<F>], input: &[UInt8<F>]) -> Result<Self::OutputVar, SynthesisError>;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ where
|
||||
type ParametersVar = ParametersVar<C, GC>;
|
||||
type PublicKeyVar = PublicKeyVar<C, GC>;
|
||||
|
||||
#[tracing::instrument(target = "r1cs", skip(parameters, public_key, randomness))]
|
||||
fn randomize(
|
||||
parameters: &Self::ParametersVar,
|
||||
public_key: &Self::PublicKeyVar,
|
||||
|
||||
Reference in New Issue
Block a user