openvm_stark_sdk/config/
baby_bear_bytehash.rs

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