openvm_stark_backend/prover/hal.rs
1use std::sync::Arc;
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{
6 keygen::types::MultiStarkProvingKey,
7 prover::{
8 stacked_pcs::StackedPcsData, AirProvingContext, ColMajorMatrix, CommittedTraceData,
9 CpuColMajorBackend, DeviceMultiStarkProvingKey, DeviceStarkProvingKey, ProvingContext,
10 },
11 StarkProtocolConfig,
12};
13
14pub trait MatrixDimensions {
15 fn height(&self) -> usize;
16 fn width(&self) -> usize;
17}
18
19/// Associated types needed by the prover, in the form of buffers and views,
20/// specific to a specific hardware backend.
21///
22/// Memory allocation and copying is not handled by this trait.
23pub trait ProverBackend {
24 /// Extension field degree for the challenge field `Self::Challenge` over base field
25 /// `Self::Val`.
26 const CHALLENGE_EXT_DEGREE: u8;
27 // ==== Host Types ====
28 /// Base field type, on host.
29 type Val: Copy + Send + Sync + Serialize + DeserializeOwned;
30 /// Challenge field (extension field of base field), on host.
31 type Challenge: Copy + Send + Sync + Serialize + DeserializeOwned;
32 /// Single commitment on host.
33 // Commitments are small in size and need to be transferred back to host to be included in
34 // proof.
35 type Commitment: Clone + Send + Sync + Serialize + DeserializeOwned;
36
37 // ==== Device Types ====
38 /// Single matrix buffer on device together with dimension metadata. Owning this means nothing
39 /// else has a shared reference to the buffer.
40 type Matrix: MatrixDimensions + Send + Sync;
41 /// Backend specific type for any pre-computed data associated with a single AIR. For example,
42 /// it may contain prover-specific precomputations based on the AIR constraints (but
43 /// independent from any trace data).
44 type OtherAirData: Send + Sync;
45 /// Owned buffer for the preimage of a PCS commitment on device, together with any metadata
46 /// necessary for computing opening proofs.
47 ///
48 /// For example, multiple buffers for LDE matrices, their trace domain sizes, and pointer to
49 /// mixed merkle tree.
50 type PcsData: Send + Sync;
51
52 // ==== Metering Functions ====
53 /// Per-row intermediate buffer size required to evaluate this AIR's constraints during
54 /// batch constraints zerocheck round 0. Constant `0` (the default) means the backend does
55 /// not track this; if all AIRs report `0`, memory metering falls back to the full round-0
56 /// temporary-memory limit.
57 fn constraint_eval_buffer_size(_pk: &DeviceStarkProvingKey<Self>) -> usize
58 where
59 Self: Sized,
60 {
61 0
62 }
63}
64
65pub trait ProverDevice<PB: ProverBackend, TS>:
66 TraceCommitter<PB> + MultiRapProver<PB, TS> + OpeningProver<PB, TS>
67{
68 type Error: 'static
69 + std::error::Error
70 + Send
71 + Sync
72 + From<<Self as TraceCommitter<PB>>::Error>
73 + From<<Self as MultiRapProver<PB, TS>>::Error>
74 + From<<Self as OpeningProver<PB, TS>>::Error>;
75
76 /// Device-specific context (e.g., CUDA stream). Unit `()` for CPU devices.
77 type DeviceCtx: Clone + Send + Sync;
78
79 fn device_ctx(&self) -> &Self::DeviceCtx;
80}
81
82/// Provides functionality for committing to a batch of trace matrices, possibly of different
83/// heights.
84pub trait TraceCommitter<PB: ProverBackend> {
85 type Error: std::fmt::Debug;
86 fn commit(&self, traces: &[&PB::Matrix]) -> Result<(PB::Commitment, PB::PcsData), Self::Error>;
87}
88
89/// This trait is responsible for the proving steps that reduce AIR zerocheck constraints and
90/// interaction consistency claims to polynomial opening claims.
91///
92/// This trait is _not_ responsible for committing to trace matrices or for checking polynomial
93/// openings against PCS commitments.
94pub trait MultiRapProver<PB: ProverBackend, TS> {
95 /// The partial proof is the proof that the trace matrices satisfy all constraints assuming that
96 /// certain polynomial opening claims are validated. In other words, it is a proof that reduces
97 /// the constraint satisfaction claim to certain polynomial opening claims.
98 type PartialProof: Clone + Send + Sync + Serialize + DeserializeOwned;
99 /// Other artifacts of the proof (e.g., sampled randomness) that may be passed to later stages
100 /// of the protocol.
101 type Artifacts;
102
103 type Error: std::fmt::Debug;
104
105 fn prove_rap_constraints(
106 &self,
107 transcript: &mut TS,
108 mpk: &DeviceMultiStarkProvingKey<PB>,
109 ctx: &ProvingContext<PB>,
110 common_main_pcs_data: &PB::PcsData,
111 ) -> Result<(Self::PartialProof, Self::Artifacts), Self::Error>;
112}
113
114/// This trait is responsible for proving the evaluation claims of a collection of polynomials at a
115/// collection of points. The opening point may be the same across polynomials. The polynomials may
116/// be defined over different domains and are hence of "mixed" nature. The polynomials are already
117/// committed and provided in their committed form.
118pub trait OpeningProver<PB: ProverBackend, TS> {
119 /// PCS opening proof on host. This should not be a reference.
120 type OpeningProof: Clone + Send + Sync + Serialize + DeserializeOwned;
121 type OpeningPoints;
122
123 /// Computes the opening proof.
124 /// The `common_main_pcs_data` is the `PcsData` for the collection of common main trace
125 /// matrices. It is owned by the function and may be mutated.
126 /// The `pre_cached_pcs_data_per_commit` is the `PcsData` for the preprocessed and cached trace
127 /// matrices. These are specified by their `PcsData` per commitment.
128 type Error: std::fmt::Debug;
129
130 fn prove_openings(
131 &self,
132 transcript: &mut TS,
133 mpk: &DeviceMultiStarkProvingKey<PB>,
134 ctx: ProvingContext<PB>,
135 common_main_pcs_data: PB::PcsData,
136 points: Self::OpeningPoints,
137 ) -> Result<Self::OpeningProof, Self::Error>;
138}
139
140/// Trait to manage data transport of prover types from host to device.
141pub trait DeviceDataTransporter<SC, PB>
142where
143 SC: StarkProtocolConfig,
144 PB: ProverBackend<Val = SC::F, Challenge = SC::EF, Commitment = SC::Digest>,
145{
146 /// Transport the proving key to the device, filtering for only the provided `air_ids`.
147 fn transport_pk_to_device(
148 &self,
149 mpk: &MultiStarkProvingKey<SC>,
150 ) -> DeviceMultiStarkProvingKey<PB>;
151
152 fn transport_matrix_to_device(&self, matrix: &ColMajorMatrix<SC::F>) -> PB::Matrix;
153
154 /// The `commitment` and `prover_data` are assumed to have been previously computed from the
155 /// `trace`.
156 fn transport_pcs_data_to_device(
157 &self,
158 pcs_data: &StackedPcsData<SC::F, SC::Digest>,
159 ) -> PB::PcsData;
160
161 fn transport_committed_trace_data_to_device(
162 &self,
163 committed_trace: &CommittedTraceData<CpuColMajorBackend<SC>>,
164 ) -> CommittedTraceData<PB> {
165 let trace = self.transport_matrix_to_device(&committed_trace.trace);
166 let data = self.transport_pcs_data_to_device(committed_trace.data.as_ref());
167
168 CommittedTraceData {
169 commitment: committed_trace.commitment,
170 trace,
171 data: Arc::new(data),
172 }
173 }
174
175 fn transport_proving_ctx_to_device(
176 &self,
177 ctx: &ProvingContext<CpuColMajorBackend<SC>>,
178 ) -> ProvingContext<PB> {
179 let per_trace = ctx
180 .per_trace
181 .iter()
182 .map(|(air_idx, trace_ctx)| {
183 let common_main = self.transport_matrix_to_device(&trace_ctx.common_main);
184 let cached_mains = trace_ctx
185 .cached_mains
186 .iter()
187 .map(|cd| self.transport_committed_trace_data_to_device(cd))
188 .collect();
189 let trace_ctx_gpu = AirProvingContext::new(
190 cached_mains,
191 common_main,
192 trace_ctx.public_values.clone(),
193 );
194 (*air_idx, trace_ctx_gpu)
195 })
196 .collect();
197 ProvingContext::new(per_trace)
198 }
199
200 // ==================================================================================
201 // Device-to-Host methods below should only be used for testing / debugging purposes.
202 // ==================================================================================
203
204 /// Transport a device matrix to host. This should only be used for testing / debugging
205 /// purposes.
206 fn transport_matrix_from_device_to_host(&self, matrix: &PB::Matrix) -> ColMajorMatrix<SC::F>;
207}