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, 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
53pub trait ProverDevice<PB: ProverBackend, TS>:
54    TraceCommitter<PB> + MultiRapProver<PB, TS> + OpeningProver<PB, TS>
55{
56    type Error: 'static
57        + std::error::Error
58        + Send
59        + Sync
60        + From<<Self as TraceCommitter<PB>>::Error>
61        + From<<Self as MultiRapProver<PB, TS>>::Error>
62        + From<<Self as OpeningProver<PB, TS>>::Error>;
63
64    /// Device-specific context (e.g., CUDA stream). Unit `()` for CPU devices.
65    type DeviceCtx: Clone + Send + Sync;
66
67    fn device_ctx(&self) -> &Self::DeviceCtx;
68}
69
70/// Provides functionality for committing to a batch of trace matrices, possibly of different
71/// heights.
72pub trait TraceCommitter<PB: ProverBackend> {
73    type Error: std::fmt::Debug;
74    fn commit(&self, traces: &[&PB::Matrix]) -> Result<(PB::Commitment, PB::PcsData), Self::Error>;
75}
76
77/// This trait is responsible for the proving steps that reduce AIR zerocheck constraints and
78/// interaction consistency claims to polynomial opening claims.
79///
80/// This trait is _not_ responsible for committing to trace matrices or for checking polynomial
81/// openings against PCS commitments.
82pub trait MultiRapProver<PB: ProverBackend, TS> {
83    /// The partial proof is the proof that the trace matrices satisfy all constraints assuming that
84    /// certain polynomial opening claims are validated. In other words, it is a proof that reduces
85    /// the constraint satisfaction claim to certain polynomial opening claims.
86    type PartialProof: Clone + Send + Sync + Serialize + DeserializeOwned;
87    /// Other artifacts of the proof (e.g., sampled randomness) that may be passed to later stages
88    /// of the protocol.
89    type Artifacts;
90
91    type Error: std::fmt::Debug;
92
93    fn prove_rap_constraints(
94        &self,
95        transcript: &mut TS,
96        mpk: &DeviceMultiStarkProvingKey<PB>,
97        ctx: &ProvingContext<PB>,
98        common_main_pcs_data: &PB::PcsData,
99    ) -> Result<(Self::PartialProof, Self::Artifacts), Self::Error>;
100}
101
102/// This trait is responsible for proving the evaluation claims of a collection of polynomials at a
103/// collection of points. The opening point may be the same across polynomials. The polynomials may
104/// be defined over different domains and are hence of "mixed" nature. The polynomials are already
105/// committed and provided in their committed form.
106pub trait OpeningProver<PB: ProverBackend, TS> {
107    /// PCS opening proof on host. This should not be a reference.
108    type OpeningProof: Clone + Send + Sync + Serialize + DeserializeOwned;
109    type OpeningPoints;
110
111    /// Computes the opening proof.
112    /// The `common_main_pcs_data` is the `PcsData` for the collection of common main trace
113    /// matrices. It is owned by the function and may be mutated.
114    /// The `pre_cached_pcs_data_per_commit` is the `PcsData` for the preprocessed and cached trace
115    /// matrices. These are specified by their `PcsData` per commitment.
116    type Error: std::fmt::Debug;
117
118    fn prove_openings(
119        &self,
120        transcript: &mut TS,
121        mpk: &DeviceMultiStarkProvingKey<PB>,
122        ctx: ProvingContext<PB>,
123        common_main_pcs_data: PB::PcsData,
124        points: Self::OpeningPoints,
125    ) -> Result<Self::OpeningProof, Self::Error>;
126}
127
128/// Trait to manage data transport of prover types from host to device.
129pub trait DeviceDataTransporter<SC, PB>
130where
131    SC: StarkProtocolConfig,
132    PB: ProverBackend<Val = SC::F, Challenge = SC::EF, Commitment = SC::Digest>,
133{
134    /// Transport the proving key to the device, filtering for only the provided `air_ids`.
135    fn transport_pk_to_device(
136        &self,
137        mpk: &MultiStarkProvingKey<SC>,
138    ) -> DeviceMultiStarkProvingKey<PB>;
139
140    fn transport_matrix_to_device(&self, matrix: &ColMajorMatrix<SC::F>) -> PB::Matrix;
141
142    /// The `commitment` and `prover_data` are assumed to have been previously computed from the
143    /// `trace`.
144    fn transport_pcs_data_to_device(
145        &self,
146        pcs_data: &StackedPcsData<SC::F, SC::Digest>,
147    ) -> PB::PcsData;
148
149    fn transport_committed_trace_data_to_device(
150        &self,
151        committed_trace: &CommittedTraceData<CpuColMajorBackend<SC>>,
152    ) -> CommittedTraceData<PB> {
153        let trace = self.transport_matrix_to_device(&committed_trace.trace);
154        let data = self.transport_pcs_data_to_device(committed_trace.data.as_ref());
155
156        CommittedTraceData {
157            commitment: committed_trace.commitment,
158            trace,
159            data: Arc::new(data),
160        }
161    }
162
163    fn transport_proving_ctx_to_device(
164        &self,
165        ctx: &ProvingContext<CpuColMajorBackend<SC>>,
166    ) -> ProvingContext<PB> {
167        let per_trace = ctx
168            .per_trace
169            .iter()
170            .map(|(air_idx, trace_ctx)| {
171                let common_main = self.transport_matrix_to_device(&trace_ctx.common_main);
172                let cached_mains = trace_ctx
173                    .cached_mains
174                    .iter()
175                    .map(|cd| self.transport_committed_trace_data_to_device(cd))
176                    .collect();
177                let trace_ctx_gpu = AirProvingContext::new(
178                    cached_mains,
179                    common_main,
180                    trace_ctx.public_values.clone(),
181                );
182                (*air_idx, trace_ctx_gpu)
183            })
184            .collect();
185        ProvingContext::new(per_trace)
186    }
187
188    // ==================================================================================
189    // Device-to-Host methods below should only be used for testing / debugging purposes.
190    // ==================================================================================
191
192    /// Transport a device matrix to host. This should only be used for testing / debugging
193    /// purposes.
194    fn transport_matrix_from_device_to_host(&self, matrix: &PB::Matrix) -> ColMajorMatrix<SC::F>;
195}