Skip to content

Commit

Permalink
Split permutation from sponge construction
Browse files Browse the repository at this point in the history
Work towards #29; this doesn't touch the constraint system implementation yet,
in order to be able to get design feedback on the software part.

- The `poseidon::PoseidonParameters` struct is renamed to `poseidon::Parameters`
but otherwise remains unchanged.

- The `poseidon::PoseidonSpongeState` struct is renamed to `poseidon::State`
  and redefined to hold just the state itself, as well as the parameters needed
to run the permutation.  It exposes a `permute(&mut self)` method, `rate()` and
`capacity()` accessors, as well as `Index`, `IndexMut`, `AsRef`, and `AsMut`
impls that allow access to the state.

- The `poseidon::PoseidonSponge` struct is renamed to `poseidon::Sponge` and
  holds a `State` and a `DuplexSpongeMode`.  In other words, it consists of the
state, together with the extra data tracking how that state is being used to
implement a higher-level duplex construction.

- The `CryptographicSponge` trait is changed so that `new()` takes an owned,
  `Self::Parameters`, not a borrowed one.  This allows the caller to decide
where to copy data, instead of forcing the sponge implementation to clone
internally.  Or, a `CryptographicSponge` implementation could declare the
associated `Parameters` type to be some shared type (like an `Arc` wrapper)
that avoids the need to copy at all.

- The `SpongeExt` trait that allows converting back and forth between a state
  and a sponge is deleted; it's not safe to pass between abstraction layers
that way.
  • Loading branch information
hdevalence committed Oct 19, 2021
1 parent 51d6fc9 commit a5468be
Show file tree
Hide file tree
Showing 8 changed files with 537 additions and 491 deletions.
18 changes: 3 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pub use absorb::*;

/// The sponge for Poseidon
///
/// This implementation of Poseidon is entirely from Fractal's implementation in [COS20][cos]
/// with small syntax changes.
/// This implementation of Poseidon was derived from Fractal's implementation in
/// [COS20][cos].
///
/// [cos]: https://eprint.iacr.org/2019/1076
pub mod poseidon;
Expand Down Expand Up @@ -110,7 +110,7 @@ pub trait CryptographicSponge: Clone {
type Parameters;

/// Initialize a new instance of the sponge.
fn new(params: &Self::Parameters) -> Self;
fn new(params: Self::Parameters) -> Self;

/// Absorb an input into the sponge.
fn absorb(&mut self, input: &impl Absorb);
Expand Down Expand Up @@ -185,18 +185,6 @@ pub trait FieldBasedCryptographicSponge<CF: PrimeField>: CryptographicSponge {
}
}

/// An extension for the interface of a cryptographic sponge.
/// In addition to operations defined in `CryptographicSponge`, `SpongeExt` can convert itself to
/// a state, and instantiate itself from state.
pub trait SpongeExt: CryptographicSponge {
/// The full state of the cryptographic sponge.
type State: Clone;
/// Returns a sponge that uses `state`.
fn from_state(state: Self::State, params: &Self::Parameters) -> Self;
/// Consumes `self` and returns the state.
fn into_state(self) -> Self::State;
}

/// The mode structure for duplex sponges
#[derive(Clone, Debug)]
pub enum DuplexSpongeMode {
Expand Down
18 changes: 10 additions & 8 deletions src/poseidon/constraints.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Constraints for Poseidon.

use crate::constraints::AbsorbGadget;
use crate::constraints::{CryptographicSpongeVar, SpongeWithGadget};
use crate::poseidon::{PoseidonParameters, PoseidonSponge};
use crate::poseidon::{Parameters, Sponge};
use crate::DuplexSpongeMode;
use ark_ff::{FpParameters, PrimeField};
use ark_r1cs_std::fields::fp::FpVar;
Expand All @@ -21,7 +23,7 @@ pub struct PoseidonSpongeVar<F: PrimeField> {
pub cs: ConstraintSystemRef<F>,

/// Sponge Parameters
pub parameters: PoseidonParameters<F>,
pub parameters: Parameters<F>,

// Sponge State
/// The sponge's state
Expand All @@ -30,7 +32,7 @@ pub struct PoseidonSpongeVar<F: PrimeField> {
pub mode: DuplexSpongeMode,
}

impl<F: PrimeField> SpongeWithGadget<F> for PoseidonSponge<F> {
impl<F: PrimeField> SpongeWithGadget<F> for Sponge<F> {
type Var = PoseidonSpongeVar<F>;
}

Expand Down Expand Up @@ -179,11 +181,11 @@ impl<F: PrimeField> PoseidonSpongeVar<F> {
}
}

impl<F: PrimeField> CryptographicSpongeVar<F, PoseidonSponge<F>> for PoseidonSpongeVar<F> {
type Parameters = PoseidonParameters<F>;
impl<F: PrimeField> CryptographicSpongeVar<F, Sponge<F>> for PoseidonSpongeVar<F> {
type Parameters = Parameters<F>;

#[tracing::instrument(target = "r1cs", skip(cs))]
fn new(cs: ConstraintSystemRef<F>, parameters: &PoseidonParameters<F>) -> Self {
fn new(cs: ConstraintSystemRef<F>, parameters: &Parameters<F>) -> Self {
let zero = FpVar::<F>::zero();
let state = vec![zero; parameters.rate + parameters.capacity];
let mode = DuplexSpongeMode::Absorbing {
Expand Down Expand Up @@ -295,7 +297,7 @@ mod tests {
use crate::constraints::CryptographicSpongeVar;
use crate::poseidon::constraints::PoseidonSpongeVar;
use crate::poseidon::tests::poseidon_parameters_for_test;
use crate::poseidon::PoseidonSponge;
use crate::poseidon::Sponge;
use crate::{CryptographicSponge, FieldBasedCryptographicSponge};
use ark_ff::UniformRand;
use ark_r1cs_std::fields::fp::FpVar;
Expand Down Expand Up @@ -324,7 +326,7 @@ mod tests {

let sponge_params = poseidon_parameters_for_test();

let mut native_sponge = PoseidonSponge::<Fr>::new(&sponge_params);
let mut native_sponge = Sponge::<Fr>::new(sponge_params.clone());
let mut constraint_sponge = PoseidonSpongeVar::<Fr>::new(cs.clone(), &sponge_params);

native_sponge.absorb(&absorb1);
Expand Down
Loading

0 comments on commit a5468be

Please sign in to comment.