risc0_zkvm/host/client/prove/opts.rs
1// Copyright 2025 RISC Zero, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Module containing the [ProverOpts] struct and related functionality.
16
17#[cfg(feature = "prove")]
18use anyhow::Result;
19use risc0_circuit_recursion::control_id::ALLOWED_CONTROL_IDS;
20use risc0_zkp::core::digest::Digest;
21use serde::{Deserialize, Serialize};
22
23use crate::receipt::DEFAULT_MAX_PO2;
24
25/// Options to configure a [Prover][super::Prover].
26#[derive(Clone, Debug, Serialize, Deserialize)]
27#[non_exhaustive]
28pub struct ProverOpts {
29 /// Identifier of the hash function to use for the STARK proving protocol.
30 pub hashfn: String,
31
32 /// When false, only prove execution sessions that end in a successful
33 /// [crate::ExitCode] (i.e. `Halted(0)` or `Paused(0)`).
34 /// When set to true, any completed execution session will be proven, including indicated
35 /// errors (e.g. `Halted(1)`) and sessions ending in `Fault`.
36 pub prove_guest_errors: bool,
37
38 /// Kind of receipt to be generated by the prover.
39 pub receipt_kind: ReceiptKind,
40
41 /// List of control IDs to enable for recursion proving.
42 ///
43 /// This list is used to construct the control root, which commits to the set of recursion
44 /// programs that are allowed to run and is a key field in the
45 /// [SuccinctReceiptVerifierParameters][crate::SuccinctReceiptVerifierParameters].
46 pub control_ids: Vec<Digest>,
47
48 /// Maximum cycle count, as a power of two (po2) that these prover options support.
49 pub(crate) max_segment_po2: usize,
50
51 /// Whether or not dev-mode is enabled. If enabled, fake receipts may be generated, and fake
52 /// receipts will verify successfully.
53 pub(crate) dev_mode: bool,
54}
55
56/// An enumeration of receipt kinds that can be requested to be generated.
57#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
58#[non_exhaustive]
59pub enum ReceiptKind {
60 /// Request that a [CompositeReceipt][crate::CompositeReceipt] be generated.
61 ///
62 /// Composite receipts are made up of a receipt for every segment in a zkVM execution, and
63 /// every assumption. They are linear in size with respect to the execution length.
64 Composite,
65
66 /// Request that a [SuccinctReceipt][crate::SuccinctReceipt] be generated.
67 ///
68 /// Succinct receipts are constant in size, with respect to the execution length.
69 ///
70 Succinct,
71
72 /// Request that a [Groth16Receipt][crate::Groth16Receipt] be generated.
73 ///
74 /// Groth16 receipts are proven using Groth16, are constant in size, and are the smallest
75 /// available receipt format. A Groth16 receipt can be serialized to a few hundred bytes.
76 Groth16,
77}
78
79impl Default for ProverOpts {
80 /// Return [ProverOpts] that are intended to work for most applications.
81 ///
82 /// Proof generated with these options may be linear in size with the execution length, but
83 /// can be compressed using the [Prover::compress][super::Prover::compress] methods.
84 fn default() -> Self {
85 Self {
86 hashfn: "poseidon2".to_string(),
87 prove_guest_errors: false,
88 receipt_kind: ReceiptKind::Composite,
89 control_ids: ALLOWED_CONTROL_IDS.to_vec(),
90 max_segment_po2: DEFAULT_MAX_PO2,
91 dev_mode: crate::is_dev_mode_enabled_via_environment(),
92 }
93 }
94}
95
96impl ProverOpts {
97 /// Construct a [ProverOpts] ready to prove segments with up to the given max cycle count as a
98 /// power of two (po2). All fields are equal to the default expect where they need to be
99 /// adjusted to support a larger po2.
100 ///
101 /// NOTE: If the po2 used to prove is greater than the targeted verifier supports,
102 /// [DEFAULT_MAX_PO2] by default, receipts will be rejected by the verifier.
103 #[stability::unstable]
104 pub fn from_max_po2(po2_max: usize) -> Self {
105 Self {
106 hashfn: "poseidon2".to_string(),
107 prove_guest_errors: false,
108 receipt_kind: ReceiptKind::Composite,
109 control_ids: crate::receipt::succinct::allowed_control_ids("poseidon2", po2_max)
110 .unwrap()
111 .collect(),
112 max_segment_po2: po2_max,
113 dev_mode: crate::is_dev_mode_enabled_via_environment(),
114 }
115 }
116
117 /// Construct a verifier context that will accept receipts with control any of the default
118 /// control ID associated with cycle counts of all supported powers of two (po2).
119 #[stability::unstable]
120 pub fn all_po2s() -> Self {
121 Self::from_max_po2(risc0_zkp::MAX_CYCLES_PO2)
122 }
123
124 /// Choose the fastest prover options. Receipt will be linear in length of the execution,
125 ///
126 /// This is an alias for [ProverOpts::composite].
127 pub fn fast() -> Self {
128 Self::composite()
129 }
130
131 /// Choose the prover that generates composite receipts, linear in the length of the execution,
132 /// and supports compression via recursion.
133 pub fn composite() -> Self {
134 Self {
135 hashfn: "poseidon2".to_string(),
136 prove_guest_errors: false,
137 receipt_kind: ReceiptKind::Composite,
138 control_ids: ALLOWED_CONTROL_IDS.to_vec(),
139 max_segment_po2: DEFAULT_MAX_PO2,
140 dev_mode: crate::is_dev_mode_enabled_via_environment(),
141 }
142 }
143
144 /// Choose the prover that generates succinct receipts, which are constant size in the length
145 /// of execution.
146 pub fn succinct() -> Self {
147 Self {
148 hashfn: "poseidon2".to_string(),
149 prove_guest_errors: false,
150 receipt_kind: ReceiptKind::Succinct,
151 control_ids: ALLOWED_CONTROL_IDS.to_vec(),
152 max_segment_po2: DEFAULT_MAX_PO2,
153 dev_mode: crate::is_dev_mode_enabled_via_environment(),
154 }
155 }
156
157 /// Choose the prover that generates Groth16 receipts which are constant size in the length of
158 /// the execution and small enough to verify on blockchains, like Ethereum.
159 ///
160 /// Only supported with Docker installed.
161 pub fn groth16() -> Self {
162 Self {
163 hashfn: "poseidon2".to_string(),
164 prove_guest_errors: false,
165 receipt_kind: ReceiptKind::Groth16,
166 control_ids: ALLOWED_CONTROL_IDS.to_vec(),
167 max_segment_po2: DEFAULT_MAX_PO2,
168 dev_mode: crate::is_dev_mode_enabled_via_environment(),
169 }
170 }
171
172 /// Return [ProverOpts] with the hashfn set to the given value.
173 pub fn with_hashfn(self, hashfn: String) -> Self {
174 Self {
175 hashfn: hashfn.to_owned(),
176 ..self
177 }
178 }
179
180 /// Return [ProverOpts] with prove_guest_errors set to the given value.
181 pub fn with_prove_guest_errors(self, prove_guest_errors: bool) -> Self {
182 Self {
183 prove_guest_errors,
184 ..self
185 }
186 }
187
188 /// Return [ProverOpts] with the receipt_kind set to the given value.
189 pub fn with_receipt_kind(self, receipt_kind: ReceiptKind) -> Self {
190 Self {
191 receipt_kind,
192 ..self
193 }
194 }
195
196 /// Return [ProverOpts] with the control_ids set to the given value.
197 pub fn with_control_ids(self, control_ids: Vec<Digest>) -> Self {
198 Self {
199 control_ids,
200 ..self
201 }
202 }
203
204 /// Return [ProverOpts] with the max_segment_po2 set to the given value.
205 #[stability::unstable]
206 pub fn with_segment_po2_max(self, max_segment_po2: usize) -> Self {
207 Self {
208 max_segment_po2,
209 ..self
210 }
211 }
212
213 /// Return [ProverOpts] with dev_mode enabled or disabled.
214 pub fn with_dev_mode(self, dev_mode: bool) -> Self {
215 if cfg!(feature = "disable-dev-mode") && dev_mode {
216 panic!("zkVM: Inconsistent settings -- please resolve. \
217 The RISC0_DEV_MODE environment variable is set but dev mode has been disabled by feature flag.");
218 }
219 Self { dev_mode, ..self }
220 }
221
222 /// Returns `true` if dev-mode is enabled.
223 pub fn dev_mode(&self) -> bool {
224 self.dev_mode
225 }
226
227 #[cfg(feature = "prove")]
228 pub(crate) fn hash_suite(
229 &self,
230 ) -> Result<risc0_zkp::core::hash::HashSuite<risc0_zkp::field::baby_bear::BabyBear>> {
231 risc0_zkp::core::hash::hash_suite_from_name(&self.hashfn)
232 .ok_or_else(|| anyhow::anyhow!("unsupported hash suite: {}", self.hashfn))
233 }
234}