openvm_stark_sdk/
cost_estimate.rs1use std::{marker::PhantomData, ops::Add};
2
3use openvm_stark_backend::{
4 config::{Com, StarkGenericConfig, Val},
5 keygen::types::StarkVerifyingKey,
6 p3_field::FieldExtensionAlgebra,
7};
8
9use crate::config::FriParameters;
10
11#[derive(Clone, Copy, Debug)]
13pub struct VerifierCostParameters {
14 pub num_main_columns: usize,
16 pub num_perm_columns: usize,
18 pub log_max_height: usize,
20 pub quotient_degree: usize,
22}
23
24#[derive(Clone, Copy, Debug)]
32pub struct MmcsVerifyBatchCostEstimate {
33 pub num_f_to_hash: usize,
36 pub num_compress: usize,
38}
39
40impl MmcsVerifyBatchCostEstimate {
41 pub fn from_dim(width: usize, max_log_height_lde: usize) -> Self {
44 Self {
45 num_f_to_hash: width,
46 num_compress: max_log_height_lde,
47 }
48 }
49}
50
51impl Add for MmcsVerifyBatchCostEstimate {
52 type Output = Self;
53
54 fn add(self, rhs: Self) -> Self::Output {
55 Self {
56 num_f_to_hash: self.num_f_to_hash + rhs.num_f_to_hash,
57 num_compress: self.num_compress + rhs.num_compress,
58 }
59 }
60}
61
62#[derive(Clone, Copy, Debug)]
63pub struct FriOpenInputCostEstimate {
64 pub mmcs: MmcsVerifyBatchCostEstimate,
66 pub num_ro_eval: usize,
69}
70
71impl FriOpenInputCostEstimate {
72 pub fn new(
76 width: usize,
77 max_log_height: usize,
78 num_points: usize,
79 fri_params: FriParameters,
80 ) -> Self {
81 let mut mmcs =
82 MmcsVerifyBatchCostEstimate::from_dim(width, max_log_height + fri_params.log_blowup);
83 mmcs.num_compress *= fri_params.num_queries;
84 mmcs.num_f_to_hash *= fri_params.num_queries;
85 let num_ro_eval = width * num_points * fri_params.num_queries;
86 Self {
87 mmcs: MmcsVerifyBatchCostEstimate::from_dim(width, max_log_height),
88 num_ro_eval,
89 }
90 }
91}
92
93impl Add for FriOpenInputCostEstimate {
94 type Output = Self;
95
96 fn add(self, rhs: Self) -> Self::Output {
97 Self {
98 mmcs: self.mmcs + rhs.mmcs,
99 num_ro_eval: self.num_ro_eval + rhs.num_ro_eval,
100 }
101 }
102}
103
104pub struct FriQueryCostEstimate {
105 pub mmcs: MmcsVerifyBatchCostEstimate,
107 pub num_fri_folds: usize,
109}
110
111impl FriQueryCostEstimate {
112 pub fn new(max_log_height: usize, fri_params: FriParameters) -> Self {
114 let mut mmcs = MmcsVerifyBatchCostEstimate {
115 num_f_to_hash: 2 * max_log_height,
116 num_compress: max_log_height * (max_log_height + fri_params.log_blowup - 1) / 2,
117 };
118 mmcs.num_compress *= fri_params.num_queries;
119 mmcs.num_f_to_hash *= fri_params.num_queries;
120 let num_fri_folds = max_log_height * fri_params.num_queries;
121 Self {
122 mmcs,
123 num_fri_folds,
124 }
125 }
126}
127
128impl Add for FriQueryCostEstimate {
129 type Output = Self;
130
131 fn add(self, rhs: Self) -> Self::Output {
132 Self {
133 mmcs: self.mmcs + rhs.mmcs,
134 num_fri_folds: self.num_fri_folds + rhs.num_fri_folds,
135 }
136 }
137}
138
139pub struct FriVerifierCostEstimate {
140 pub open_input: FriOpenInputCostEstimate,
141 pub query: FriQueryCostEstimate,
142 pub constraint_eval: PhantomData<usize>,
145}
146
147impl FriVerifierCostEstimate {
148 pub fn new(
149 params: VerifierCostParameters,
150 fri_params: FriParameters,
151 ext_degree: usize,
152 ) -> Self {
153 let mut open_input = FriOpenInputCostEstimate::new(
160 params.num_main_columns,
161 params.log_max_height,
162 2,
163 fri_params,
164 );
165 let mut query = FriQueryCostEstimate::new(params.log_max_height, fri_params);
166
167 open_input = open_input
170 + FriOpenInputCostEstimate::new(
171 params.num_perm_columns,
172 params.log_max_height,
173 2,
174 fri_params,
175 );
176 query = query + FriQueryCostEstimate::new(params.log_max_height, fri_params);
177
178 open_input = open_input
181 + FriOpenInputCostEstimate::new(
182 params.quotient_degree * ext_degree,
183 params.log_max_height,
184 1,
185 fri_params,
186 );
187 query = query + FriQueryCostEstimate::new(params.log_max_height, fri_params);
188
189 Self {
190 open_input,
191 query,
192 constraint_eval: PhantomData,
193 }
194 }
195
196 pub fn from_vk<SC: StarkGenericConfig>(
197 vks: &[&StarkVerifyingKey<Val<SC>, Com<SC>>],
198 fri_params: FriParameters,
199 log_max_height: usize,
200 ) -> Self {
201 let num_main_columns: usize = vks
202 .iter()
203 .map(|vk| {
204 vk.params.width.common_main + vk.params.width.cached_mains.iter().sum::<usize>()
205 })
206 .sum();
207 let ext_degree = <SC::Challenge as FieldExtensionAlgebra<Val<SC>>>::D;
208 let num_perm_columns: usize = vks
209 .iter()
210 .map(|vk| vk.params.width.after_challenge.iter().sum::<usize>())
211 .sum::<usize>()
212 * ext_degree;
213 let quotient_degree = vks.iter().map(|vk| vk.quotient_degree).max().unwrap_or(0) as usize;
214 Self::new(
215 VerifierCostParameters {
216 num_main_columns,
217 num_perm_columns,
218 log_max_height,
219 quotient_degree,
220 },
221 fri_params,
222 ext_degree,
223 )
224 }
225}