p3_poseidon2_air/
constants.rs

1use p3_field::PrimeCharacteristicRing;
2use rand::Rng;
3use rand::distr::{Distribution, StandardUniform};
4
5/// Round constants for Poseidon2, in a format that's convenient for the AIR.
6#[derive(Debug, Clone)]
7pub struct RoundConstants<
8    F: PrimeCharacteristicRing,
9    const WIDTH: usize,
10    const HALF_FULL_ROUNDS: usize,
11    const PARTIAL_ROUNDS: usize,
12> {
13    pub(crate) beginning_full_round_constants: [[F; WIDTH]; HALF_FULL_ROUNDS],
14    pub(crate) partial_round_constants: [F; PARTIAL_ROUNDS],
15    pub(crate) ending_full_round_constants: [[F; WIDTH]; HALF_FULL_ROUNDS],
16}
17
18impl<
19    F: PrimeCharacteristicRing,
20    const WIDTH: usize,
21    const HALF_FULL_ROUNDS: usize,
22    const PARTIAL_ROUNDS: usize,
23> RoundConstants<F, WIDTH, HALF_FULL_ROUNDS, PARTIAL_ROUNDS>
24{
25    pub const fn new(
26        beginning_full_round_constants: [[F; WIDTH]; HALF_FULL_ROUNDS],
27        partial_round_constants: [F; PARTIAL_ROUNDS],
28        ending_full_round_constants: [[F; WIDTH]; HALF_FULL_ROUNDS],
29    ) -> Self {
30        Self {
31            beginning_full_round_constants,
32            partial_round_constants,
33            ending_full_round_constants,
34        }
35    }
36
37    pub fn from_rng<R: Rng>(rng: &mut R) -> Self
38    where
39        StandardUniform: Distribution<F> + Distribution<[F; WIDTH]>,
40    {
41        Self {
42            beginning_full_round_constants: core::array::from_fn(|_| rng.sample(StandardUniform)),
43            partial_round_constants: core::array::from_fn(|_| rng.sample(StandardUniform)),
44            ending_full_round_constants: core::array::from_fn(|_| rng.sample(StandardUniform)),
45        }
46    }
47}