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}