Skip to content

Commit

Permalink
rand in hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
jkwoods committed Oct 15, 2024
1 parent a251b59 commit 3c9a6e6
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
30 changes: 28 additions & 2 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub struct NovaAugmentedCircuitInputs<E: Engine> {
z0: Vec<E::Base>,
zi: Option<Vec<E::Base>>,
U: Option<RelaxedR1CSInstance<E>>,
ri: Option<E::Base>,
r_next: E::Base,
u: Option<R1CSInstance<E>>,
T: Option<Commitment<E>>,
}
Expand All @@ -65,6 +67,8 @@ impl<E: Engine> NovaAugmentedCircuitInputs<E> {
z0: Vec<E::Base>,
zi: Option<Vec<E::Base>>,
U: Option<RelaxedR1CSInstance<E>>,
ri: Option<E::Base>,
r_next: E::Base,
u: Option<R1CSInstance<E>>,
T: Option<Commitment<E>>,
) -> Self {
Expand All @@ -74,6 +78,8 @@ impl<E: Engine> NovaAugmentedCircuitInputs<E> {
z0,
zi,
U,
ri,
r_next,
u,
T,
}
Expand Down Expand Up @@ -117,6 +123,8 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
Vec<AllocatedNum<E::Base>>,
Vec<AllocatedNum<E::Base>>,
AllocatedRelaxedR1CSInstance<E>,
AllocatedNum<E::Base>,
AllocatedNum<E::Base>,
AllocatedR1CSInstance<E>,
AllocatedPoint<E>,
),
Expand Down Expand Up @@ -158,6 +166,14 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
self.params.n_limbs,
)?;

// Allocate ri
let r_i = AllocatedNum::alloc(cs.namespace(|| "ri"), || {
Ok(self.inputs.get()?.ri.unwrap_or(E::Base::ZERO))
})?;

// Allocate r_i+1
let r_next = AllocatedNum::alloc(cs.namespace(|| "r_i+1"), || Ok(self.inputs.get()?.r_next))?;

// Allocate the instance to be folded in
let u = AllocatedR1CSInstance::alloc(
cs.namespace(|| "allocate instance u to fold"),
Expand All @@ -174,7 +190,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
)?;
T.check_on_curve(cs.namespace(|| "check T on curve"))?;

Ok((params, i, z_0, z_i, U, u, T))
Ok((params, i, z_0, z_i, U, r_i, r_next, u, T))
}

/// Synthesizes base case and returns the new relaxed `R1CSInstance`
Expand Down Expand Up @@ -212,6 +228,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
z_0: &[AllocatedNum<E::Base>],
z_i: &[AllocatedNum<E::Base>],
U: &AllocatedRelaxedR1CSInstance<E>,
r_i: &AllocatedNum<E::Base>,
u: &AllocatedR1CSInstance<E>,
T: &AllocatedPoint<E>,
arity: usize,
Expand All @@ -230,6 +247,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
ro.absorb(e);
}
U.absorb_in_ro(cs.namespace(|| "absorb U"), &mut ro)?;
ro.absorb(r_i);

let hash_bits = ro.squeeze(cs.namespace(|| "Input hash"), NUM_HASH_BITS)?;
let hash = le_bits_to_num(cs.namespace(|| "bits to hash"), &hash_bits)?;
Expand Down Expand Up @@ -263,7 +281,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
let arity = self.step_circuit.arity();

// Allocate all witnesses
let (params, i, z_0, z_i, U, u, T) =
let (params, i, z_0, z_i, U, r_i, r_next, u, T) =
self.alloc_witness(cs.namespace(|| "allocate the circuit witness"), arity)?;

// Compute variable indicating if this is the base case
Expand All @@ -282,6 +300,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
&z_0,
&z_i,
&U,
&r_i,
&u,
&T,
arity,
Expand Down Expand Up @@ -347,6 +366,7 @@ impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
ro.absorb(e);
}
Unew.absorb_in_ro(cs.namespace(|| "absorb U_new"), &mut ro)?;
ro.absorb(&r_next);
let hash_bits = ro.squeeze(cs.namespace(|| "output hash bits"), NUM_HASH_BITS)?;
let hash = le_bits_to_num(cs.namespace(|| "convert hash to num"), &hash_bits)?;

Expand Down Expand Up @@ -410,6 +430,7 @@ mod tests {

// Execute the base case for the primary
let zero1 = <<E2 as Engine>::Base as Field>::ZERO;
let ri_1 = <<E2 as Engine>::Base as Field>::ZERO;
let mut cs1 = SatisfyingAssignment::<E1>::new();
let inputs1: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
scalar_as_base::<E1>(zero1), // pass zero for testing
Expand All @@ -418,6 +439,8 @@ mod tests {
None,
None,
None,
ri_1,
None,
None,
);
let circuit1: NovaAugmentedCircuit<'_, E2, TrivialCircuit<<E2 as Engine>::Base>> =
Expand All @@ -429,13 +452,16 @@ mod tests {

// Execute the base case for the secondary
let zero2 = <<E1 as Engine>::Base as Field>::ZERO;
let ri_2 = <<E1 as Engine>::Base as Field>::ZERO;
let mut cs2 = SatisfyingAssignment::<E2>::new();
let inputs2: NovaAugmentedCircuitInputs<E1> = NovaAugmentedCircuitInputs::new(
scalar_as_base::<E2>(zero2), // pass zero for testing
zero2,
vec![zero2],
None,
None,
None,
ri_2,
Some(inst1),
None,
);
Expand Down
2 changes: 1 addition & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ pub(crate) const NUM_CHALLENGE_BITS: usize = 128;
pub(crate) const NUM_HASH_BITS: usize = 250;
pub(crate) const BN_LIMB_WIDTH: usize = 64;
pub(crate) const BN_N_LIMBS: usize = 4;
pub(crate) const NUM_FE_WITHOUT_IO_FOR_CRHF: usize = 17;
pub(crate) const NUM_FE_WITHOUT_IO_FOR_CRHF: usize = 18;
pub(crate) const NUM_FE_FOR_RO: usize = 9;
pub(crate) const NUM_FE_FOR_RO_RELAXED: usize = 19;
37 changes: 37 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use nifs::NIFS;
use r1cs::{
CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
};
use rand_core::OsRng;
use serde::{Deserialize, Serialize};
use traits::{
circuit::StepCircuit, commitment::CommitmentEngineTrait, snark::RelaxedR1CSSNARKTrait,
Expand Down Expand Up @@ -246,8 +247,10 @@ where
z0_secondary: Vec<E2::Scalar>,
r_W_primary: RelaxedR1CSWitness<E1>,
r_U_primary: RelaxedR1CSInstance<E1>,
ri_primary: E1::Scalar,
r_W_secondary: RelaxedR1CSWitness<E2>,
r_U_secondary: RelaxedR1CSInstance<E2>,
ri_secondary: E2::Scalar,
l_w_secondary: R1CSWitness<E2>,
l_u_secondary: R1CSInstance<E2>,
i: usize,
Expand Down Expand Up @@ -297,6 +300,9 @@ where
return Err(NovaError::InvalidInitialInputLength);
}

let ri_primary = E1::Scalar::random(&mut OsRng);
let ri_secondary = E2::Scalar::random(&mut OsRng);

// base case for the primary
let mut cs_primary = SatisfyingAssignment::<E1>::new();
let inputs_primary: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
Expand All @@ -306,6 +312,8 @@ where
None,
None,
None,
ri_primary, // "r next"
None,
None,
);

Expand All @@ -327,6 +335,8 @@ where
z0_secondary.to_vec(),
None,
None,
None,
ri_secondary, // "r next"
Some(u_primary.clone()),
None,
);
Expand Down Expand Up @@ -374,8 +384,10 @@ where
z0_secondary: z0_secondary.to_vec(),
r_W_primary,
r_U_primary,
ri_primary,
r_W_secondary,
r_U_secondary,
ri_secondary,
l_w_secondary,
l_u_secondary,
i: 0,
Expand Down Expand Up @@ -411,13 +423,17 @@ where
&self.l_w_secondary,
)?;

let r_next_primary = E1::Scalar::random(&mut OsRng);

let mut cs_primary = SatisfyingAssignment::<E1>::new();
let inputs_primary: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
scalar_as_base::<E1>(pp.digest()),
E1::Scalar::from(self.i as u64),
self.z0_primary.to_vec(),
Some(self.zi_primary.clone()),
Some(self.r_U_secondary.clone()),
Some(self.ri_primary),
r_next_primary,
Some(self.l_u_secondary.clone()),
Some(nifs_secondary.comm_T),
);
Expand Down Expand Up @@ -445,13 +461,17 @@ where
&l_w_primary,
)?;

let r_next_secondary = E2::Scalar::random(&mut OsRng);

let mut cs_secondary = SatisfyingAssignment::<E2>::new();
let inputs_secondary: NovaAugmentedCircuitInputs<E1> = NovaAugmentedCircuitInputs::new(
pp.digest(),
E2::Scalar::from(self.i as u64),
self.z0_secondary.to_vec(),
Some(self.zi_secondary.clone()),
Some(self.r_U_primary.clone()),
Some(self.ri_secondary),
r_next_secondary,
Some(l_u_primary),
Some(nifs_primary.comm_T),
);
Expand Down Expand Up @@ -489,6 +509,9 @@ where
self.r_U_secondary = r_U_secondary;
self.r_W_secondary = r_W_secondary;

self.ri_primary = r_next_primary;
self.ri_secondary = r_next_secondary;

Ok(())
}

Expand Down Expand Up @@ -612,6 +635,7 @@ where
hasher.absorb(*e);
}
self.r_U_secondary.absorb_in_ro(&mut hasher);
hasher.absorb(self.ri_primary);

let mut hasher2 = <E1 as Engine>::RO::new(
pp.ro_consts_primary.clone(),
Expand All @@ -626,6 +650,7 @@ where
hasher2.absorb(*e);
}
self.r_U_primary.absorb_in_ro(&mut hasher2);
hasher2.absorb(self.ri_secondary);

(
hasher.squeeze(NUM_HASH_BITS),
Expand Down Expand Up @@ -728,6 +753,7 @@ where
hasher.absorb(*e);
}
self.r_U_secondary.absorb_in_ro(&mut hasher);
hasher.absorb(self.ri_primary);

let mut hasher2 = <E1 as Engine>::RO::new(
pp.ro_consts_primary.clone(),
Expand All @@ -742,6 +768,7 @@ where
hasher2.absorb(*e);
}
self.r_U_primary.absorb_in_ro(&mut hasher2);
hasher2.absorb(self.ri_secondary);

(
hasher.squeeze(NUM_HASH_BITS),
Expand Down Expand Up @@ -869,9 +896,11 @@ where
S2: RelaxedR1CSSNARKTrait<E2>,
{
r_U_primary: RelaxedR1CSInstance<E1>,
ri_primary: E1::Scalar,
r_W_snark_primary: S1,

r_U_secondary: RelaxedR1CSInstance<E2>,
ri_secondary: E2::Scalar,
l_u_secondary: R1CSInstance<E2>,
nifs_secondary: NIFS<E2>,
f_W_snark_secondary: S2,
Expand Down Expand Up @@ -1008,9 +1037,11 @@ where

Ok(Self {
r_U_primary: recursive_snark.r_U_primary.clone(),
ri_primary: recursive_snark.ri_primary.clone(),

Check failure on line 1040 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `<E1 as Engine>::Scalar` which implements the `Copy` trait
r_W_snark_primary: r_W_snark_primary?,

r_U_secondary: recursive_snark.r_U_secondary.clone(),
ri_secondary: recursive_snark.ri_secondary.clone(),

Check failure on line 1044 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `<E2 as Engine>::Scalar` which implements the `Copy` trait
l_u_secondary: recursive_snark.l_u_secondary.clone(),
nifs_secondary,
f_W_snark_secondary: f_W_snark_secondary?,
Expand Down Expand Up @@ -1077,9 +1108,11 @@ where

Ok(Self {
r_U_primary: recursive_snark.r_U_primary.clone(),
ri_primary: recursive_snark.ri_primary.clone(),

Check failure on line 1111 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `<E1 as Engine>::Scalar` which implements the `Copy` trait
r_W_snark_primary: snark_primary?,

r_U_secondary: recursive_snark.r_U_secondary.clone(),
ri_secondary: recursive_snark.ri_secondary.clone(),

Check failure on line 1115 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

using `clone` on type `<E2 as Engine>::Scalar` which implements the `Copy` trait
l_u_secondary: recursive_snark.l_u_secondary.clone(),
nifs_secondary,
f_W_snark_secondary: snark_secondary?,
Expand Down Expand Up @@ -1147,6 +1180,7 @@ where
hasher.absorb(*e);
}
self.r_U_secondary.absorb_in_ro(&mut hasher);
hasher.absorb(self.ri_primary);

let mut hasher2 = <E1 as Engine>::RO::new(
vk.ro_consts_primary.clone(),
Expand All @@ -1161,6 +1195,7 @@ where
hasher2.absorb(*e);
}
self.r_U_primary.absorb_in_ro(&mut hasher2);
hasher2.absorb(self.ri_secondary);

(
hasher.squeeze(NUM_HASH_BITS),
Expand Down Expand Up @@ -1255,6 +1290,7 @@ where
hasher.absorb(*e);
}
self.r_U_secondary.absorb_in_ro(&mut hasher);
hasher.absorb(self.ri_primary);

let mut hasher2 = <E1 as Engine>::RO::new(
vk.ro_consts_primary.clone(),
Expand All @@ -1269,6 +1305,7 @@ where
hasher2.absorb(*e);
}
self.r_U_primary.absorb_in_ro(&mut hasher2);
hasher2.absorb(self.ri_secondary);

(
hasher.squeeze(NUM_HASH_BITS),
Expand Down

0 comments on commit 3c9a6e6

Please sign in to comment.