From c0aa60401590a9a78ee38f987d66e16c86c9f78d Mon Sep 17 00:00:00 2001 From: moana Date: Wed, 24 Jan 2024 18:08:23 +0100 Subject: [PATCH] Remove the hades constants iterator This change also decreases the amount of constants that are statically loaded from 960 to 335. As it turns out, we never needed so many constants. Also rename `add_round_key` to `add_round_constants` to match the paper. --- CHANGELOG.md | 2 + assets/HOWTO.md | 2 +- assets/ark.bin | Bin 30720 -> 10720 bytes src/hades.rs | 7 ++- src/hades/permutation.rs | 101 +++++++++++++------------------- src/hades/permutation/gadget.rs | 39 +++++------- src/hades/permutation/scalar.rs | 43 +++++++------- src/hades/round_constants.rs | 17 +++--- 8 files changed, 92 insertions(+), 119 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b31d4..dd1615c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Rename trait `hades::Strategy` to `hades::Permutation` [#243] - Rename struct `hades::ScalarStrategy` to `hades::ScalarPermutation` [#243] - Rename struct `hades::GadgetStrategy` to `hades::GadgetPermutaiton` [#243] +- Reduce the number of `ROUND_CONSTANTS` from 960 to 335 [#246] +- Remove the constants iterator in favor of indexing the constants array directly [#246] ### Removed diff --git a/assets/HOWTO.md b/assets/HOWTO.md index 3cabe0c..f9a328d 100644 --- a/assets/HOWTO.md +++ b/assets/HOWTO.md @@ -18,7 +18,7 @@ use std::io::Write; // The amount of constants generated, this needs to be the same number as in // `dusk_poseidon::hades::CONSTANTS`. -const CONSTANTS: usize = 960; +const CONSTANTS: usize = 335; fn constants() -> [BlsScalar; CONSTANTS] { let mut cnst = [BlsScalar::zero(); CONSTANTS]; diff --git a/assets/ark.bin b/assets/ark.bin index 043249354529e6feab08ca2603d3e40691de7ca2..55c576d65f09362a7af02be1040bc37c144129c2 100644 GIT binary patch delta 8 PcmZqp!1y3|!vjqK6hj1F delta 20166 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 Fk`oI0e1!l2 diff --git a/src/hades.rs b/src/hades.rs index cea4f39..07bd2c2 100644 --- a/src/hades.rs +++ b/src/hades.rs @@ -15,8 +15,8 @@ //! end, and each full round has `WIDTH` quintic S-Boxes. //! - 59 partial rounds: each partial round has `WIDTH - 1` identity function //! and one quintic S-Box. -//! - 960 round constants -//! - Round constants are generated using [this algorithm](https://extgit.iaik.tugraz.at/krypto/hadesmimc/blob/master/code/calc_round_numbers.py) +//! - 335 round constants +//! - The round constants are generated using [this algorithm](https://extgit.iaik.tugraz.at/krypto/hadesmimc/blob/master/code/calc_round_numbers.py) //! - The MDS matrix is a cauchy matrix, the method used to generate it, is //! noted in section "Concrete Instantiations Poseidon and Starkad" @@ -32,7 +32,8 @@ const TOTAL_FULL_ROUNDS: usize = 8; const PARTIAL_ROUNDS: usize = 59; -const CONSTANTS: usize = 960; +// (PARTIAL_ROUNDS + TOTAL_FULL_ROUNDS) * WIDTH +const CONSTANTS: usize = 335; /// The amount of field elements that fit into the hades permutation container pub const WIDTH: usize = 5; diff --git a/src/hades/permutation.rs b/src/hades/permutation.rs index 4492942..9c2f5dd 100644 --- a/src/hades/permutation.rs +++ b/src/hades/permutation.rs @@ -18,7 +18,7 @@ use dusk_bls12_381::BlsScalar; #[cfg(feature = "zk")] use dusk_plonk::prelude::{Composer, Witness}; -use crate::hades::{PARTIAL_ROUNDS, ROUND_CONSTANTS, TOTAL_FULL_ROUNDS, WIDTH}; +use crate::hades::{PARTIAL_ROUNDS, TOTAL_FULL_ROUNDS, WIDTH}; /// State for zero-knowledge plonk circuits #[cfg(feature = "zk")] @@ -39,7 +39,7 @@ use scalar::ScalarPermutation; /// - Applies the other half of the `FULL_ROUNDS`. /// /// This structure allows to minimize the number of non-linear ops while -/// mantaining the security. +/// maintaining the security. pub(crate) fn permute(state: &mut [BlsScalar; WIDTH]) { let mut hades = ScalarPermutation::new(); @@ -50,11 +50,11 @@ pub(crate) fn permute(state: &mut [BlsScalar; WIDTH]) { /// /// This permutation is a 3-step process that: /// - Applies half of the `FULL_ROUNDS` (which can be understood as linear ops). -/// - Applies the `PARTIAL_ROUDS` (which can be understood as non-linear ops). +/// - Applies the `PARTIAL_ROUNDS` (which can be understood as non-linear ops). /// - Applies the other half of the `FULL_ROUNDS`. /// /// This structure allows to minimize the number of non-linear ops while -/// mantaining the security. +/// maintaining the security. #[cfg(feature = "zk")] pub(crate) fn permute_gadget( composer: &mut Composer, @@ -67,30 +67,19 @@ pub(crate) fn permute_gadget( /// Defines the Hades252 permutation algorithm. pub(crate) trait Permutation { - /// Fetch the next round constant from an iterator - fn next_c<'b, I>(constants: &mut I) -> BlsScalar - where - I: Iterator, - { - constants - .next() - .copied() - .expect("Hades252 shouldn't be out of ARK constants") - } + /// Increment the inner rounds counter. + /// + /// This counter is needed to index the `ROUND_CONSTANTS`. + fn increment_round(&mut self); - /// Add round keys to the state. + /// Add round constants to the state. /// - /// This round key addition, also known as `ARK`, is used to reach + /// This constants addition, also known as `ARC`, is used to reach /// `Confusion and Diffusion` properties for the algorithm. /// /// Basically it allows to destroy any connection between the inputs and the /// outputs of the function. - fn add_round_key<'b, I>( - &mut self, - constants: &mut I, - state: &mut [T; WIDTH], - ) where - I: Iterator; + fn add_round_constants(&mut self, state: &mut [T; WIDTH]); /// Computes `input ^ 5 (mod p)` /// @@ -100,60 +89,52 @@ pub(crate) trait Permutation { fn quintic_s_box(&mut self, value: &mut T); /// Multiply the MDS matrix with the state. - fn mul_matrix<'b, I>(&mut self, constants: &mut I, state: &mut [T; WIDTH]) - where - I: Iterator; + fn mul_matrix(&mut self, state: &mut [T; WIDTH]); /// Applies a `Partial Round` also known as a `Partial S-Box layer` to a set /// of inputs. /// /// One partial round consists of 3 steps: - /// - ARK: Add round keys constants to each state element. - /// - Sub State: Apply `quintic S-Box` just to **the last element of the + /// - ARC: Add round constants to the elements of the state. + /// - Sub Words: Apply `quintic S-Box` just to **the last element of the /// state** generated from the first step. /// - Mix Layer: Multiplies the output state from the second step by the /// `MDS_MATRIX`. - fn apply_partial_round<'b, I>( - &mut self, - constants: &mut I, - state: &mut [T; WIDTH], - ) where - I: Iterator, - { - // Add round keys to each state element - self.add_round_key(constants, state); - - // Then apply quintic s-box + fn apply_partial_round(&mut self, state: &mut [T; WIDTH]) { + // Increment the inner rounds counter + self.increment_round(); + + // Add round constants to each state element + self.add_round_constants(state); + + // Then apply quintic s-box to the last element of the state self.quintic_s_box(&mut state[WIDTH - 1]); // Multiply this result by the MDS matrix - self.mul_matrix(constants, state); + self.mul_matrix(state); } /// Applies a `Full Round` also known as a `Full S-Box layer` to a set of /// inputs. /// - /// One full round constists of 3 steps: - /// - ARK: Add round keys to each state element. - /// - Sub State: Apply `quintic S-Box` to **all of the state-elements** + /// One full round consists of 3 steps: + /// - ARC: Add round constants to the elements of the state. + /// - Sub Words: Apply `quintic S-Box` to **all of the state-elements** /// generated from the first step. /// - Mix Layer: Multiplies the output state from the second step by the /// `MDS_MATRIX`. - fn apply_full_round<'a, I>( - &mut self, - constants: &mut I, - state: &mut [T; WIDTH], - ) where - I: Iterator, - { - // Add round keys to each state element - self.add_round_key(constants, state); - - // Then apply quintic s-box + fn apply_full_round(&mut self, state: &mut [T; WIDTH]) { + // Increment the inner rounds counter + self.increment_round(); + + // Add round constants to each state element + self.add_round_constants(state); + + // Then apply quintic s-box to each element of the state state.iter_mut().for_each(|w| self.quintic_s_box(w)); // Multiply this result by the MDS matrix - self.mul_matrix(constants, state); + self.mul_matrix(state); } /// Applies one Hades permutation. @@ -161,28 +142,26 @@ pub(crate) trait Permutation { /// This permutation is a 3-step process that: /// - Applies half of the `FULL_ROUNDS` (which can be understood as linear /// ops). - /// - Applies the `PARTIAL_ROUDS` (which can be understood as non-linear + /// - Applies the `PARTIAL_ROUNDS` (which can be understood as non-linear /// ops). /// - Applies the other half of the `FULL_ROUNDS`. /// /// This structure allows to minimize the number of non-linear ops while - /// mantaining the security. + /// maintaining the security. fn perm(&mut self, state: &mut [T; WIDTH]) { - let mut constants = ROUND_CONSTANTS.iter(); - // Apply R_f full rounds for _ in 0..TOTAL_FULL_ROUNDS / 2 { - self.apply_full_round(&mut constants, state); + self.apply_full_round(state); } // Apply R_P partial rounds for _ in 0..PARTIAL_ROUNDS { - self.apply_partial_round(&mut constants, state); + self.apply_partial_round(state); } // Apply R_f full rounds for _ in 0..TOTAL_FULL_ROUNDS / 2 { - self.apply_full_round(&mut constants, state); + self.apply_full_round(state); } } diff --git a/src/hades/permutation/gadget.rs b/src/hades/permutation/gadget.rs index dbce114..1355c00 100644 --- a/src/hades/permutation/gadget.rs +++ b/src/hades/permutation/gadget.rs @@ -7,9 +7,11 @@ use dusk_bls12_381::BlsScalar; use dusk_plonk::prelude::*; -use crate::hades::{Permutation as HadesPermutation, MDS_MATRIX, WIDTH}; +use crate::hades::{ + Permutation as HadesPermutation, MDS_MATRIX, ROUND_CONSTANTS, WIDTH, +}; -/// A state for the ['HadesPermutation`] operating on [`Witness`]es. +/// An implementation for the ['HadesPermutation`] operating on [`Witness`]es. /// Requires a reference to a `ConstraintSystem`. pub(crate) struct GadgetPermutaiton<'a> { /// A reference to the constraint system used by the gadgets @@ -31,19 +33,17 @@ impl AsMut for GadgetPermutaiton<'_> { } impl<'a> HadesPermutation for GadgetPermutaiton<'a> { - fn add_round_key<'b, I>( - &mut self, - constants: &mut I, - state: &mut [Witness; WIDTH], - ) where - I: Iterator, - { + fn increment_round(&mut self) { + self.round += 1; + } + + fn add_round_constants(&mut self, state: &mut [Witness; WIDTH]) { // To safe constraints we only add the constants here in the first // round. The remaining constants will be added in the matrix // multiplication. - if self.round == 0 { - state.iter_mut().for_each(|w| { - let constant = Self::next_c(constants); + if self.round == 1 { + state.iter_mut().enumerate().for_each(|(i, w)| { + let constant = ROUND_CONSTANTS[i]; let constraint = Constraint::new().left(1).a(*w).constant(constant); @@ -64,22 +64,14 @@ impl<'a> HadesPermutation for GadgetPermutaiton<'a> { } /// Adds a constraint for each matrix coefficient multiplication - fn mul_matrix<'b, I>( - &mut self, - constants: &mut I, - state: &mut [Witness; WIDTH], - ) where - I: Iterator, - { + fn mul_matrix(&mut self, state: &mut [Witness; WIDTH]) { let mut result = [Composer::ZERO; WIDTH]; - self.round += 1; // Implementation optimized for WIDTH = 5 // - // c is the next round's constant and hence zero for the last round. - // // The resulting array `r` will be defined as // r[x] = sum_{j=0..WIDTH} ( MDS[x][j] * state[j] ) + c + // with c being the constant for the next round. // // q_l = MDS[x][0] // q_r = MDS[x][1] @@ -97,8 +89,9 @@ impl<'a> HadesPermutation for GadgetPermutaiton<'a> { // w_4 = r[x] // r[x] = q_l · w_l + q_r · w_r + q_4 · w_4 + c; for j in 0..WIDTH { + // c is the next round's constant and hence zero for the last round. let c = match self.round < Self::rounds() { - true => Self::next_c(constants), + true => ROUND_CONSTANTS[self.round * WIDTH + j], false => BlsScalar::zero(), }; diff --git a/src/hades/permutation/scalar.rs b/src/hades/permutation/scalar.rs index 8c2ac5d..0ee528d 100644 --- a/src/hades/permutation/scalar.rs +++ b/src/hades/permutation/scalar.rs @@ -6,44 +6,45 @@ use dusk_bls12_381::BlsScalar; -use crate::hades::{Permutation as HadesPermutation, MDS_MATRIX, WIDTH}; +use crate::hades::{ + Permutation as HadesPermutation, MDS_MATRIX, ROUND_CONSTANTS, WIDTH, +}; -/// State that implements the [`HadesPermutation`] for `BlsScalar` as input +/// An implementation of the [`HadesPermutation`] for `BlsScalar` as input /// values. #[derive(Default)] -pub(crate) struct ScalarPermutation {} +pub(crate) struct ScalarPermutation { + round: usize, +} impl ScalarPermutation { /// Constructs a new `ScalarPermutation`. pub fn new() -> Self { - Default::default() + Self { round: 0 } } } impl HadesPermutation for ScalarPermutation { - fn add_round_key<'b, I>( - &mut self, - constants: &mut I, - state: &mut [BlsScalar; WIDTH], - ) where - I: Iterator, - { - state.iter_mut().for_each(|w| { - *w += Self::next_c(constants); - }); + fn increment_round(&mut self) { + self.round += 1; + } + + fn add_round_constants(&mut self, state: &mut [BlsScalar; WIDTH]) { + state + .iter_mut() + .enumerate() + // We start counting the rounds at 1 so we need to substract 1 when + // indexing + .for_each(|(i, s)| { + *s += ROUND_CONSTANTS[(self.round - 1) * WIDTH + i] + }); } fn quintic_s_box(&mut self, value: &mut BlsScalar) { *value = value.square().square() * *value; } - fn mul_matrix<'b, I>( - &mut self, - _constants: &mut I, - state: &mut [BlsScalar; WIDTH], - ) where - I: Iterator, - { + fn mul_matrix(&mut self, state: &mut [BlsScalar; WIDTH]) { let mut result = [BlsScalar::zero(); WIDTH]; for (j, value) in state.iter().enumerate() { diff --git a/src/hades/round_constants.rs b/src/hades/round_constants.rs index cba27c8..9aa6fb0 100644 --- a/src/hades/round_constants.rs +++ b/src/hades/round_constants.rs @@ -4,8 +4,8 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -//! This module is designed to load the 960 constants used as `round_constants` -//! from `ark.bin`. +//! This module is designed to load the constants used as `round_constants` +//! from `assets/ark.bin`. //! //! The constants were originally computed using: //! https://extgit.iaik.tugraz.at/krypto/hadesmimc/blob/master/code/calc_round_numbers.py @@ -15,22 +15,19 @@ use dusk_bls12_381::BlsScalar; use crate::hades::CONSTANTS; -/// `ROUND_CONSTANTS` constists on a static reference -/// that points to the pre-loaded 960 Fq constants. +/// `ROUND_CONSTANTS` constists on a static reference that points to the +/// pre-loaded 335 constant scalar of the bls12_381 curve. /// -/// This 960 `BlsScalar` constants are loaded from `ark.bin` -/// where all of the `BlsScalar`s are represented in buf. +/// These 335 `BlsScalar` constants are loaded from `assets/ark.bin`. /// -/// This round constants have been taken from: -/// https://extgit.iaik.tugraz.at/krypto/hadesmimc/blob/master/code/calc_round_numbers.py -/// and then mapped onto `Fq` in the Ristretto scalar field. +/// Check `assets/HOWTO.md` to see how we generated the constants. pub const ROUND_CONSTANTS: [BlsScalar; CONSTANTS] = { let bytes = include_bytes!("../../assets/ark.bin"); let mut cnst = [BlsScalar::zero(); CONSTANTS]; let mut i = 0; let mut j = 0; - while i < bytes.len() { + while i < CONSTANTS * 32 { let a = super::u64_from_buffer(bytes, i); let b = super::u64_from_buffer(bytes, i + 8); let c = super::u64_from_buffer(bytes, i + 16);