use alloc::vec;
use miden_core::{Felt, field::QuadFelt};
use miden_crypto::{
field::Field,
hash::{
blake::Blake3Hasher, keccak::Keccak256Hash, poseidon2::Poseidon2Permutation256,
rpo::RpoPermutation256, rpx::RpxPermutation256,
},
stark::{
GenericStarkConfig,
challenger::{DuplexChallenger, HashChallenger, SerializingChallenger64},
dft::Radix2DitParallel,
fri::PcsParams,
hasher::{ChainingHasher, StatefulSponge},
lmcs::LmcsConfig,
symmetric::{CompressionFunctionFromHasher, TruncatedPermutation},
},
};
const LOG_BLOWUP: u8 = 3;
const LOG_FOLDING_ARITY: u8 = 2;
const LOG_FINAL_DEGREE: u8 = 7;
const FOLDING_POW_BITS: usize = 16;
const DEEP_POW_BITS: usize = 0;
const NUM_QUERIES: usize = 27;
const QUERY_POW_BITS: usize = 0;
pub fn pcs_params() -> PcsParams {
PcsParams::new(
LOG_BLOWUP,
LOG_FOLDING_ARITY,
LOG_FINAL_DEGREE,
FOLDING_POW_BITS,
DEEP_POW_BITS,
NUM_QUERIES,
QUERY_POW_BITS,
)
.expect("invalid PCS parameters")
}
const BYTE_DIGEST_SIZE: usize = 32;
const COMPRESSION_INPUTS: usize = 2;
const SPONGE_WIDTH: usize = 12;
const SPONGE_RATE: usize = 8;
const DIGEST_WIDTH: usize = 4;
type PackedFelt = <Felt as Field>::Packing;
pub type MidenStarkConfig<L, Ch> =
GenericStarkConfig<Felt, QuadFelt, L, Radix2DitParallel<Felt>, Ch>;
type ByteLmcs<H> = LmcsConfig<
Felt,
u8,
ChainingHasher<H>,
CompressionFunctionFromHasher<H, COMPRESSION_INPUTS, BYTE_DIGEST_SIZE>,
BYTE_DIGEST_SIZE,
BYTE_DIGEST_SIZE,
>;
type ByteChallenger<H> = SerializingChallenger64<Felt, HashChallenger<u8, H, BYTE_DIGEST_SIZE>>;
type AlgLmcs<P> = LmcsConfig<
PackedFelt,
PackedFelt,
StatefulSponge<P, SPONGE_WIDTH, SPONGE_RATE, DIGEST_WIDTH>,
TruncatedPermutation<P, COMPRESSION_INPUTS, DIGEST_WIDTH, SPONGE_WIDTH>,
SPONGE_WIDTH,
DIGEST_WIDTH,
>;
type AlgChallenger<P> = DuplexChallenger<Felt, P, SPONGE_WIDTH, SPONGE_RATE>;
pub fn blake3_256_config(
params: PcsParams,
) -> MidenStarkConfig<ByteLmcs<Blake3Hasher>, ByteChallenger<Blake3Hasher>> {
let lmcs = LmcsConfig::new(
ChainingHasher::new(Blake3Hasher),
CompressionFunctionFromHasher::new(Blake3Hasher),
);
let challenger = SerializingChallenger64::from_hasher(vec![], Blake3Hasher);
GenericStarkConfig::new(params, lmcs, Radix2DitParallel::default(), challenger)
}
pub fn keccak_config(
params: PcsParams,
) -> MidenStarkConfig<ByteLmcs<Keccak256Hash>, ByteChallenger<Keccak256Hash>> {
let hash = Keccak256Hash {};
let lmcs = LmcsConfig::new(ChainingHasher::new(hash), CompressionFunctionFromHasher::new(hash));
let challenger = SerializingChallenger64::from_hasher(vec![], hash);
GenericStarkConfig::new(params, lmcs, Radix2DitParallel::default(), challenger)
}
pub fn rpo_config(
params: PcsParams,
) -> MidenStarkConfig<AlgLmcs<RpoPermutation256>, AlgChallenger<RpoPermutation256>> {
let perm = RpoPermutation256;
let lmcs = LmcsConfig::new(StatefulSponge::new(perm), TruncatedPermutation::new(perm));
let challenger = DuplexChallenger::new(perm);
GenericStarkConfig::new(params, lmcs, Radix2DitParallel::default(), challenger)
}
pub fn poseidon2_config(
params: PcsParams,
) -> MidenStarkConfig<AlgLmcs<Poseidon2Permutation256>, AlgChallenger<Poseidon2Permutation256>> {
let perm = Poseidon2Permutation256;
let lmcs = LmcsConfig::new(StatefulSponge::new(perm), TruncatedPermutation::new(perm));
let challenger = DuplexChallenger::new(perm);
GenericStarkConfig::new(params, lmcs, Radix2DitParallel::default(), challenger)
}
pub fn rpx_config(
params: PcsParams,
) -> MidenStarkConfig<AlgLmcs<RpxPermutation256>, AlgChallenger<RpxPermutation256>> {
let perm = RpxPermutation256;
let lmcs = LmcsConfig::new(StatefulSponge::new(perm), TruncatedPermutation::new(perm));
let challenger = DuplexChallenger::new(perm);
GenericStarkConfig::new(params, lmcs, Radix2DitParallel::default(), challenger)
}