1// Keygen API for STARK backend
2// Changes:
3// - All AIRs can be optional
4use std::sync::Arc;
56use derivative::Derivative;
7use p3_matrix::dense::RowMajorMatrix;
8use serde::{Deserialize, Serialize};
910use crate::{
11 air_builders::symbolic::SymbolicConstraintsDag,
12 config::{Com, PcsProverData, RapPartialProvingKey, StarkGenericConfig, Val},
13 interaction::RapPhaseSeqKind,
14};
1516/// Widths of different parts of trace matrix
17#[derive(Clone, Debug, Serialize, Deserialize)]
18pub struct TraceWidth {
19pub preprocessed: Option<usize>,
20pub cached_mains: Vec<usize>,
21pub common_main: usize,
22/// Width counted by extension field elements, _not_ base field elements
23pub after_challenge: Vec<usize>,
24}
2526impl TraceWidth {
27/// Returns the widths of all main traces, including the common main trace if it exists.
28pub fn main_widths(&self) -> Vec<usize> {
29let mut ret = self.cached_mains.clone();
30if self.common_main != 0 {
31 ret.push(self.common_main);
32 }
33 ret
34 }
35}
3637#[derive(Clone, Debug, Serialize, Deserialize)]
38#[repr(C)]
39pub struct StarkVerifyingParams {
40/// Trace sub-matrix widths
41pub width: TraceWidth,
42/// Number of public values for this STARK only
43pub num_public_values: usize,
44/// Number of values to expose to verifier in each trace challenge phase
45pub num_exposed_values_after_challenge: Vec<usize>,
46/// For only this RAP, how many challenges are needed in each trace challenge phase
47pub num_challenges_to_sample: Vec<usize>,
48}
4950/// Verifier data for preprocessed trace for a single AIR.
51///
52/// Currently assumes each AIR has it's own preprocessed commitment
53#[derive(Clone, Serialize, Deserialize)]
54pub struct VerifierSinglePreprocessedData<Com> {
55/// Commitment to the preprocessed trace.
56pub commit: Com,
57}
5859/// Verifying key for a single STARK (corresponding to single AIR matrix)
60#[derive(Clone, Serialize, Deserialize)]
61#[repr(C)]
62pub struct StarkVerifyingKey<Val, Com> {
63/// Preprocessed trace data, if any
64pub preprocessed_data: Option<VerifierSinglePreprocessedData<Com>>,
65/// Parameters of the STARK
66pub params: StarkVerifyingParams,
67/// Symbolic constraints of the AIR in all challenge phases. This is
68 /// a serialization of the constraints in the AIR.
69pub symbolic_constraints: SymbolicConstraintsDag<Val>,
70/// The factor to multiple the trace degree by to get the degree of the quotient polynomial. Determined from the max constraint degree of the AIR constraints.
71 /// This is equivalently the number of chunks the quotient polynomial is split into.
72pub quotient_degree: u8,
73pub rap_phase_seq_kind: RapPhaseSeqKind,
74}
7576/// Common verifying key for multiple AIRs.
77///
78/// This struct contains the necessary data for the verifier to verify proofs generated for
79/// multiple AIRs using a single verifying key.
80#[derive(Derivative, Serialize, Deserialize)]
81#[derivative(Clone(bound = "Com<SC>: Clone"))]
82#[serde(bound(
83 serialize = "Com<SC>: Serialize",
84 deserialize = "Com<SC>: Deserialize<'de>"
85))]
86pub struct MultiStarkVerifyingKey<SC: StarkGenericConfig> {
87/// All parts of the verifying key needed by the verifier, except
88 /// the `pre_hash` used to initialize the Fiat-Shamir transcript.
89pub inner: MultiStarkVerifyingKey0<SC>,
90/// The hash of all other parts of the verifying key. The Fiat-Shamir hasher will
91 /// initialize by observing this hash.
92pub pre_hash: Com<SC>,
93}
9495/// Everything in [MultiStarkVerifyingKey] except the `pre_hash` used to initialize the Fiat-Shamir transcript.
96#[derive(Derivative, Serialize, Deserialize)]
97#[derivative(Clone(bound = "Com<SC>: Clone"))]
98#[serde(bound(
99 serialize = "Com<SC>: Serialize",
100 deserialize = "Com<SC>: Deserialize<'de>"
101))]
102pub struct MultiStarkVerifyingKey0<SC: StarkGenericConfig> {
103pub per_air: Vec<StarkVerifyingKey<Val<SC>, Com<SC>>>,
104pub trace_height_constraints: Vec<LinearConstraint>,
105pub log_up_pow_bits: usize,
106}
107108#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
109pub struct LinearConstraint {
110pub coefficients: Vec<u32>,
111pub threshold: u32,
112}
113114/// Proving key for a single STARK (corresponding to single AIR matrix)
115#[derive(Serialize, Deserialize, Derivative)]
116#[derivative(Clone(bound = "Com<SC>: Clone"))]
117#[serde(bound(
118 serialize = "PcsProverData<SC>: Serialize",
119 deserialize = "PcsProverData<SC>: Deserialize<'de>"
120))]
121pub struct StarkProvingKey<SC: StarkGenericConfig> {
122/// Type name of the AIR, for display purposes only
123pub air_name: String,
124/// Verifying key
125pub vk: StarkVerifyingKey<Val<SC>, Com<SC>>,
126/// Prover only data for preprocessed trace
127pub preprocessed_data: Option<ProverOnlySinglePreprocessedData<SC>>,
128/// Partial proving key for RAP partial proving in challenge phases
129pub rap_partial_pk: RapPartialProvingKey<SC>,
130}
131132/// Common proving key for multiple AIRs.
133///
134/// This struct contains the necessary data for the prover to generate proofs for multiple AIRs
135/// using a single proving key.
136#[derive(Serialize, Deserialize, Derivative)]
137#[derivative(Clone(bound = "Com<SC>: Clone"))]
138#[serde(bound(
139 serialize = "PcsProverData<SC>: Serialize",
140 deserialize = "PcsProverData<SC>: Deserialize<'de>"
141))]
142pub struct MultiStarkProvingKey<SC: StarkGenericConfig> {
143pub per_air: Vec<StarkProvingKey<SC>>,
144pub trace_height_constraints: Vec<LinearConstraint>,
145/// Maximum degree of constraints across all AIRs
146pub max_constraint_degree: usize,
147pub log_up_pow_bits: usize,
148/// See [MultiStarkVerifyingKey]
149pub vk_pre_hash: Com<SC>,
150}
151152impl<Val, Com> StarkVerifyingKey<Val, Com> {
153pub fn num_cached_mains(&self) -> usize {
154self.params.width.cached_mains.len()
155 }
156157pub fn has_common_main(&self) -> bool {
158self.params.width.common_main != 0
159}
160161pub fn has_interaction(&self) -> bool {
162 !self.symbolic_constraints.interactions.is_empty()
163 }
164}
165166impl<SC: StarkGenericConfig> MultiStarkProvingKey<SC> {
167pub fn get_vk(&self) -> MultiStarkVerifyingKey<SC> {
168 MultiStarkVerifyingKey {
169 inner: self.get_vk0(),
170 pre_hash: self.vk_pre_hash.clone(),
171 }
172 }
173174fn get_vk0(&self) -> MultiStarkVerifyingKey0<SC> {
175 MultiStarkVerifyingKey0 {
176 per_air: self.per_air.iter().map(|pk| pk.vk.clone()).collect(),
177 trace_height_constraints: self.trace_height_constraints.clone(),
178 log_up_pow_bits: self.log_up_pow_bits,
179 }
180 }
181}
182impl<SC: StarkGenericConfig> MultiStarkVerifyingKey<SC> {
183pub fn num_challenges_per_phase(&self) -> Vec<usize> {
184self.full_view().num_challenges_per_phase()
185 }
186}
187188/// Prover only data for preprocessed trace for a single AIR.
189/// Currently assumes each AIR has it's own preprocessed commitment
190#[derive(Serialize, Deserialize, Derivative)]
191#[derivative(Clone(bound = "Com<SC>: Clone"))]
192#[serde(bound(
193 serialize = "PcsProverData<SC>: Serialize",
194 deserialize = "PcsProverData<SC>: Deserialize<'de>"
195))]
196pub struct ProverOnlySinglePreprocessedData<SC: StarkGenericConfig> {
197/// Preprocessed trace matrix.
198pub trace: Arc<RowMajorMatrix<Val<SC>>>,
199/// Prover data, such as a Merkle tree, for the trace commitment.
200pub data: Arc<PcsProverData<SC>>,
201}