1#![allow(missing_docs)]
2
3use std::fmt::Debug;
4
5use hashbrown::HashMap;
6use itertools::Itertools;
7use p3_matrix::{dense::RowMajorMatrixView, stack::VerticalPair};
8use serde::{de::DeserializeOwned, Deserialize, Serialize};
9use strum::{EnumDiscriminants, EnumTryAs};
10
11use super::{Challenge, Com, OpeningProof, StarkGenericConfig, Val};
12use crate::{
13 baby_bear_poseidon2::BabyBearPoseidon2, septic_digest::SepticDigest, shape::OrderedShape, Dom,
14 StarkVerifyingKey,
15};
16
17pub type QuotientOpenedValues<T> = Vec<T>;
18
19pub struct ShardMainData<SC: StarkGenericConfig, M, P> {
20 pub traces: Vec<M>,
21 pub main_commit: Com<SC>,
22 pub main_data: P,
23 pub chip_ordering: HashMap<String, usize>,
24 pub public_values: Vec<SC::Val>,
25}
26
27impl<SC: StarkGenericConfig, M, P> ShardMainData<SC, M, P> {
28 pub const fn new(
29 traces: Vec<M>,
30 main_commit: Com<SC>,
31 main_data: P,
32 chip_ordering: HashMap<String, usize>,
33 public_values: Vec<Val<SC>>,
34 ) -> Self {
35 Self { traces, main_commit, main_data, chip_ordering, public_values }
36 }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ShardCommitment<C> {
41 pub main_commit: C,
42 pub permutation_commit: C,
43 pub quotient_commit: C,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(bound(serialize = "T: Serialize"))]
48#[serde(bound(deserialize = "T: Deserialize<'de>"))]
49pub struct AirOpenedValues<T> {
50 pub local: Vec<T>,
51 pub next: Vec<T>,
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(bound(serialize = "F: Serialize, EF: Serialize"))]
56#[serde(bound(deserialize = "F: Deserialize<'de>, EF: Deserialize<'de>"))]
57pub struct ChipOpenedValues<F, EF> {
58 pub preprocessed: AirOpenedValues<EF>,
59 pub main: AirOpenedValues<EF>,
60 pub permutation: AirOpenedValues<EF>,
61 pub quotient: Vec<Vec<EF>>,
62 pub global_cumulative_sum: SepticDigest<F>,
63 pub local_cumulative_sum: EF,
64 pub log_degree: usize,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct ShardOpenedValues<F, EF> {
69 pub chips: Vec<ChipOpenedValues<F, EF>>,
70}
71
72pub const PROOF_MAX_NUM_PVS: usize = 231;
76
77#[derive(Serialize, Deserialize, Clone)]
78#[serde(bound = "")]
79pub struct ShardProof<SC: StarkGenericConfig> {
80 pub commitment: ShardCommitment<Com<SC>>,
81 pub opened_values: ShardOpenedValues<Val<SC>, Challenge<SC>>,
82 pub opening_proof: OpeningProof<SC>,
83 pub chip_ordering: HashMap<String, usize>,
84 pub public_values: Vec<Val<SC>>,
85}
86
87impl<SC: StarkGenericConfig> Debug for ShardProof<SC> {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 f.debug_struct("ShardProof").finish()
90 }
91}
92
93impl<T: Send + Sync + Clone> AirOpenedValues<T> {
94 #[must_use]
95 pub fn view(&self) -> VerticalPair<RowMajorMatrixView<'_, T>, RowMajorMatrixView<'_, T>> {
96 let a = RowMajorMatrixView::new_row(&self.local);
97 let b = RowMajorMatrixView::new_row(&self.next);
98 VerticalPair::new(a, b)
99 }
100}
101
102impl<SC: StarkGenericConfig> ShardProof<SC> {
103 pub fn local_cumulative_sum(&self) -> Challenge<SC> {
104 self.opened_values.chips.iter().map(|c| c.local_cumulative_sum).sum()
105 }
106
107 pub fn global_cumulative_sum(&self) -> SepticDigest<Val<SC>> {
108 self.opened_values.chips.iter().map(|c| c.global_cumulative_sum).sum()
109 }
110
111 pub fn log_degree_cpu(&self) -> usize {
112 let idx = self.chip_ordering.get("Cpu").expect("Cpu chip not found");
113 self.opened_values.chips[*idx].log_degree
114 }
115
116 pub fn contains_cpu(&self) -> bool {
117 self.chip_ordering.contains_key("Cpu")
118 }
119
120 pub fn contains_global_memory_init(&self) -> bool {
121 self.chip_ordering.contains_key("MemoryGlobalInit")
122 }
123
124 pub fn contains_global_memory_finalize(&self) -> bool {
125 self.chip_ordering.contains_key("MemoryGlobalFinalize")
126 }
127}
128
129#[derive(Serialize, Deserialize, Clone)]
130#[serde(bound = "")]
131pub struct MachineProof<SC: StarkGenericConfig> {
132 pub shard_proofs: Vec<ShardProof<SC>>,
133}
134
135impl<SC: StarkGenericConfig> Debug for MachineProof<SC> {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 f.debug_struct("Proof").field("shard_proofs", &self.shard_proofs.len()).finish()
138 }
139}
140
141pub type CoreSC = BabyBearPoseidon2;
143
144pub type InnerSC = BabyBearPoseidon2;
146
147#[derive(Debug, Clone, Serialize, Deserialize, EnumDiscriminants, EnumTryAs)]
149#[strum_discriminants(derive(Default, Hash, PartialOrd, Ord))]
150#[strum_discriminants(name(SP1ProofMode))]
151pub enum SP1Proof {
152 #[strum_discriminants(default)]
156 Core(Vec<ShardProof<CoreSC>>),
157 Compressed(Box<SP1ReduceProof<InnerSC>>),
161 Plonk(PlonkBn254Proof),
163 Groth16(Groth16Bn254Proof),
165}
166
167impl core::fmt::Display for SP1Proof {
168 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
169 match self {
170 SP1Proof::Core(_) => write!(f, "Core"),
171 SP1Proof::Compressed(_) => write!(f, "Compressed"),
172 SP1Proof::Plonk(_) => write!(f, "Plonk"),
173 SP1Proof::Groth16(_) => write!(f, "Groth16"),
174 }
175 }
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize, Default)]
179pub struct PlonkBn254Proof {
180 pub public_inputs: [String; 2],
181 pub encoded_proof: String,
182 pub raw_proof: String,
183 pub plonk_vkey_hash: [u8; 32],
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize, Default)]
187pub struct Groth16Bn254Proof {
188 pub public_inputs: [String; 2],
189 pub encoded_proof: String,
190 pub raw_proof: String,
191 pub groth16_vkey_hash: [u8; 32],
192}
193
194#[derive(Serialize, Deserialize, Clone)]
196#[serde(bound(serialize = "ShardProof<SC>: Serialize, Dom<SC>: Serialize"))]
197#[serde(bound(deserialize = "ShardProof<SC>: Deserialize<'de>, Dom<SC>: DeserializeOwned"))]
198pub struct SP1ReduceProof<SC: StarkGenericConfig> {
199 pub vk: StarkVerifyingKey<SC>,
201 pub proof: ShardProof<SC>,
203}
204
205impl<SC: StarkGenericConfig> std::fmt::Debug for SP1ReduceProof<SC> {
206 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 let mut debug_struct = f.debug_struct("SP1ReduceProof");
208 debug_struct.field("vk", &self.vk);
209 debug_struct.field("proof", &self.proof);
210 debug_struct.finish()
211 }
212}
213
214pub struct PublicValuesDigest(pub [u8; 32]);
216
217impl From<[u32; 8]> for PublicValuesDigest {
218 fn from(arr: [u32; 8]) -> Self {
219 let mut bytes = [0u8; 32];
220 for (i, word) in arr.iter().enumerate() {
221 bytes[i * 4..(i + 1) * 4].copy_from_slice(&word.to_le_bytes());
222 }
223 PublicValuesDigest(bytes)
224 }
225}
226
227pub struct DeferredDigest(pub [u8; 32]);
229
230impl From<[u32; 8]> for DeferredDigest {
231 fn from(arr: [u32; 8]) -> Self {
232 let mut bytes = [0u8; 32];
233 for (i, word) in arr.iter().enumerate() {
234 bytes[i * 4..(i + 1) * 4].copy_from_slice(&word.to_le_bytes());
235 }
236 DeferredDigest(bytes)
237 }
238}
239
240impl<SC: StarkGenericConfig> ShardProof<SC> {
241 pub fn shape(&self) -> OrderedShape {
242 OrderedShape {
243 inner: self
244 .chip_ordering
245 .iter()
246 .sorted_by_key(|(_, idx)| *idx)
247 .zip(self.opened_values.chips.iter())
248 .map(|((name, _), values)| (name.to_owned(), values.log_degree))
249 .collect(),
250 }
251 }
252}