snarkvm_circuit_algorithms/poseidon/
mod.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16mod hash;
17mod hash_many;
18mod hash_to_group;
19mod hash_to_scalar;
20mod prf;
21
22#[cfg(all(test, feature = "console"))]
23use snarkvm_circuit_types::environment::assert_scope;
24#[cfg(test)]
25use snarkvm_utilities::{TestRng, Uniform};
26
27use crate::{Elligator2, Hash, HashMany, HashToGroup, HashToScalar, PRF};
28use snarkvm_circuit_types::{Field, Group, Scalar, environment::prelude::*};
29
30/// Poseidon2 is a cryptographic hash function of input rate 2.
31pub type Poseidon2<E> = Poseidon<E, 2>;
32/// Poseidon4 is a cryptographic hash function of input rate 4.
33pub type Poseidon4<E> = Poseidon<E, 4>;
34/// Poseidon8 is a cryptographic hash function of input rate 8.
35pub type Poseidon8<E> = Poseidon<E, 8>;
36
37const CAPACITY: usize = 1;
38
39/// The mode structure for duplex sponges.
40#[derive(PartialEq, Eq, Clone, Debug)]
41pub enum DuplexSpongeMode {
42    /// The sponge is currently absorbing data.
43    Absorbing {
44        /// The next position of the state to be XOR-ed when absorbing.
45        next_absorb_index: usize,
46    },
47    /// The sponge is currently squeezing data out.
48    Squeezing {
49        /// The next position of the state to be outputted when squeezing.
50        next_squeeze_index: usize,
51    },
52}
53
54#[derive(Clone)]
55pub struct Poseidon<E: Environment, const RATE: usize> {
56    /// The domain separator for the Poseidon hash function.
57    domain: Field<E>,
58    /// The number of rounds in a full-round operation.
59    full_rounds: usize,
60    /// The number of rounds in a partial-round operation.
61    partial_rounds: usize,
62    /// The exponent used in S-boxes.
63    alpha: Field<E>,
64    /// The additive round keys. These are added before each MDS matrix application to make it an affine shift.
65    /// They are indexed by `ark[round_number][state_element_index]`
66    ark: Vec<Vec<Field<E>>>,
67    /// The Maximally Distance Separating (MDS) matrix.
68    mds: Vec<Vec<Field<E>>>,
69}
70
71#[cfg(feature = "console")]
72impl<E: Environment, const RATE: usize> Inject for Poseidon<E, RATE> {
73    type Primitive = console::Poseidon<E::Network, RATE>;
74
75    fn new(_mode: Mode, poseidon: Self::Primitive) -> Self {
76        // Initialize the domain separator.
77        let domain = Field::constant(poseidon.domain());
78
79        // Initialize the Poseidon parameters.
80        let parameters = poseidon.parameters();
81        let full_rounds = parameters.full_rounds;
82        let partial_rounds = parameters.partial_rounds;
83        let alpha = Field::constant(console::Field::from_u128(parameters.alpha as u128));
84        // Cache the bits for the field element.
85        alpha.to_bits_le();
86        let ark = parameters
87            .ark
88            .iter()
89            .take(full_rounds + partial_rounds)
90            .map(|round| {
91                round.iter().take(RATE + 1).copied().map(|field| Field::constant(console::Field::new(field))).collect()
92            })
93            .collect();
94        let mds = parameters
95            .mds
96            .iter()
97            .take(RATE + 1)
98            .map(|round| {
99                round.iter().take(RATE + 1).copied().map(|field| Field::constant(console::Field::new(field))).collect()
100            })
101            .collect();
102
103        Self { domain, full_rounds, partial_rounds, alpha, ark, mds }
104    }
105}