sp1_recursion_core/stark/
config.rs1use p3_baby_bear::BabyBear;
2use p3_bn254_fr::{Bn254Fr, DiffusionMatrixBN254};
3use p3_challenger::MultiField32Challenger;
4use p3_commit::ExtensionMmcs;
5use p3_dft::Radix2DitParallel;
6use p3_field::{extension::BinomialExtensionField, AbstractField};
7use p3_fri::{
8 BatchOpening, CommitPhaseProofStep, FriConfig, FriProof, QueryProof, TwoAdicFriPcs,
9 TwoAdicFriPcsProof,
10};
11use p3_merkle_tree::FieldMerkleTreeMmcs;
12use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixGeneral};
13use p3_symmetric::{Hash, MultiField32PaddingFreeSponge, TruncatedPermutation};
14use serde::{Deserialize, Serialize};
15use sp1_stark::{Com, StarkGenericConfig, ZeroCommitment};
16
17use super::{poseidon2::bn254_poseidon2_rc3, sp1_dev_mode};
18
19pub const DIGEST_SIZE: usize = 1;
20
21pub const OUTER_MULTI_FIELD_CHALLENGER_WIDTH: usize = 3;
22pub const OUTER_MULTI_FIELD_CHALLENGER_RATE: usize = 2;
23pub const OUTER_MULTI_FIELD_CHALLENGER_DIGEST_SIZE: usize = 1;
24
25pub type OuterVal = BabyBear;
27pub type OuterChallenge = BinomialExtensionField<OuterVal, 4>;
28pub type OuterPerm = Poseidon2<Bn254Fr, Poseidon2ExternalMatrixGeneral, DiffusionMatrixBN254, 3, 5>;
29pub type OuterHash =
30 MultiField32PaddingFreeSponge<OuterVal, Bn254Fr, OuterPerm, 3, 16, DIGEST_SIZE>;
31pub type OuterDigestHash = Hash<OuterVal, Bn254Fr, DIGEST_SIZE>;
32pub type OuterDigest = [Bn254Fr; DIGEST_SIZE];
33pub type OuterCompress = TruncatedPermutation<OuterPerm, 2, 1, 3>;
34pub type OuterValMmcs = FieldMerkleTreeMmcs<BabyBear, Bn254Fr, OuterHash, OuterCompress, 1>;
35pub type OuterChallengeMmcs = ExtensionMmcs<OuterVal, OuterChallenge, OuterValMmcs>;
36pub type OuterDft = Radix2DitParallel;
37pub type OuterChallenger = MultiField32Challenger<
38 OuterVal,
39 Bn254Fr,
40 OuterPerm,
41 OUTER_MULTI_FIELD_CHALLENGER_WIDTH,
42 OUTER_MULTI_FIELD_CHALLENGER_RATE,
43>;
44pub type OuterPcs = TwoAdicFriPcs<OuterVal, OuterDft, OuterValMmcs, OuterChallengeMmcs>;
45
46pub type OuterQueryProof = QueryProof<OuterChallenge, OuterChallengeMmcs>;
47pub type OuterCommitPhaseStep = CommitPhaseProofStep<OuterChallenge, OuterChallengeMmcs>;
48pub type OuterFriProof = FriProof<OuterChallenge, OuterChallengeMmcs, OuterVal>;
49pub type OuterBatchOpening = BatchOpening<OuterVal, OuterValMmcs>;
50pub type OuterPcsProof =
51 TwoAdicFriPcsProof<OuterVal, OuterChallenge, OuterValMmcs, OuterChallengeMmcs>;
52
53pub fn outer_perm() -> OuterPerm {
55 const ROUNDS_F: usize = 8;
56 const ROUNDS_P: usize = 56;
57 let mut round_constants = bn254_poseidon2_rc3();
58 let internal_start = ROUNDS_F / 2;
59 let internal_end = (ROUNDS_F / 2) + ROUNDS_P;
60 let internal_round_constants =
61 round_constants.drain(internal_start..internal_end).map(|vec| vec[0]).collect::<Vec<_>>();
62 let external_round_constants = round_constants;
63 OuterPerm::new(
64 ROUNDS_F,
65 external_round_constants,
66 Poseidon2ExternalMatrixGeneral,
67 ROUNDS_P,
68 internal_round_constants,
69 DiffusionMatrixBN254,
70 )
71}
72
73pub fn outer_fri_config() -> FriConfig<OuterChallengeMmcs> {
75 let perm = outer_perm();
76 let hash = OuterHash::new(perm.clone()).unwrap();
77 let compress = OuterCompress::new(perm.clone());
78 let challenge_mmcs = OuterChallengeMmcs::new(OuterValMmcs::new(hash, compress));
79 let num_queries = if sp1_dev_mode() {
80 1
81 } else {
82 match std::env::var("FRI_QUERIES") {
83 Ok(value) => value.parse().unwrap(),
84 Err(_) => 25,
85 }
86 };
87 FriConfig { log_blowup: 4, num_queries, proof_of_work_bits: 16, mmcs: challenge_mmcs }
88}
89
90pub fn outer_fri_config_with_blowup(log_blowup: usize) -> FriConfig<OuterChallengeMmcs> {
92 let perm = outer_perm();
93 let hash = OuterHash::new(perm.clone()).unwrap();
94 let compress = OuterCompress::new(perm.clone());
95 let challenge_mmcs = OuterChallengeMmcs::new(OuterValMmcs::new(hash, compress));
96 let num_queries = if sp1_dev_mode() {
97 1
98 } else {
99 match std::env::var("FRI_QUERIES") {
100 Ok(value) => value.parse().unwrap(),
101 Err(_) => 100 / log_blowup,
102 }
103 };
104 FriConfig { log_blowup, num_queries, proof_of_work_bits: 16, mmcs: challenge_mmcs }
105}
106
107#[derive(Deserialize)]
108#[serde(from = "std::marker::PhantomData<BabyBearPoseidon2Outer>")]
109pub struct BabyBearPoseidon2Outer {
110 pub perm: OuterPerm,
111 pub pcs: OuterPcs,
112}
113
114impl Clone for BabyBearPoseidon2Outer {
115 fn clone(&self) -> Self {
116 Self::new()
117 }
118}
119
120impl Serialize for BabyBearPoseidon2Outer {
121 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
122 where
123 S: serde::Serializer,
124 {
125 std::marker::PhantomData::<BabyBearPoseidon2Outer>.serialize(serializer)
126 }
127}
128
129impl From<std::marker::PhantomData<BabyBearPoseidon2Outer>> for BabyBearPoseidon2Outer {
130 fn from(_: std::marker::PhantomData<BabyBearPoseidon2Outer>) -> Self {
131 Self::new()
132 }
133}
134
135impl BabyBearPoseidon2Outer {
136 pub fn new() -> Self {
137 let perm = outer_perm();
138 let hash = OuterHash::new(perm.clone()).unwrap();
139 let compress = OuterCompress::new(perm.clone());
140 let val_mmcs = OuterValMmcs::new(hash, compress);
141 let dft = OuterDft {};
142 let fri_config = outer_fri_config();
143 let pcs = OuterPcs::new(27, dft, val_mmcs, fri_config);
144 Self { pcs, perm }
145 }
146 pub fn new_with_log_blowup(log_blowup: usize) -> Self {
147 let perm = outer_perm();
148 let hash = OuterHash::new(perm.clone()).unwrap();
149 let compress = OuterCompress::new(perm.clone());
150 let val_mmcs = OuterValMmcs::new(hash, compress);
151 let dft = OuterDft {};
152 let fri_config = outer_fri_config_with_blowup(log_blowup);
153 let pcs = OuterPcs::new(27, dft, val_mmcs, fri_config);
154 Self { pcs, perm }
155 }
156}
157
158impl Default for BabyBearPoseidon2Outer {
159 fn default() -> Self {
160 Self::new()
161 }
162}
163
164impl StarkGenericConfig for BabyBearPoseidon2Outer {
165 type Val = OuterVal;
166 type Domain = <OuterPcs as p3_commit::Pcs<OuterChallenge, OuterChallenger>>::Domain;
167 type Pcs = OuterPcs;
168 type Challenge = OuterChallenge;
169 type Challenger = OuterChallenger;
170
171 fn pcs(&self) -> &Self::Pcs {
172 &self.pcs
173 }
174
175 fn challenger(&self) -> Self::Challenger {
176 OuterChallenger::new(self.perm.clone()).unwrap()
177 }
178}
179
180impl ZeroCommitment<BabyBearPoseidon2Outer> for OuterPcs {
181 fn zero_commitment(&self) -> Com<BabyBearPoseidon2Outer> {
182 OuterDigestHash::from([Bn254Fr::zero(); DIGEST_SIZE])
183 }
184}
185
186pub fn test_fri_config() -> FriConfig<OuterChallengeMmcs> {
188 let perm = outer_perm();
189 let hash = OuterHash::new(perm.clone()).unwrap();
190 let compress = OuterCompress::new(perm.clone());
191 let challenge_mmcs = OuterChallengeMmcs::new(OuterValMmcs::new(hash, compress));
192 FriConfig { log_blowup: 1, num_queries: 1, proof_of_work_bits: 1, mmcs: challenge_mmcs }
193}