use std::any::type_name; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use p3_baby_bear::{BabyBear, DiffusionMatrixBabyBear}; use p3_bn254_fr::{Bn254Fr, DiffusionMatrixBN254}; use p3_field::{PrimeField, PrimeField64}; use p3_goldilocks::{DiffusionMatrixGoldilocks, Goldilocks}; use p3_koala_bear::{DiffusionMatrixKoalaBear, KoalaBear}; use p3_mersenne_31::{DiffusionMatrixMersenne31, Mersenne31}; use p3_poseidon2::{ DiffusionPermutation, MdsLightPermutation, Poseidon2, Poseidon2ExternalMatrixGeneral, }; use p3_symmetric::Permutation; use rand::distributions::{Distribution, Standard}; use rand::thread_rng; fn bench_poseidon2(c: &mut Criterion) { poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::(c); poseidon2_p64::( c, ); poseidon2_p64::( c, ); poseidon2_p64::(c); poseidon2_p64::( c, ); poseidon2_p64::( c, ); poseidon2::(c, 8, 22); } fn poseidon2( c: &mut Criterion, rounds_f: usize, rounds_p: usize, ) where F: PrimeField, Standard: Distribution, MdsLight: MdsLightPermutation + Default, Diffusion: DiffusionPermutation + Default, { let mut rng = thread_rng(); let external_linear_layer = MdsLight::default(); let internal_linear_layer = Diffusion::default(); let poseidon = Poseidon2::::new_from_rng( rounds_f, external_linear_layer, rounds_p, internal_linear_layer, &mut rng, ); let input = [F::zero(); WIDTH]; let name = format!( "poseidon2::<{}, {}, {}, {}>", type_name::(), D, rounds_f, rounds_p ); let id = BenchmarkId::new(name, WIDTH); c.bench_with_input(id, &input, |b, &input| b.iter(|| poseidon.permute(input))); } // For fields implementing PrimeField64 we should benchmark using the optimal round constants. fn poseidon2_p64(c: &mut Criterion) where F: PrimeField64, Standard: Distribution, MdsLight: MdsLightPermutation + Default, Diffusion: DiffusionPermutation + Default, { let mut rng = thread_rng(); let external_linear_layer = MdsLight::default(); let internal_linear_layer = Diffusion::default(); let poseidon = Poseidon2::::new_from_rng_128( external_linear_layer, internal_linear_layer, &mut rng, ); let input = [F::zero(); WIDTH]; let name = format!("poseidon2::<{}, {}>", type_name::(), D); let id = BenchmarkId::new(name, WIDTH); c.bench_with_input(id, &input, |b, &input| b.iter(|| poseidon.permute(input))); } criterion_group!(benches, bench_poseidon2); criterion_main!(benches);