Skip to content

Commit

Permalink
feat: add pseudorandom permutation and sponge APIs (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
bhgomes authored Jun 28, 2022
1 parent e8ea531 commit 8270ba2
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [\#126](https://github.com/Manta-Network/manta-rs/pull/126) Add ECLAIR v0 scaffolding and deprecate old compiler patterns
- [\#128](https://github.com/Manta-Network/manta-rs/pull/128) Add more parameter loading utilities
- [\#130](https://github.com/Manta-Network/manta-rs/pull/130) Add the sage script and the hardcoded tests for the security of mds matrix
- [\#136](https://github.com/Manta-Network/manta-rs/pull/136) Add pseudorandom permutation and sponge abstractions
- [\#134](https://github.com/Manta-Network/manta-rs/pull/134) Add signature scheme API and Schnorr signature implementaion

### Changed
Expand Down
1 change: 1 addition & 0 deletions manta-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ pub mod hash;
pub mod key;
pub mod merkle_tree;
pub mod password;
pub mod permutation;
pub mod rand;
pub mod signature;
81 changes: 81 additions & 0 deletions manta-crypto/src/permutation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2019-2022 Manta Network.
// This file is part of manta-rs.
//
// manta-rs is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// manta-rs is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with manta-rs. If not, see <http://www.gnu.org/licenses/>.

//! Pseudorandom Permutations
pub mod sponge;

/// Pseudorandom Permutation
pub trait PseudorandomPermutation<COM = ()> {
/// Permutation Domain Type
///
/// A pseudorandom permutation acts on this domain, and should be a bijection on this space.
type Domain;

/// Computes the permutation of `state`.
fn permute(&self, state: &mut Self::Domain, compiler: &mut COM);
}

impl<P, COM> PseudorandomPermutation<COM> for &P
where
P: PseudorandomPermutation<COM>,
{
type Domain = P::Domain;

#[inline]
fn permute(&self, state: &mut Self::Domain, compiler: &mut COM) {
(*self).permute(state, compiler)
}
}

/// Pseudorandom Permutation Family
pub trait PseudorandomPermutationFamily<COM = ()> {
/// Key Type
type Key: ?Sized;

/// Permutation Domain Type
///
/// A pseudorandom permutation acts on this domain, and should be a bijection on this space.
type Domain;

/// Permutation Type
///
/// Given a [`Key`](Self::Key) we can produce a pseudorandom permutation of this type.
type Permutation: PseudorandomPermutation<COM, Domain = Self::Domain>;

/// Returns the pseudorandom permutation associated to the given `key`.
fn permutation(&self, key: &Self::Key, compiler: &mut COM) -> Self::Permutation;

/// Computes the permutation of `state` under the pseudorandom permutation derived from `key`.
#[inline]
fn permute(&self, key: &Self::Key, state: &mut Self::Domain, compiler: &mut COM) {
self.permutation(key, compiler).permute(state, compiler)
}
}

impl<P, COM> PseudorandomPermutationFamily<COM> for &P
where
P: PseudorandomPermutationFamily<COM>,
{
type Key = P::Key;
type Domain = P::Domain;
type Permutation = P::Permutation;

#[inline]
fn permutation(&self, key: &Self::Key, compiler: &mut COM) -> Self::Permutation {
(*self).permutation(key, compiler)
}
}
108 changes: 108 additions & 0 deletions manta-crypto/src/permutation/sponge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright 2019-2022 Manta Network.
// This file is part of manta-rs.
//
// manta-rs is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// manta-rs is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with manta-rs. If not, see <http://www.gnu.org/licenses/>.

//! Sponges over Pseudorandom Permutations
use crate::permutation::PseudorandomPermutation;

/// Sponge Reader
pub trait Read<P, COM = ()>: Sized
where
P: PseudorandomPermutation<COM>,
{
/// Reads an element of type `Self` from the `state`.
fn read(state: &P::Domain, compiler: &mut COM) -> Self;
}

/// Sponge Writer
pub trait Write<P, COM = ()>
where
P: PseudorandomPermutation<COM>,
{
/// Output Type
type Output;

/// Writes `self` to the `state`, returning some output data computed from `self` and `state`.
fn write(&self, state: &mut P::Domain, compiler: &mut COM) -> Self::Output;
}

/// Permutation Sponge
///
/// This `struct` is a general sponge-like construction which takes a permutation and repeatedly
/// applies it to an internal state, with read and write access to the state via the [`absorb`]
/// and [`squeeze`] methods. Using a concrete permutation and fixed [`absorb`] input and [`squeeze`]
/// output functions one can build the classical sponge constructions.
///
/// [`absorb`]: Self::absorb
/// [`squeeze`]: Self::squeeze
pub struct Sponge<'p, P, COM = ()>
where
P: PseudorandomPermutation<COM>,
{
/// Permutation
pub permutation: &'p P,

/// Sponge State
pub state: &'p mut P::Domain,
}

impl<'p, P, COM> Sponge<'p, P, COM>
where
P: PseudorandomPermutation<COM>,
{
/// Builds a new [`Sponge`] over `permutation` with the given initial `state`.
#[inline]
pub fn new(permutation: &'p P, state: &'p mut P::Domain) -> Self {
Self { permutation, state }
}

/// Updates `self` by absorbing writes into the state with `input`.
#[inline]
pub fn absorb<W>(&mut self, input: &W, compiler: &mut COM) -> W::Output
where
W: Write<P, COM>,
{
let out = input.write(self.state, compiler);
self.permutation.permute(self.state, compiler);
out
}

/// Absorbs all the items in the `input` iterator, collecting all output items from writes into
/// the state. See [`Write::write`] for more.
#[inline]
pub fn absorb_all<'w, W, I, C>(&mut self, input: I, compiler: &mut COM) -> C
where
W: 'w + Write<P, COM>,
I: IntoIterator<Item = &'w W>,
C: FromIterator<W::Output>,
{
input
.into_iter()
.map(|item| self.absorb(item, compiler))
.collect()
}

/// Returns the next values from `self` by squeezing reads of the values from the state.
#[inline]
pub fn squeeze<R>(&mut self, compiler: &mut COM) -> R
where
R: Read<P, COM>,
{
let out = R::read(self.state, compiler);
self.permutation.permute(self.state, compiler);
out
}
}

0 comments on commit 8270ba2

Please sign in to comment.