1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(non_snake_case)]
mod arc_matrix;
mod matrix;
mod matrix_ops;
mod mds_matrix;
#[cfg(test)]
mod tests;
pub use arc_matrix::*;
use ark_ff::{BigInteger, PrimeField};
pub use matrix::*;
pub use matrix_ops::*;
pub use mds_matrix::*;
/// Input parameters that are used to generate Poseidon parameters.
#[derive(Clone, Debug)]
pub struct InputParameters<T: BigInteger> {
/// Whether or not to allow inverse alpha.
pub allow_inverse: bool,
/// Security level in bits.
pub M: usize,
/// Width of desired hash function, e.g. $t=3$ corresponds to 2-to-1 hash.
pub t: usize,
/// Modulus of the prime field.
pub p: T, // let modulus = <F as PrimeField>::Params::MODULUS;
// The below are derived values, stored for convenience.
/// log_2(p)
pub log_2_p: f64,
}
/// The exponent in `Sbox(x) = x^\alpha`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Alpha {
/// A positive exponent $x^{alpha}$.
Exponent(u32),
/// 1/x
Inverse,
}
impl Alpha {
/// Return the memory representation of alpha as a byte array in little-endian byte order.
pub fn to_bytes_le(&self) -> [u8; 4] {
match self {
Alpha::Exponent(exp) => exp.to_le_bytes(),
Alpha::Inverse => (-1i32).to_le_bytes(),
}
}
}
/// `RoundNumbers` required for security based on known attacks.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct RoundNumbers {
/// Number of partial rounds.
pub r_P: usize,
/// Number of full rounds.
pub r_F: usize,
}
impl RoundNumbers {
/// Number of full rounds.
pub fn full(&self) -> usize {
self.r_F
}
/// Number of full rounds as mutable reference.
pub fn full_mut(&mut self) -> &mut usize {
&mut self.r_F
}
/// Number of partial rounds.
pub fn partial(&self) -> usize {
self.r_P
}
/// Number of full rounds as mutable reference.
pub fn partial_mut(&mut self) -> &mut usize {
&mut self.r_P
}
/// Number of total rounds.
pub fn total(&self) -> usize {
self.r_P + self.r_F
}
}
// TODO: arc and mds could be collections
/// A set of Poseidon parameters for a given set of input parameters.
#[derive(Clone, Debug)]
pub struct PoseidonParameters<F: PrimeField> {
// Input parameters.
/// Security level.
pub M: usize,
/// Width of desired hash function, e.g. $t=3$ corresponds to a 2-to-1 hash.
pub t: usize,
// Generated parameters.
/// Exponent of the Sbox, i.e. S-box(x) = x^{\alpha} used in the `SubWords` step
pub alpha: Alpha,
/// Round numbers
pub rounds: RoundNumbers,
/// `t x t` MDS matrix used in the `MixLayer` step
pub mds: MdsMatrix<F>,
/// `num_total_rounds x t` matrix of constants used in the `AddRoundConstant` step
pub arc: ArcMatrix<F>,
/// Optimized round constants.
pub optimized_arc: OptimizedArcMatrix<F>,
/// Optimized MDS matrices.
pub optimized_mds: OptimizedMdsMatrices<F>,
}