openvm_static_verifier/hash/
mod.rs

1use core::array;
2use std::sync::LazyLock;
3
4use halo2_base::utils::biguint_to_fe;
5pub(crate) use openvm_stark_sdk::config::baby_bear_bn254_poseidon2::SPONGE_WIDTH as POSEIDON2_WIDTH;
6use openvm_stark_sdk::{
7    config::bn254_poseidon2::{
8        default_bn254_poseidon2_width2_constants, default_bn254_poseidon2_width3_constants,
9        Poseidon2Bn254Constants,
10    },
11    openvm_stark_backend::p3_field::PrimeField,
12};
13
14use crate::Fr;
15
16pub mod poseidon2;
17use poseidon2::Poseidon2Params;
18
19/// Width-2 compression permutation width.
20const COMPRESS_WIDTH: usize = 2;
21
22/// Convert `Poseidon2Bn254Constants` from stark-backend into halo2 `Poseidon2Params`.
23fn bn254_constants_to_params<const WIDTH: usize>(
24    constants: &Poseidon2Bn254Constants<WIDTH>,
25) -> Poseidon2Params<Fr, WIDTH> {
26    use openvm_stark_sdk::config::baby_bear_bn254_poseidon2::Bn254Scalar;
27
28    let bn254_to_fr = |elem: &Bn254Scalar| -> Fr { biguint_to_fe(&elem.as_canonical_biguint()) };
29
30    let initial_ext: Vec<[Fr; WIDTH]> = constants
31        .initial_external_rc()
32        .iter()
33        .map(|rc| array::from_fn(|i| bn254_to_fr(&rc[i])))
34        .collect();
35    let terminal_ext: Vec<[Fr; WIDTH]> = constants
36        .terminal_external_rc()
37        .iter()
38        .map(|rc| array::from_fn(|i| bn254_to_fr(&rc[i])))
39        .collect();
40    let internal_rc: Vec<Fr> = constants.internal_rc().iter().map(bn254_to_fr).collect();
41    let mat_internal_diag_m_1 =
42        array::from_fn(|i| bn254_to_fr(&constants.mat_internal_diag_m_1()[i]));
43
44    let mut external_rc = initial_ext;
45    external_rc.extend(terminal_ext);
46
47    let rounds_f = external_rc.len();
48    let rounds_p = internal_rc.len();
49    Poseidon2Params::new(
50        rounds_f,
51        rounds_p,
52        mat_internal_diag_m_1,
53        external_rc,
54        internal_rc,
55    )
56}
57
58/// Width-3 Poseidon2 params for leaf hashing and transcript sponge.
59pub(crate) static POSEIDON2_PARAMS: LazyLock<Poseidon2Params<Fr, POSEIDON2_WIDTH>> =
60    LazyLock::new(|| bn254_constants_to_params(default_bn254_poseidon2_width3_constants()));
61
62/// Width-2 Poseidon2 params for Merkle compression (gnark-crypto compatible).
63pub(crate) static POSEIDON2_COMPRESS_PARAMS: LazyLock<Poseidon2Params<Fr, COMPRESS_WIDTH>> =
64    LazyLock::new(|| bn254_constants_to_params(default_bn254_poseidon2_width2_constants()));