liminal_ark_pnbr_poseidon_parameters/
lib.rs

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