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}