Skip to main content

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}