openvm_stark_backend/prover/hal.rs
1//! # Hardware Abstraction Layer
2//!
3//! Not all hardware implementations need to implement this.
4//! A pure external device implementation can just implement the [Prover](super::Prover) trait
5//! directly.
6
7use std::sync::Arc;
8
9use p3_challenger::CanObserve;
10use p3_matrix::dense::RowMajorMatrix;
11use serde::{de::DeserializeOwned, Serialize};
12
13use super::types::{
14 AirView, DeviceMultiStarkProvingKey, DeviceStarkProvingKey, ProverDataAfterRapPhases,
15};
16use crate::{
17 config::{Com, PcsProverData, StarkGenericConfig, Val},
18 keygen::types::MultiStarkProvingKey,
19 prover::types::{CommittedTraceData, DeviceMultiStarkProvingKeyView},
20};
21
22/// Associated types needed by the prover, in the form of buffers and views,
23/// specific to a specific hardware backend.
24///
25/// Memory allocation and copying is not handled by this trait.
26pub trait ProverBackend {
27 /// Extension field degree for the challenge field `Self::Challenge` over base field
28 /// `Self::Val`.
29 const CHALLENGE_EXT_DEGREE: u8;
30 // ==== Host Types ====
31 /// Base field type, on host.
32 type Val: Copy + Send + Sync + Serialize + DeserializeOwned;
33 /// Challenge field (extension field of base field), on host.
34 type Challenge: Copy + Send + Sync + Serialize + DeserializeOwned;
35 /// PCS opening proof on host (see [OpeningProver]). This should not be a reference.
36 type OpeningProof: Clone + Send + Sync + Serialize + DeserializeOwned;
37 /// Partial proof for multiple RAPs
38 type RapPartialProof: Clone + Send + Sync + Serialize + DeserializeOwned;
39 /// Single commitment on host.
40 // Commitments are small in size and need to be transferred back to host to be included in
41 // proof.
42 type Commitment: Clone + Send + Sync + Serialize + DeserializeOwned;
43 /// Challenger to observe commitments. Sampling is left to other trait implementations.
44 /// We anticipate that the challenger largely operates on the host.
45 type Challenger: CanObserve<Self::Val> + CanObserve<Self::Commitment>;
46
47 // ==== Device Types ====
48 /// Single matrix buffer on device together with dimension metadata. Owning this means nothing
49 /// else has a shared reference to the buffer.
50 type Matrix: MatrixDimensions + Send + Sync;
51 /// Owned buffer for the preimage of a PCS commitment on device, together with any metadata
52 /// necessary for computing opening proofs.
53 ///
54 /// For example, multiple buffers for LDE matrices, their trace domain sizes, and pointer to
55 /// mixed merkle tree.
56 type PcsData: Send + Sync;
57 /// Part of proving key for a single RAP specific for the RAP challenge phases
58 type RapPartialProvingKey: Send + Sync;
59}
60
61pub trait MatrixDimensions {
62 fn height(&self) -> usize;
63 fn width(&self) -> usize;
64}
65
66pub trait ProverDevice<PB: ProverBackend>:
67 TraceCommitter<PB> + RapPartialProver<PB> + QuotientCommitter<PB> + OpeningProver<PB>
68{
69}
70
71/// Provides functionality for committing to a batch of trace matrices, possibly of different
72/// heights.
73pub trait TraceCommitter<PB: ProverBackend> {
74 fn commit(&self, traces: &[PB::Matrix]) -> (PB::Commitment, PB::PcsData);
75}
76
77/// This trait is responsible for all partial proving of after challenge rounds (a.k.a layers) in a
78/// RAP after the main trace has been committed.
79///
80/// The partial prover *may*:
81/// - observe and/or sample challenges
82/// - commit to additional trace data
83/// - generate other partial proof data
84pub trait RapPartialProver<PB: ProverBackend> {
85 /// The `trace_views` are the respective (owned) trace matrices, evaluated on the trace domain.
86 /// Currently this function does not provide a view of any already committed data associated
87 /// with the trace views, although that data is available.
88 ///
89 /// The [AirView] are owned matrices because it is expected these matrices may be dropped
90 /// after this function call.
91 fn partially_prove(
92 &self,
93 challenger: &mut PB::Challenger,
94 mpk: &DeviceMultiStarkProvingKeyView<'_, PB>,
95 trace_views: Vec<AirView<PB::Matrix, PB::Val>>,
96 ) -> (PB::RapPartialProof, ProverDataAfterRapPhases<PB>);
97}
98
99/// Only needed in proof systems that use quotient polynomials.
100pub trait QuotientCommitter<PB: ProverBackend> {
101 /// Given a view of the PCS data from all phases of proving,
102 /// first get the trace polynomials evaluated on the quotient domains.
103 /// Then compute the quotient polynomial evaluated on the quotient domain
104 /// and commit to it.
105 ///
106 /// The lengths of
107 /// - `pk_views`: proving key per AIR
108 /// - `public_values`: public values per AIR
109 /// - `cached_pcs_datas_per_air`: pcs data from cached traces per AIR (if any)
110 ///
111 /// must be equal, and all equal to the number of AIRs.
112 ///
113 /// Quotient polynomials for multiple RAP matrices are committed together into a single
114 /// commitment. The quotient polynomials can be committed together even if the corresponding
115 /// trace matrices are committed separately.
116 fn eval_and_commit_quotient(
117 &self,
118 challenger: &mut PB::Challenger,
119 pk_views: &[&DeviceStarkProvingKey<PB>],
120 public_values: &[Vec<PB::Val>],
121 cached_pcs_datas_per_air: &[Vec<PB::PcsData>],
122 common_main_pcs_data: &PB::PcsData,
123 prover_data_after: &ProverDataAfterRapPhases<PB>,
124 ) -> (PB::Commitment, PB::PcsData);
125}
126
127/// Polynomial commitment scheme (PCS) opening proof generator.
128pub trait OpeningProver<PB: ProverBackend> {
129 /// Opening proof for multiple RAP matrices, where
130 /// - (for now) each preprocessed trace matrix has a separate commitment
131 /// - main trace matrices can have multiple commitments
132 /// - for each after_challenge phase, all matrices in the phase share a commitment
133 /// - quotient poly chunks are all committed together
134 fn open(
135 &self,
136 challenger: &mut PB::Challenger,
137 // For each preprocessed trace commitment, the prover data and
138 // the log height of the matrix, in order
139 preprocessed: Vec<&PB::PcsData>,
140 // For each main trace commitment, the prover data and
141 // the log height of each matrix, in order
142 // Note: this is all one challenge phase.
143 main: Vec<PB::PcsData>,
144 // `after_phase[i]` has shared commitment prover data for all matrices in phase `i + 1`.
145 after_phase: Vec<PB::PcsData>,
146 // Quotient poly commitment prover data
147 quotient_data: PB::PcsData,
148 // Quotient degree for each RAP committed in quotient_data, in order
149 quotient_degrees: &[u8],
150 ) -> PB::OpeningProof;
151}
152
153/// Trait to manage data transport of prover types from host to device.
154pub trait DeviceDataTransporter<SC, PB>
155where
156 SC: StarkGenericConfig,
157 PB: ProverBackend<Val = Val<SC>, Challenge = SC::Challenge, Commitment = Com<SC>>,
158{
159 /// Transport the proving key to the device, filtering for only the provided `air_ids`.
160 fn transport_pk_to_device(
161 &self,
162 mpk: &MultiStarkProvingKey<SC>,
163 ) -> DeviceMultiStarkProvingKey<PB>;
164
165 fn transport_matrix_to_device(&self, matrix: &Arc<RowMajorMatrix<Val<SC>>>) -> PB::Matrix;
166
167 /// The `commitment` and `prover_data` are assumed to have been previously computed from the
168 /// `trace`.
169 fn transport_committed_trace_to_device(
170 &self,
171 commitment: Com<SC>,
172 trace: &Arc<RowMajorMatrix<Val<SC>>>,
173 prover_data: &Arc<PcsProverData<SC>>,
174 ) -> CommittedTraceData<PB>;
175
176 /// Transport a device matrix to host. This should only be used for testing / debugging
177 /// purposes.
178 fn transport_matrix_from_device_to_host(
179 &self,
180 matrix: &PB::Matrix,
181 ) -> Arc<RowMajorMatrix<Val<SC>>>;
182}