1use crate::{permutation::Poseidon2Permutation, Poseidon2Params};
7use ark_ff::PrimeField;
8use spongefish::Unit;
9
10pub trait Poseidon2Sponge {}
12
13impl<F, const N: usize, const R: usize, P> Poseidon2Sponge for Poseidon2Permutation<F, N, R, P>
15where
16 F: PrimeField + Unit,
17 P: Poseidon2Params<F, N>,
18{
19}
20
21#[cfg(feature = "bls12-381")]
22pub mod bls12_381 {
24 #![allow(dead_code)]
25 use super::*;
26 use crate::constants::bls12_381::*;
27 use ark_bls12_381::Fr;
28 use spongefish::duplex_sponge::DuplexSponge;
29 pub type Poseidon2PermutationBlsN2R1 = Poseidon2Permutation<Fr, 2, 1, Poseidon2ParamsBls2>;
31 pub type Poseidon2SpongeBlsN2R1 = DuplexSponge<Poseidon2PermutationBlsN2R1>;
33
34 pub type Poseidon2PermutationBlsN3R1 = Poseidon2Permutation<Fr, 3, 1, Poseidon2ParamsBls3>;
36 pub type Poseidon2SpongeBlsN3R1 = DuplexSponge<Poseidon2PermutationBlsN3R1>;
38
39 pub type Poseidon2PermutationBlsN3R2 = Poseidon2Permutation<Fr, 3, 2, Poseidon2ParamsBls3>;
41 pub type Poseidon2SpongeBlsN3R2 = DuplexSponge<Poseidon2PermutationBlsN3R2>;
43
44 #[test]
45 fn test_bls_sponge() {
46 use super::tests::test_sponge;
47 test_sponge::<Fr, Poseidon2SpongeBlsN2R1>();
48 test_sponge::<Fr, Poseidon2SpongeBlsN3R1>();
49 test_sponge::<Fr, Poseidon2SpongeBlsN3R2>();
50 }
51}
52
53#[cfg(feature = "bn254")]
54pub mod bn254 {
56 #![allow(dead_code)]
57 use super::*;
58 use crate::constants::bn254::*;
59 use ark_bn254::Fr;
60 use spongefish::duplex_sponge::DuplexSponge;
61 pub type Poseidon2PermutationBnN3R1 = Poseidon2Permutation<Fr, 3, 1, Poseidon2ParamsBn3>;
63 pub type Poseidon2SpongeBnN3R1 = DuplexSponge<Poseidon2PermutationBnN3R1>;
65
66 pub type Poseidon2PermutationBnN3R2 = Poseidon2Permutation<Fr, 3, 2, Poseidon2ParamsBn3>;
68 pub type Poseidon2SpongeBnN3R2 = DuplexSponge<Poseidon2PermutationBnN3R2>;
70
71 #[test]
72 fn test_bn_sponge() {
73 use super::tests::test_sponge;
74 test_sponge::<Fr, Poseidon2SpongeBnN3R1>();
75 test_sponge::<Fr, Poseidon2SpongeBnN3R2>();
76 }
77}
78
79#[cfg(test)]
80pub(crate) mod tests {
81 use super::*;
82 use ark_ff::BigInteger;
83 use ark_std::vec::Vec;
84 use spongefish::codecs::arkworks_algebra::*;
85
86 pub(crate) fn test_sponge<F: PrimeField + Unit, H: DuplexSpongeInterface<F>>() {
87 let io = DomainSeparator::<H, F>::new("test")
88 .absorb(1, "in")
89 .squeeze(2048, "out");
90
91 let mut merlin = io.to_prover_state();
93 merlin.add_units(&[F::from(42u32)]).unwrap();
95
96 let mut merlin_challenges = [F::default(); 2048];
97 merlin.fill_challenge_units(&mut merlin_challenges).unwrap();
98
99 let mut arthur = io.to_verifier_state(merlin.narg_string());
101 arthur.fill_next_units(&mut [F::default()]).unwrap();
104 let mut arthur_challenges = [F::default(); 2048];
105 arthur.fill_challenge_units(&mut arthur_challenges).unwrap();
106
107 assert_eq!(merlin_challenges, arthur_challenges);
109
110 let chal_bytes: Vec<u8> = merlin_challenges
112 .iter()
113 .flat_map(|c| c.into_bigint().to_bytes_le())
114 .collect();
115 let frequencies = (0u8..=255)
116 .map(|i| chal_bytes.iter().filter(|&&x| x == i).count())
117 .collect::<Vec<_>>();
118 let expected_mean = (F::MODULUS_BIT_SIZE / 8 * 2048 / 256) as usize;
120 assert!(
121 frequencies
122 .iter()
123 .all(|&x| x < expected_mean * 2 && x > expected_mean / 2),
124 "Counts for each value shouldn't be too far away from mean: {:?}",
125 frequencies
126 );
127 }
128}