use crate::stark::StarkGenericConfig;
use p3_baby_bear::{BabyBear, DiffusionMatrixBabyBear};
use p3_challenger::DuplexChallenger;
use p3_commit::ExtensionMmcs;
use p3_dft::Radix2DitParallel;
use p3_field::{extension::BinomialExtensionField, Field};
use p3_fri::BatchOpening;
use p3_fri::CommitPhaseProofStep;
use p3_fri::QueryProof;
use p3_fri::{FriConfig, FriProof, TwoAdicFriPcs, TwoAdicFriPcsProof};
use p3_merkle_tree::FieldMerkleTreeMmcs;
use p3_poseidon2::Poseidon2;
use p3_poseidon2::Poseidon2ExternalMatrixGeneral;
use p3_symmetric::Hash;
use p3_symmetric::{PaddingFreeSponge, TruncatedPermutation};
use serde::Deserialize;
use serde::Serialize;
use sp1_primitives::poseidon2_init;
pub const DIGEST_SIZE: usize = 8;
pub type InnerVal = BabyBear;
pub type InnerChallenge = BinomialExtensionField<InnerVal, 4>;
pub type InnerPerm =
Poseidon2<InnerVal, Poseidon2ExternalMatrixGeneral, DiffusionMatrixBabyBear, 16, 7>;
pub type InnerHash = PaddingFreeSponge<InnerPerm, 16, 8, 8>;
pub type InnerDigestHash = Hash<InnerVal, InnerVal, DIGEST_SIZE>;
pub type InnerDigest = [InnerVal; DIGEST_SIZE];
pub type InnerCompress = TruncatedPermutation<InnerPerm, 2, 8, 16>;
pub type InnerValMmcs = FieldMerkleTreeMmcs<
<InnerVal as Field>::Packing,
<InnerVal as Field>::Packing,
InnerHash,
InnerCompress,
8,
>;
pub type InnerChallengeMmcs = ExtensionMmcs<InnerVal, InnerChallenge, InnerValMmcs>;
pub type InnerChallenger = DuplexChallenger<InnerVal, InnerPerm, 16, 8>;
pub type InnerDft = Radix2DitParallel;
pub type InnerPcs = TwoAdicFriPcs<InnerVal, InnerDft, InnerValMmcs, InnerChallengeMmcs>;
pub type InnerQueryProof = QueryProof<InnerChallenge, InnerChallengeMmcs>;
pub type InnerCommitPhaseStep = CommitPhaseProofStep<InnerChallenge, InnerChallengeMmcs>;
pub type InnerFriProof = FriProof<InnerChallenge, InnerChallengeMmcs, InnerVal>;
pub type InnerBatchOpening = BatchOpening<InnerVal, InnerValMmcs>;
pub type InnerPcsProof =
TwoAdicFriPcsProof<InnerVal, InnerChallenge, InnerValMmcs, InnerChallengeMmcs>;
pub fn inner_perm() -> InnerPerm {
poseidon2_init()
}
pub fn sp1_fri_config() -> FriConfig<InnerChallengeMmcs> {
let perm = inner_perm();
let hash = InnerHash::new(perm.clone());
let compress = InnerCompress::new(perm.clone());
let challenge_mmcs = InnerChallengeMmcs::new(InnerValMmcs::new(hash, compress));
let num_queries = match std::env::var("FRI_QUERIES") {
Ok(value) => value.parse().unwrap(),
Err(_) => 100,
};
FriConfig {
log_blowup: 1,
num_queries,
proof_of_work_bits: 16,
mmcs: challenge_mmcs,
}
}
pub fn inner_fri_config() -> FriConfig<InnerChallengeMmcs> {
let perm = inner_perm();
let hash = InnerHash::new(perm.clone());
let compress = InnerCompress::new(perm.clone());
let challenge_mmcs = InnerChallengeMmcs::new(InnerValMmcs::new(hash, compress));
let num_queries = match std::env::var("FRI_QUERIES") {
Ok(value) => value.parse().unwrap(),
Err(_) => 100,
};
FriConfig {
log_blowup: 1,
num_queries,
proof_of_work_bits: 16,
mmcs: challenge_mmcs,
}
}
#[derive(Deserialize)]
#[serde(from = "std::marker::PhantomData<BabyBearPoseidon2Inner>")]
pub struct BabyBearPoseidon2Inner {
pub perm: InnerPerm,
pub pcs: InnerPcs,
}
impl Clone for BabyBearPoseidon2Inner {
fn clone(&self) -> Self {
Self::new()
}
}
impl Serialize for BabyBearPoseidon2Inner {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
std::marker::PhantomData::<BabyBearPoseidon2Inner>.serialize(serializer)
}
}
impl From<std::marker::PhantomData<BabyBearPoseidon2Inner>> for BabyBearPoseidon2Inner {
fn from(_: std::marker::PhantomData<BabyBearPoseidon2Inner>) -> Self {
Self::new()
}
}
impl BabyBearPoseidon2Inner {
pub fn new() -> Self {
let perm = inner_perm();
let hash = InnerHash::new(perm.clone());
let compress = InnerCompress::new(perm.clone());
let val_mmcs = InnerValMmcs::new(hash, compress);
let dft = InnerDft {};
let fri_config = inner_fri_config();
let pcs = InnerPcs::new(27, dft, val_mmcs, fri_config);
Self { pcs, perm }
}
}
impl Default for BabyBearPoseidon2Inner {
fn default() -> Self {
Self::new()
}
}
impl StarkGenericConfig for BabyBearPoseidon2Inner {
type Val = InnerVal;
type Domain = <InnerPcs as p3_commit::Pcs<InnerChallenge, InnerChallenger>>::Domain;
type Pcs = InnerPcs;
type Challenge = InnerChallenge;
type Challenger = InnerChallenger;
fn pcs(&self) -> &Self::Pcs {
&self.pcs
}
fn challenger(&self) -> Self::Challenger {
InnerChallenger::new(self.perm.clone())
}
}