Skip to content

Commit

Permalink
Only expose perm functions and width from hades
Browse files Browse the repository at this point in the history
Resolves #243
  • Loading branch information
moCello committed Jan 22, 2024
1 parent 2eeb49c commit 383b1c5
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 49 deletions.
24 changes: 10 additions & 14 deletions src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ use dusk_bls12_381::BlsScalar;
use dusk_bytes::{DeserializableSlice, Error as BytesError, Serializable};
use dusk_jubjub::JubJubAffine;

use crate::hades::{ScalarStrategy, Strategy, WIDTH};
use crate::hades::{permute, WIDTH};

#[cfg(feature = "rkyv-impl")]
use bytecheck::CheckBytes;
Expand Down Expand Up @@ -199,12 +199,10 @@ impl PoseidonCipher {
nonce: &BlsScalar,
) -> Self {
let zero = BlsScalar::zero();
let mut strategy = ScalarStrategy::new();

let mut cipher = [zero; CIPHER_SIZE];
let mut state = PoseidonCipher::initial_state(secret, *nonce);

strategy.perm(&mut state);
permute(&mut state);

(0..MESSAGE_CAPACITY).for_each(|i| {
state[i + 1] += if i < message.len() {
Expand All @@ -216,7 +214,7 @@ impl PoseidonCipher {
cipher[i] = state[i + 1];
});

strategy.perm(&mut state);
permute(&mut state);
cipher[MESSAGE_CAPACITY] = state[1];

PoseidonCipher::new(cipher)
Expand All @@ -231,19 +229,17 @@ impl PoseidonCipher {
nonce: &BlsScalar,
) -> Option<[BlsScalar; MESSAGE_CAPACITY]> {
let zero = BlsScalar::zero();
let mut strategy = ScalarStrategy::new();

let mut message = [zero; MESSAGE_CAPACITY];
let mut state = PoseidonCipher::initial_state(secret, *nonce);

strategy.perm(&mut state);
permute(&mut state);

(0..MESSAGE_CAPACITY).for_each(|i| {
message[i] = self.cipher[i] - state[i + 1];
state[i + 1] = self.cipher[i];
});

strategy.perm(&mut state);
permute(&mut state);

if self.cipher[MESSAGE_CAPACITY] != state[1] {
return None;
Expand All @@ -256,7 +252,7 @@ impl PoseidonCipher {
#[cfg(feature = "zk")]
mod zk {
use super::PoseidonCipher;
use crate::hades::{GadgetStrategy, WIDTH};
use crate::hades::{permute_gadget, WIDTH};

use dusk_plonk::prelude::*;

Expand Down Expand Up @@ -302,7 +298,7 @@ mod zk {
let mut state =
PoseidonCipher::initial_state_circuit(composer, ks0, ks1, nonce);

GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);

(0..PoseidonCipher::capacity()).for_each(|i| {
let x = if i < message.len() {
Expand All @@ -319,7 +315,7 @@ mod zk {
cipher[i] = state[i + 1];
});

GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);
cipher[PoseidonCipher::capacity()] = state[1];

cipher
Expand All @@ -342,7 +338,7 @@ mod zk {
let mut state =
PoseidonCipher::initial_state_circuit(composer, ks0, ks1, nonce);

GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);

(0..PoseidonCipher::capacity()).for_each(|i| {
let constraint = Constraint::new()
Expand All @@ -356,7 +352,7 @@ mod zk {
state[i + 1] = cipher[i];
});

GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);

composer.assert_equal(cipher[PoseidonCipher::capacity()], state[1]);

Expand Down
5 changes: 3 additions & 2 deletions src/hades.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod strategies;

use mds_matrix::MDS_MATRIX;
use round_constants::ROUND_CONSTANTS;
use strategies::Strategy;

const TOTAL_FULL_ROUNDS: usize = 8;

Expand All @@ -36,9 +37,9 @@ const CONSTANTS: usize = 960;
/// The amount of field elements that fit into the hades permutation container
pub const WIDTH: usize = 5;

pub use strategies::permute;
#[cfg(feature = "zk")]
pub use strategies::GadgetStrategy;
pub use strategies::{ScalarStrategy, Strategy};
pub use strategies::permute_gadget;

const fn u64_from_buffer<const N: usize>(buf: &[u8; N], i: usize) -> u64 {
u64::from_le_bytes([
Expand Down
29 changes: 25 additions & 4 deletions src/hades/strategies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,42 @@
use dusk_bls12_381::BlsScalar;

use crate::hades::{PARTIAL_ROUNDS, ROUND_CONSTANTS, TOTAL_FULL_ROUNDS};
#[cfg(feature = "zk")]
use dusk_plonk::prelude::{Composer, Witness};

use crate::hades::{PARTIAL_ROUNDS, ROUND_CONSTANTS, TOTAL_FULL_ROUNDS, WIDTH};

/// Strategy for zero-knowledge plonk circuits
#[cfg(feature = "zk")]
mod gadget;
#[cfg(feature = "zk")]
use gadget::GadgetStrategy;

/// Strategy for scalars
mod scalar;
use scalar::ScalarStrategy;

// #[cfg(feature = "zk")]
// pub use gadget::GadgetStrategy;
// pub use scalar::ScalarStrategy;

/// Perform one Hades permutation on the given state.
pub fn permute(state: &mut [BlsScalar; WIDTH]) {
let mut hades = ScalarStrategy::new();

hades.perm(state);
}

/// Perform one Hades permutation on the given state in a plonk circuit.
#[cfg(feature = "zk")]
pub use gadget::GadgetStrategy;
pub use scalar::ScalarStrategy;
pub fn permute_gadget(composer: &mut Composer, state: &mut [Witness; WIDTH]) {
let mut hades = GadgetStrategy::new(composer);

hades.perm(state);
}

/// Defines the Hades252 strategy algorithm.
pub trait Strategy<T: Clone + Copy> {
pub(crate) trait Strategy<T: Clone + Copy> {
/// Fetch the next round constant from an iterator
fn next_c<'b, I>(constants: &mut I) -> BlsScalar
where
Expand Down
19 changes: 6 additions & 13 deletions src/hades/strategies/gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::hades::{Strategy, MDS_MATRIX, WIDTH};

/// Implements a Hades252 strategy for `Witness` as input values.
/// Requires a reference to a `ConstraintSystem`.
pub struct GadgetStrategy<'a> {
pub(crate) struct GadgetStrategy<'a> {
/// A reference to the constraint system used by the gadgets
cs: &'a mut Composer,
count: usize,
Expand All @@ -22,13 +22,6 @@ impl<'a> GadgetStrategy<'a> {
pub fn new(cs: &'a mut Composer) -> Self {
GadgetStrategy { cs, count: 0 }
}

/// Perform the hades permutation on a plonk circuit
pub fn gadget(composer: &'a mut Composer, x: &mut [Witness]) {
let mut strategy = GadgetStrategy::new(composer);

strategy.perm(x);
}
}

impl AsMut<Composer> for GadgetStrategy<'_> {
Expand Down Expand Up @@ -136,7 +129,7 @@ impl<'a> Strategy<Witness> for GadgetStrategy<'a> {
mod tests {
use super::*;

use crate::hades::ScalarStrategy;
use crate::hades::{permute, permute_gadget};

use core::result::Result;
use ff::Field;
Expand Down Expand Up @@ -166,7 +159,7 @@ mod tests {
});

// Apply Hades gadget strategy.
GadgetStrategy::gadget(composer, &mut i_var);
permute_gadget(composer, &mut i_var);

// Copy the result of the permutation into the perm.
perm.copy_from_slice(&i_var);
Expand All @@ -193,7 +186,7 @@ mod tests {
let mut output = [BlsScalar::zero(); WIDTH];

output.copy_from_slice(&input);
ScalarStrategy::new().perm(&mut output);
permute(&mut output);

(input, output)
}
Expand Down Expand Up @@ -235,7 +228,7 @@ mod tests {
// Prepare input & output
let i = [BlsScalar::from(5000u64); WIDTH];
let mut o = [BlsScalar::from(5000u64); WIDTH];
ScalarStrategy::new().perm(&mut o);
permute(&mut o);

let circuit = TestCircuit { i, o };
let mut rng = StdRng::seed_from_u64(0xbeef);
Expand All @@ -262,7 +255,7 @@ mod tests {
i[1] = x_scalar;

let mut o = [BlsScalar::from(31u64); WIDTH];
ScalarStrategy::new().perm(&mut o);
permute(&mut o);

let circuit = TestCircuit { i, o };
let mut rng = StdRng::seed_from_u64(0xbeef);
Expand Down
2 changes: 1 addition & 1 deletion src/hades/strategies/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::hades::{Strategy, MDS_MATRIX, WIDTH};

/// Implements a Hades252 strategy for `BlsScalar` as input values.
#[derive(Default)]
pub struct ScalarStrategy {}
pub(crate) struct ScalarStrategy {}

impl ScalarStrategy {
/// Constructs a new `ScalarStrategy`.
Expand Down
4 changes: 2 additions & 2 deletions src/perm_uses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use dusk_bls12_381::BlsScalar;

use crate::hades::{ScalarStrategy, Strategy, WIDTH};
use crate::hades::{permute, WIDTH};

/// Takes in one BlsScalar and outputs 2.
/// This function is fixed.
Expand All @@ -23,7 +23,7 @@ pub fn two_outputs(message: BlsScalar) -> [BlsScalar; 2] {
// Since we do a fixed_length hash, `words` is always the size of `WIDTH`.
// Therefore, we can simply do the permutation and return the desired
// results.
ScalarStrategy::new().perm(&mut words);
permute(&mut words);

[words[1], words[2]]
}
Expand Down
13 changes: 6 additions & 7 deletions src/sponge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub mod truncated;

use dusk_bls12_381::BlsScalar;

use crate::hades::{ScalarStrategy, Strategy, WIDTH};
use crate::hades::{permute, WIDTH};

#[cfg(feature = "zk")]
pub use zk::gadget;
Expand All @@ -32,7 +32,6 @@ pub use zk::gadget;
/// value. The padding values will be zeroes. To avoid collision, the padding
/// will imply one additional permutation in case `len` is a multiple of `r`.
pub fn hash(messages: &[BlsScalar]) -> BlsScalar {
let mut h = ScalarStrategy::new();
let mut state = [BlsScalar::zero(); WIDTH];

// If exists an `m` such as `m · (WIDTH - 1) == l`, then the last iteration
Expand Down Expand Up @@ -66,20 +65,20 @@ pub fn hash(messages: &[BlsScalar]) -> BlsScalar {
// append `1`, then there must be an extra permutation
// for the padding
} else if i == last_iteration {
h.perm(&mut state);
permute(&mut state);

state[1] += BlsScalar::one();
}

h.perm(&mut state);
permute(&mut state);
});

state[1]
}

#[cfg(feature = "zk")]
mod zk {
use crate::hades::{GadgetStrategy, WIDTH};
use crate::hades::{permute_gadget, WIDTH};
use dusk_plonk::prelude::{Composer, Constraint, Witness};

/// Mirror the implementation of [`hash`] inside of a PLONK circuit.
Expand Down Expand Up @@ -121,15 +120,15 @@ mod zk {

state[chunk.len() + 1] = composer.gate_add(constraint);
} else if i == last_iteration {
GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);

let constraint =
Constraint::new().left(1).a(state[1]).constant(1);

state[1] = composer.gate_add(constraint);
}

GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);
});

state[1]
Expand Down
10 changes: 4 additions & 6 deletions src/sponge/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use dusk_bls12_381::BlsScalar;

use crate::hades::{ScalarStrategy, Strategy, WIDTH};
use crate::hades::{permute, WIDTH};

#[cfg(feature = "zk")]
pub use zk::gadget;
Expand Down Expand Up @@ -47,8 +47,6 @@ fn tag<const A: usize>() -> u64 {
///
/// If `A` is not dividable by `r`, the padding values will be zeroes.
pub fn hash<const A: usize>(messages: &[BlsScalar; A]) -> BlsScalar {
let mut h = ScalarStrategy::new();

// initialize the state with zeros and set the first element to the tag
let mut state = [BlsScalar::zero(); WIDTH];
state[0] = BlsScalar::from(tag::<A>());
Expand All @@ -59,7 +57,7 @@ pub fn hash<const A: usize>(messages: &[BlsScalar; A]) -> BlsScalar {
state[1..].iter_mut().zip(chunk.iter()).for_each(|(s, c)| {
*s += c;
});
h.perm(&mut state);
permute(&mut state);
});

state[1]
Expand All @@ -71,7 +69,7 @@ mod zk {

use dusk_plonk::prelude::*;

use crate::hades::{GadgetStrategy, WIDTH};
use crate::hades::{permute_gadget, WIDTH};

/// Mirror the implementation of merkle [`hash`] inside of a PLONK circuit.
///
Expand All @@ -94,7 +92,7 @@ mod zk {
let constraint = Constraint::new().left(1).a(*s).right(1).b(*c);
*s = composer.gate_add(constraint);
});
GadgetStrategy::gadget(composer, &mut state);
permute_gadget(composer, &mut state);
});

state[1]
Expand Down

0 comments on commit 383b1c5

Please sign in to comment.