Browse Source

output h2 as AllocatedNum (#31)

* output h2 as AllocatedNum

* clippy
main
Srinath Setty 2 years ago
committed by GitHub
parent
commit
dcea0be01f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 27 deletions
  1. +18
    -25
      src/circuit.rs
  2. +16
    -2
      src/poseidon.rs

+ 18
- 25
src/circuit.rs

@ -54,7 +54,7 @@ where
G: Group, G: Group,
{ {
h1: G::Base, h1: G::Base,
h2: G::Scalar,
h2: G::Base,
u2: RelaxedR1CSInstance<G>, u2: RelaxedR1CSInstance<G>,
i: G::Base, i: G::Base,
z0: G::Base, z0: G::Base,
@ -76,7 +76,7 @@ where
i: G::Base, i: G::Base,
z0: G::Base, z0: G::Base,
zi: G::Base, zi: G::Base,
h2: G::Scalar,
h2: G::Base,
params: G::Base, params: G::Base,
T: Commitment<G>, T: Commitment<G>,
w: Commitment<G>, w: Commitment<G>,
@ -146,32 +146,33 @@ where
cs: &mut CS, cs: &mut CS,
) -> Result<(), SynthesisError> { ) -> Result<(), SynthesisError> {
/***********************************************************************/ /***********************************************************************/
// This circuit does not modify h2 but it outputs it.
// Allocate it and output it.
// Allocate h1
/***********************************************************************/ /***********************************************************************/
// Allocate h2 as a big number with 8 limbs
let h2_bn = BigNat::alloc_from_nat(
cs.namespace(|| "allocate h2"),
|| Ok(f_to_nat(&self.inputs.get()?.h2)),
let h1 = AllocatedNum::alloc(cs.namespace(|| "allocate h1"), || Ok(self.inputs.get()?.h1))?;
let h1_bn = BigNat::from_num(
cs.namespace(|| "allocate h1_bn"),
Num::from(h1.clone()),
self.params.limb_width, self.params.limb_width,
self.params.n_limbs, self.params.n_limbs,
)?; )?;
let _ = h2_bn.inputize(cs.namespace(|| "Output 1"))?;
/***********************************************************************/ /***********************************************************************/
// Allocate h1
// This circuit does not modify h2 but it outputs it.
// Allocate it and output it.
/***********************************************************************/ /***********************************************************************/
let h1 = AllocatedNum::alloc(cs.namespace(|| "allocate h1"), || Ok(self.inputs.get()?.h1))?;
let h1_bn = BigNat::from_num(
cs.namespace(|| "allocate h1_bn"),
Num::from(h1.clone()),
// Allocate h2 as a big number with 8 limbs
let h2 = AllocatedNum::alloc(cs.namespace(|| "allocate h2"), || Ok(self.inputs.get()?.h2))?;
let h2_bn = BigNat::from_num(
cs.namespace(|| "allocate h2_bn"),
Num::from(h2.clone()),
self.params.limb_width, self.params.limb_width,
self.params.n_limbs, self.params.n_limbs,
)?; )?;
let _ = h2.inputize(cs.namespace(|| "Output 1"))?;
/***********************************************************************/ /***********************************************************************/
// Allocate u2 by allocating W_r, E_r, u_r, X_r // Allocate u2 by allocating W_r, E_r, u_r, X_r
/***********************************************************************/ /***********************************************************************/
@ -291,8 +292,6 @@ where
// Allocate 0 and 1 // Allocate 0 and 1
let zero = alloc_zero(cs.namespace(|| "zero"))?; let zero = alloc_zero(cs.namespace(|| "zero"))?;
// Hack: We just do this because the number of inputs must be even!!
zero.inputize(cs.namespace(|| "allocate zero as input"))?;
let one = alloc_one(cs.namespace(|| "one"))?; let one = alloc_one(cs.namespace(|| "one"))?;
// Compute default values of U2': // Compute default values of U2':
@ -325,13 +324,7 @@ where
let mut ro: PoseidonROGadget<G::Base> = PoseidonROGadget::new(self.poseidon_constants.clone()); let mut ro: PoseidonROGadget<G::Base> = PoseidonROGadget::new(self.poseidon_constants.clone());
ro.absorb(h1.clone()); ro.absorb(h1.clone());
// absorb each of the limbs of h2
// TODO: Check if it is more efficient to treat h2 as allocNum
for (i, limb) in h2_bn.as_limbs::<CS>().iter().enumerate() {
let limb_num = limb
.as_sapling_allocated_num(cs.namespace(|| format!("convert limb {} of h2 to num", i)))?;
ro.absorb(limb_num);
}
ro.absorb(h2);
ro.absorb(W.x.clone()); ro.absorb(W.x.clone());
ro.absorb(W.y.clone()); ro.absorb(W.y.clone());
ro.absorb(W.is_infinity.clone()); ro.absorb(W.is_infinity.clone());
@ -684,7 +677,7 @@ mod tests {
<<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs <<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs
<<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs <<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs
<<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs <<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs
<<G2 as Group>::Scalar as Field>::zero(), // TODO: provide real inputs
<<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs
<<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs <<G2 as Group>::Base as Field>::zero(), // TODO: provide real inputs
T, // TODO: provide real inputs T, // TODO: provide real inputs
w, w,

+ 16
- 2
src/poseidon.rs

@ -7,7 +7,7 @@ use bellperson::{
ConstraintSystem, SynthesisError, ConstraintSystem, SynthesisError,
}; };
use ff::{PrimeField, PrimeFieldBits}; use ff::{PrimeField, PrimeFieldBits};
use generic_array::typenum::{U25, U27, U31};
use generic_array::typenum::{U24, U25, U27, U31};
use neptune::{ use neptune::{
circuit::poseidon_hash, circuit::poseidon_hash,
poseidon::{Poseidon, PoseidonConstants}, poseidon::{Poseidon, PoseidonConstants},
@ -22,6 +22,7 @@ pub struct NovaPoseidonConstants
where where
F: PrimeField, F: PrimeField,
{ {
constants24: PoseidonConstants<F, U24>,
constants25: PoseidonConstants<F, U25>, constants25: PoseidonConstants<F, U25>,
constants27: PoseidonConstants<F, U27>, constants27: PoseidonConstants<F, U27>,
constants31: PoseidonConstants<F, U31>, constants31: PoseidonConstants<F, U31>,
@ -34,10 +35,12 @@ where
{ {
/// Generate Poseidon constants for the arities that Nova uses /// Generate Poseidon constants for the arities that Nova uses
pub fn new() -> Self { pub fn new() -> Self {
let constants24 = PoseidonConstants::<F, U24>::new_with_strength(Strength::Strengthened);
let constants25 = PoseidonConstants::<F, U25>::new_with_strength(Strength::Strengthened); let constants25 = PoseidonConstants::<F, U25>::new_with_strength(Strength::Strengthened);
let constants27 = PoseidonConstants::<F, U27>::new_with_strength(Strength::Strengthened); let constants27 = PoseidonConstants::<F, U27>::new_with_strength(Strength::Strengthened);
let constants31 = PoseidonConstants::<F, U31>::new_with_strength(Strength::Strengthened); let constants31 = PoseidonConstants::<F, U31>::new_with_strength(Strength::Strengthened);
Self { Self {
constants24,
constants25, constants25,
constants27, constants27,
constants31, constants31,
@ -82,6 +85,9 @@ where
fn hash_inner(&mut self) -> Scalar { fn hash_inner(&mut self) -> Scalar {
match self.state.len() { match self.state.len() {
24 => {
Poseidon::<Scalar, U24>::new_with_preimage(&self.state, &self.constants.constants24).hash()
}
25 => { 25 => {
Poseidon::<Scalar, U25>::new_with_preimage(&self.state, &self.constants.constants25).hash() Poseidon::<Scalar, U25>::new_with_preimage(&self.state, &self.constants.constants25).hash()
} }
@ -170,6 +176,11 @@ where
CS: ConstraintSystem<Scalar>, CS: ConstraintSystem<Scalar>,
{ {
let out = match self.state.len() { let out = match self.state.len() {
24 => poseidon_hash(
cs.namespace(|| "Posideon hash"),
self.state.clone(),
&self.constants.constants24,
)?,
25 => poseidon_hash( 25 => poseidon_hash(
cs.namespace(|| "Poseidon hash"), cs.namespace(|| "Poseidon hash"),
self.state.clone(), self.state.clone(),
@ -186,7 +197,10 @@ where
&self.constants.constants31, &self.constants.constants31,
)?, )?,
_ => { _ => {
panic!("Number of elements in the RO state does not match any of the arities used in Nova")
panic!(
"Number of elements in the RO state does not match any of the arities used in Nova {}",
self.state.len()
)
} }
}; };

Loading…
Cancel
Save