1use std::sync::Arc;
2
3use openvm_stark_backend::{
4 config::StarkConfig,
5 interaction::fri_log_up::FriLogUpPhase,
6 p3_challenger::{HashChallenger, SerializingChallenger32},
7 p3_commit::ExtensionMmcs,
8 p3_field::extension::BinomialExtensionField,
9 prover::{
10 cpu::{CpuBackend, CpuDevice},
11 MultiTraceStarkProver,
12 },
13};
14use p3_baby_bear::BabyBear;
15use p3_dft::Radix2DitParallel;
16use p3_fri::{FriParameters as P3FriParameters, TwoAdicFriPcs};
17use p3_merkle_tree::MerkleTreeMmcs;
18use p3_symmetric::{CompressionFunctionFromHasher, CryptographicHasher, SerializingHasher};
19
20use super::FriParameters;
21use crate::{
22 config::fri_params::SecurityParameters,
23 engine::{StarkEngine, StarkFriEngine},
24};
25
26type Val = BabyBear;
27type Challenge = BinomialExtensionField<Val, 4>;
28
29type FieldHash<H> = SerializingHasher<H>;
31type Compress<H> = CompressionFunctionFromHasher<H, 2, 32>;
32type ValMmcs<H> = MerkleTreeMmcs<Val, u8, FieldHash<H>, Compress<H>, 32>;
35type ChallengeMmcs<H> = ExtensionMmcs<Val, Challenge, ValMmcs<H>>;
36type Dft = Radix2DitParallel<Val>;
37type Challenger<H> = SerializingChallenger32<Val, HashChallenger<u8, H, 32>>;
38
39type Pcs<H> = TwoAdicFriPcs<Val, Dft, ValMmcs<H>, ChallengeMmcs<H>>;
40
41type RapPhase<H> = FriLogUpPhase<Val, Challenge, Challenger<H>>;
42
43pub type BabyBearByteHashConfig<H> = StarkConfig<Pcs<H>, RapPhase<H>, Challenge, Challenger<H>>;
44
45pub struct BabyBearByteHashEngine<H>
46where
47 H: CryptographicHasher<u8, [u8; 32]> + Clone,
48{
49 pub fri_params: FriParameters,
50 pub device: CpuDevice<BabyBearByteHashConfig<H>>,
51 pub byte_hash: H,
52 pub max_constraint_degree: usize,
53}
54
55impl<H> StarkEngine for BabyBearByteHashEngine<H>
56where
57 H: CryptographicHasher<u8, [u8; 32]> + Clone + Send + Sync,
58{
59 type SC = BabyBearByteHashConfig<H>;
60 type PB = CpuBackend<Self::SC>;
61 type PD = CpuDevice<Self::SC>;
62
63 fn config(&self) -> &BabyBearByteHashConfig<H> {
64 &self.device.config
65 }
66
67 fn device(&self) -> &CpuDevice<BabyBearByteHashConfig<H>> {
68 &self.device
69 }
70
71 fn prover(&self) -> MultiTraceStarkProver<BabyBearByteHashConfig<H>> {
72 MultiTraceStarkProver::new(
73 CpuBackend::default(),
74 self.device.clone(),
75 self.new_challenger(),
76 )
77 }
78
79 fn max_constraint_degree(&self) -> Option<usize> {
80 Some(self.max_constraint_degree)
81 }
82
83 fn new_challenger(&self) -> Challenger<H> {
84 Challenger::from_hasher(vec![], self.byte_hash.clone())
85 }
86}
87
88pub fn default_engine<H>(byte_hash: H) -> BabyBearByteHashEngine<H>
90where
91 H: CryptographicHasher<u8, [u8; 32]> + Clone,
92{
93 engine_from_byte_hash(byte_hash, SecurityParameters::standard_fast())
94}
95
96pub fn engine_from_byte_hash<H>(
97 byte_hash: H,
98 security_params: SecurityParameters,
99) -> BabyBearByteHashEngine<H>
100where
101 H: CryptographicHasher<u8, [u8; 32]> + Clone,
102{
103 let fri_params = security_params.fri_params;
104 let max_constraint_degree = fri_params.max_constraint_degree();
105 let config = config_from_byte_hash(byte_hash.clone(), security_params);
106 BabyBearByteHashEngine {
107 device: CpuDevice::new(Arc::new(config), fri_params.log_blowup),
108 byte_hash,
109 fri_params,
110 max_constraint_degree,
111 }
112}
113
114pub fn config_from_byte_hash<H>(
115 byte_hash: H,
116 security_params: SecurityParameters,
117) -> BabyBearByteHashConfig<H>
118where
119 H: CryptographicHasher<u8, [u8; 32]> + Clone,
120{
121 let field_hash = FieldHash::new(byte_hash.clone());
122 let compress = Compress::new(byte_hash.clone());
123 let val_mmcs = ValMmcs::new(field_hash, compress);
124 let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone());
125 let dft = Dft::default();
126 let SecurityParameters {
127 fri_params,
128 log_up_params,
129 deep_ali_params,
130 } = security_params;
131 let fri_config = P3FriParameters {
132 log_blowup: fri_params.log_blowup,
133 log_final_poly_len: fri_params.log_final_poly_len,
134 num_queries: fri_params.num_queries,
135 commit_proof_of_work_bits: fri_params.commit_proof_of_work_bits,
136 query_proof_of_work_bits: fri_params.query_proof_of_work_bits,
137 mmcs: challenge_mmcs,
138 };
139 let pcs = Pcs::new(dft, val_mmcs, fri_config);
140 let challenger = Challenger::from_hasher(vec![], byte_hash);
141 let rap_phase = FriLogUpPhase::new(log_up_params, fri_params.log_blowup);
142 BabyBearByteHashConfig::new(pcs, challenger, rap_phase, deep_ali_params)
143}
144
145pub trait BabyBearByteHashEngineWithDefaultHash<H>
146where
147 H: CryptographicHasher<u8, [u8; 32]> + Clone,
148{
149 fn default_hash() -> H;
150}
151
152impl<H: CryptographicHasher<u8, [u8; 32]> + Clone + Send + Sync> StarkFriEngine
153 for BabyBearByteHashEngine<H>
154where
155 BabyBearByteHashEngine<H>: BabyBearByteHashEngineWithDefaultHash<H>,
156{
157 fn new(fri_params: FriParameters) -> Self {
158 let security_params = SecurityParameters::new_baby_bear_100_bits(fri_params);
159 engine_from_byte_hash(Self::default_hash(), security_params)
160 }
161 fn fri_params(&self) -> FriParameters {
162 self.fri_params
163 }
164}