sp1_sdk/env/prove.rs
1//! # Env Proving
2//!
3//! This module provides a builder for proving a program.
4
5use anyhow::Result;
6use sp1_core_machine::io::SP1Stdin;
7use sp1_prover::{components::CpuProverComponents, SP1ProvingKey};
8
9use crate::{Prover, SP1ProofMode, SP1ProofWithPublicValues};
10
11/// Builder to prepare and configure proving execution of a program on an input.
12/// May be run with [`Self::run`].
13pub struct EnvProveBuilder<'a> {
14 pub(crate) prover: &'a dyn Prover<CpuProverComponents>,
15 pub(crate) mode: SP1ProofMode,
16 pub(crate) pk: &'a SP1ProvingKey,
17 pub(crate) stdin: SP1Stdin,
18}
19
20impl EnvProveBuilder<'_> {
21 /// Set the proof kind to [`SP1ProofMode::Core`] mode.
22 ///
23 /// # Details
24 /// This is the default mode for the prover. The proofs grow linearly in size with the number
25 /// of cycles.
26 ///
27 /// # Example
28 /// ```rust,no_run
29 /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
30 ///
31 /// let elf = &[1, 2, 3];
32 /// let stdin = SP1Stdin::new();
33 ///
34 /// let client = ProverClient::from_env();
35 /// let (pk, vk) = client.setup(elf);
36 /// let builder = client.prove(&pk, &stdin).core().run();
37 /// ```
38 #[must_use]
39 pub fn core(mut self) -> Self {
40 self.mode = SP1ProofMode::Core;
41 self
42 }
43
44 /// Set the proof kind to [`SP1ProofMode::Compressed`] mode.
45 ///
46 /// # Details
47 /// This mode produces a proof that is of constant size, regardless of the number of cycles. It
48 /// takes longer to prove than [`SP1ProofMode::Core`] due to the need to recursively aggregate
49 /// proofs into a single proof.
50 ///
51 /// # Example
52 /// ```rust,no_run
53 /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
54 ///
55 /// let elf = &[1, 2, 3];
56 /// let stdin = SP1Stdin::new();
57 ///
58 /// let client = ProverClient::from_env();
59 /// let (pk, vk) = client.setup(elf);
60 /// let builder = client.prove(&pk, &stdin).compressed().run();
61 /// ```
62 #[must_use]
63 pub fn compressed(mut self) -> Self {
64 self.mode = SP1ProofMode::Compressed;
65 self
66 }
67
68 /// Set the proof mode to [`SP1ProofMode::Plonk`] mode.
69 ///
70 /// # Details
71 /// This mode produces a const size PLONK proof that can be verified on chain for roughly ~300k
72 /// gas. This mode is useful for producing a maximally small proof that can be verified on
73 /// chain. For more efficient SNARK wrapping, you can use the [`SP1ProofMode::Groth16`] mode but
74 /// this mode is more .
75 ///
76 /// # Example
77 /// ```rust,no_run
78 /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
79 ///
80 /// let elf = &[1, 2, 3];
81 /// let stdin = SP1Stdin::new();
82 ///
83 /// let client = ProverClient::from_env();
84 /// let (pk, vk) = client.setup(elf);
85 /// let builder = client.prove(&pk, &stdin).plonk().run();
86 /// ```
87 #[must_use]
88 pub fn plonk(mut self) -> Self {
89 self.mode = SP1ProofMode::Plonk;
90 self
91 }
92
93 /// Set the proof mode to [`SP1ProofMode::Groth16`] mode.
94 ///
95 /// # Details
96 /// This mode produces a Groth16 proof that can be verified on chain for roughly ~100k gas. This
97 /// mode is useful for producing a proof that can be verified on chain with minimal gas.
98 ///
99 /// # Example
100 /// ```rust,no_run
101 /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
102 ///
103 /// let elf = &[1, 2, 3];
104 /// let stdin = SP1Stdin::new();
105 ///
106 /// let client = ProverClient::from_env();
107 /// let (pk, vk) = client.setup(elf);
108 /// let builder = client.prove(&pk, &stdin).groth16().run();
109 /// ```
110 #[must_use]
111 pub fn groth16(mut self) -> Self {
112 self.mode = SP1ProofMode::Groth16;
113 self
114 }
115
116 /// Set the proof mode to the given [`SP1ProofMode`].
117 ///
118 /// # Details
119 /// This method is useful for setting the proof mode to a custom mode.
120 ///
121 /// # Example
122 /// ```rust,no_run
123 /// use sp1_sdk::{Prover, ProverClient, SP1ProofMode, SP1Stdin};
124 ///
125 /// let elf = &[1, 2, 3];
126 /// let stdin = SP1Stdin::new();
127 ///
128 /// let client = ProverClient::from_env();
129 /// let (pk, vk) = client.setup(elf);
130 /// let builder = client.prove(&pk, &stdin).mode(SP1ProofMode::Groth16).run();
131 /// ```
132 #[must_use]
133 pub fn mode(mut self, mode: SP1ProofMode) -> Self {
134 self.mode = mode;
135 self
136 }
137
138 /// Run the prover with the built arguments.
139 ///
140 /// # Details
141 /// This method will run the prover with the built arguments. If the prover fails to run, the
142 /// method will return an error.
143 ///
144 /// # Example
145 /// ```rust,no_run
146 /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
147 ///
148 /// let elf = &[1, 2, 3];
149 /// let stdin = SP1Stdin::new();
150 ///
151 /// let client = ProverClient::from_env();
152 /// let (pk, vk) = client.setup(elf);
153 /// let proof = client.prove(&pk, &stdin).run().unwrap();
154 /// ```
155 pub fn run(self) -> Result<SP1ProofWithPublicValues> {
156 let Self { prover, mode: kind, pk, stdin } = self;
157
158 // Dump the program and stdin to files for debugging if `SP1_DUMP` is set.
159 crate::utils::sp1_dump(&pk.elf, &stdin);
160
161 prover.prove(pk, &stdin, kind)
162 }
163}