sp1_recursion_core/air/
public_values.rs1use crate::runtime::{DIGEST_SIZE, HASH_RATE, PERMUTATION_WIDTH};
2
3use core::fmt::Debug;
4use p3_challenger::DuplexChallenger;
5use p3_field::PrimeField32;
6use p3_symmetric::CryptographicPermutation;
7use serde::{Deserialize, Serialize};
8use sp1_core_machine::utils::indices_arr;
9use sp1_derive::AlignedBorrow;
10use sp1_stark::{air::POSEIDON_NUM_WORDS, septic_digest::SepticDigest, Word, PROOF_MAX_NUM_PVS};
11use static_assertions::const_assert_eq;
12use std::{
13 borrow::BorrowMut,
14 mem::{size_of, transmute, MaybeUninit},
15};
16
17pub const PV_DIGEST_NUM_WORDS: usize = 8;
18
19pub const CHALLENGER_STATE_NUM_ELTS: usize = size_of::<ChallengerPublicValues<u8>>();
20
21pub const RECURSIVE_PROOF_NUM_PV_ELTS: usize = size_of::<RecursionPublicValues<u8>>();
22
23const fn make_col_map() -> RecursionPublicValues<usize> {
24 let indices_arr = indices_arr::<RECURSIVE_PROOF_NUM_PV_ELTS>();
25 unsafe {
26 transmute::<[usize; RECURSIVE_PROOF_NUM_PV_ELTS], RecursionPublicValues<usize>>(indices_arr)
27 }
28}
29
30pub const RECURSION_PUBLIC_VALUES_COL_MAP: RecursionPublicValues<usize> = make_col_map();
31
32pub const NUM_PV_ELMS_TO_HASH: usize = RECURSION_PUBLIC_VALUES_COL_MAP.digest[0];
34
35const_assert_eq!(RECURSIVE_PROOF_NUM_PV_ELTS, PROOF_MAX_NUM_PVS);
38
39#[derive(AlignedBorrow, Serialize, Deserialize, Clone, Copy, Default, Debug)]
40#[repr(C)]
41pub struct ChallengerPublicValues<T> {
42 pub sponge_state: [T; PERMUTATION_WIDTH],
43 pub num_inputs: T,
44 pub input_buffer: [T; PERMUTATION_WIDTH],
45 pub num_outputs: T,
46 pub output_buffer: [T; PERMUTATION_WIDTH],
47}
48
49impl<T: Clone> ChallengerPublicValues<T> {
50 pub fn set_challenger<P: CryptographicPermutation<[T; PERMUTATION_WIDTH]>>(
51 &self,
52 challenger: &mut DuplexChallenger<T, P, PERMUTATION_WIDTH, HASH_RATE>,
53 ) where
54 T: PrimeField32,
55 {
56 challenger.sponge_state = self.sponge_state;
57 let num_inputs = self.num_inputs.as_canonical_u32() as usize;
58 challenger.input_buffer = self.input_buffer[..num_inputs].to_vec();
59 let num_outputs = self.num_outputs.as_canonical_u32() as usize;
60 challenger.output_buffer = self.output_buffer[..num_outputs].to_vec();
61 }
62
63 pub fn as_array(&self) -> [T; CHALLENGER_STATE_NUM_ELTS]
64 where
65 T: Copy,
66 {
67 unsafe {
68 let mut ret = [MaybeUninit::<T>::zeroed().assume_init(); CHALLENGER_STATE_NUM_ELTS];
69 let pv: &mut ChallengerPublicValues<T> = ret.as_mut_slice().borrow_mut();
70 *pv = *self;
71 ret
72 }
73 }
74}
75
76#[derive(AlignedBorrow, Serialize, Deserialize, Clone, Copy, Default, Debug)]
78#[repr(C)]
79pub struct RecursionPublicValues<T> {
80 pub committed_value_digest: [Word<T>; PV_DIGEST_NUM_WORDS],
82
83 pub deferred_proofs_digest: [T; POSEIDON_NUM_WORDS],
85
86 pub start_pc: T,
88
89 pub next_pc: T,
91
92 pub start_shard: T,
94
95 pub next_shard: T,
97
98 pub start_execution_shard: T,
100
101 pub next_execution_shard: T,
103
104 pub previous_init_addr_bits: [T; 32],
106
107 pub last_init_addr_bits: [T; 32],
109
110 pub previous_finalize_addr_bits: [T; 32],
112
113 pub last_finalize_addr_bits: [T; 32],
115
116 pub start_reconstruct_deferred_digest: [T; POSEIDON_NUM_WORDS],
118
119 pub end_reconstruct_deferred_digest: [T; POSEIDON_NUM_WORDS],
121
122 pub sp1_vk_digest: [T; DIGEST_SIZE],
124
125 pub vk_root: [T; DIGEST_SIZE],
127
128 pub global_cumulative_sum: SepticDigest<T>,
131
132 pub is_complete: T,
134
135 pub contains_execution_shard: T,
138
139 pub exit_code: T,
141
142 pub digest: [T; DIGEST_SIZE],
144}
145
146impl<F: Copy> RecursionPublicValues<F> {
148 pub fn as_array(&self) -> [F; RECURSIVE_PROOF_NUM_PV_ELTS] {
149 unsafe {
150 let mut ret = [MaybeUninit::<F>::zeroed().assume_init(); RECURSIVE_PROOF_NUM_PV_ELTS];
151 let pv: &mut RecursionPublicValues<F> = ret.as_mut_slice().borrow_mut();
152 *pv = *self;
153 ret
154 }
155 }
156}
157
158impl<T: Copy> IntoIterator for RecursionPublicValues<T> {
159 type Item = T;
160 type IntoIter = std::array::IntoIter<T, RECURSIVE_PROOF_NUM_PV_ELTS>;
161
162 fn into_iter(self) -> Self::IntoIter {
163 self.as_array().into_iter()
164 }
165}
166
167impl<T: Copy> IntoIterator for ChallengerPublicValues<T> {
168 type Item = T;
169 type IntoIter = std::array::IntoIter<T, CHALLENGER_STATE_NUM_ELTS>;
170
171 fn into_iter(self) -> Self::IntoIter {
172 self.as_array().into_iter()
173 }
174}