sp1_sdk/env/
mod.rs

1//! # SP1 Environment Prover
2//!
3//! A prover that can execute programs and generate proofs with a different implementation based on
4//! the value of certain environment variables.
5
6mod prove;
7
8use std::env;
9
10use anyhow::Result;
11use prove::EnvProveBuilder;
12use sp1_core_executor::SP1ContextBuilder;
13use sp1_core_machine::io::SP1Stdin;
14use sp1_cuda::MoongateServer;
15use sp1_prover::{components::CpuProverComponents, SP1Prover, SP1ProvingKey, SP1VerifyingKey};
16
17use super::{Prover, SP1VerificationError};
18#[cfg(feature = "network")]
19use crate::network::builder::NetworkProverBuilder;
20use crate::{
21    cpu::{execute::CpuExecuteBuilder, CpuProver},
22    cuda::CudaProver,
23    utils::check_release_build,
24    SP1ProofMode, SP1ProofWithPublicValues,
25};
26
27/// A prover that can execute programs and generate proofs with a different implementation based on
28/// the value of certain environment variables.
29///
30/// The environment variables are described in [`EnvProver::new`].
31pub struct EnvProver {
32    pub(crate) prover: Box<dyn Prover<CpuProverComponents>>,
33}
34
35impl EnvProver {
36    /// Creates a new [`EnvProver`] with the given configuration.
37    ///
38    /// The following environment variables are used to configure the prover:
39    /// - `SP1_PROVER`: The type of prover to use. Must be one of `mock`, `local`, `cuda`, or
40    ///   `network`.
41    /// - `NETWORK_PRIVATE_KEY`: The private key to use for the network prover.
42    /// - `NETWORK_RPC_URL`: The RPC URL to use for the network prover.
43    #[must_use]
44    pub fn new() -> Self {
45        let mode = if let Ok(mode) = env::var("SP1_PROVER") {
46            mode
47        } else {
48            tracing::warn!("SP1_PROVER environment variable not set, defaulting to 'cpu'");
49            "cpu".to_string()
50        };
51
52        let prover: Box<dyn Prover<CpuProverComponents>> = match mode.as_str() {
53            "mock" => Box::new(CpuProver::mock()),
54            "cpu" => {
55                check_release_build();
56                Box::new(CpuProver::new())
57            },
58            "cuda" => {
59                check_release_build();
60                Box::new(CudaProver::new(SP1Prover::new(), MoongateServer::default()))
61            }
62            "network" => {
63                #[cfg(not(feature = "network"))]
64                panic!(
65                    r#"The network prover requires the 'network' feature to be enabled.
66                    Please enable it in your Cargo.toml with:
67                    sp1-sdk = {{ version = "...", features = ["network"] }}"#
68                );
69
70                #[cfg(feature = "network")]
71                {
72                    Box::new(NetworkProverBuilder::default().build())
73                }
74            }
75            _ => panic!(
76                "Invalid SP1_PROVER value. Expected one of: mock, cpu, cuda, or network. Got: '{mode}'.\n\
77                Please set the SP1_PROVER environment variable to one of the supported values."
78            ),
79        };
80        EnvProver { prover }
81    }
82
83    /// Creates a new [`CpuExecuteBuilder`] for simulating the execution of a program on the CPU.
84    ///
85    /// # Details
86    /// The builder is used for both the [`crate::cpu::CpuProver`] and [`crate::CudaProver`] client
87    /// types.
88    ///
89    /// # Example
90    /// ```rust,no_run
91    /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
92    ///
93    /// let elf = &[1, 2, 3];
94    /// let stdin = SP1Stdin::new();
95    ///
96    /// let client = ProverClient::from_env();
97    /// let (public_values, execution_report) = client.execute(elf, &stdin).run().unwrap();
98    /// ```
99    #[must_use]
100    pub fn execute<'a>(&'a self, elf: &'a [u8], stdin: &SP1Stdin) -> CpuExecuteBuilder<'a> {
101        CpuExecuteBuilder {
102            prover: self.prover.inner(),
103            elf,
104            stdin: stdin.clone(),
105            context_builder: SP1ContextBuilder::default(),
106        }
107    }
108
109    /// Creates a new [`EnvProve`] for proving a program on the CPU.
110    ///
111    /// # Details
112    /// The builder is used for only the [`crate::cpu::CpuProver`] client type.
113    ///
114    /// # Example
115    /// ```rust,no_run
116    /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
117    ///
118    /// let elf = &[1, 2, 3];
119    /// let stdin = SP1Stdin::new();
120    ///
121    /// let client = ProverClient::from_env();
122    /// let (pk, vk) = client.setup(elf);
123    /// let builder = client.prove(&pk, &stdin).core().run();
124    /// ```
125    #[must_use]
126    pub fn prove<'a>(&'a self, pk: &'a SP1ProvingKey, stdin: &'a SP1Stdin) -> EnvProveBuilder<'a> {
127        EnvProveBuilder {
128            prover: self.prover.as_ref(),
129            mode: SP1ProofMode::Core,
130            pk,
131            stdin: stdin.clone(),
132        }
133    }
134
135    /// Verifies that the given proof is valid and matches the given verification key produced by
136    /// [`Self::setup`].
137    ///
138    /// ### Examples
139    /// ```no_run
140    /// use sp1_sdk::{ProverClient, SP1Stdin};
141    ///
142    /// let elf = test_artifacts::FIBONACCI_ELF;
143    /// let stdin = SP1Stdin::new();
144    ///
145    /// let client = ProverClient::from_env();
146    /// let (pk, vk) = client.setup(elf);
147    /// let proof = client.prove(&pk, &stdin).run().unwrap();
148    /// client.verify(&proof, &vk).unwrap();
149    /// ```
150    pub fn verify(
151        &self,
152        proof: &SP1ProofWithPublicValues,
153        vk: &SP1VerifyingKey,
154    ) -> Result<(), SP1VerificationError> {
155        self.prover.verify(proof, vk)
156    }
157
158    /// Setup a program to be proven and verified by the SP1 RISC-V zkVM by computing the proving
159    /// and verifying keys.
160    #[must_use]
161    pub fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
162        self.prover.setup(elf)
163    }
164}
165
166impl Default for EnvProver {
167    fn default() -> Self {
168        Self::new()
169    }
170}
171
172impl Prover<CpuProverComponents> for EnvProver {
173    fn inner(&self) -> &SP1Prover<CpuProverComponents> {
174        self.prover.inner()
175    }
176
177    fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
178        self.prover.setup(elf)
179    }
180
181    fn prove(
182        &self,
183        pk: &SP1ProvingKey,
184        stdin: &SP1Stdin,
185        mode: SP1ProofMode,
186    ) -> Result<SP1ProofWithPublicValues> {
187        self.prover.prove(pk, stdin, mode)
188    }
189
190    fn verify(
191        &self,
192        bundle: &SP1ProofWithPublicValues,
193        vkey: &SP1VerifyingKey,
194    ) -> Result<(), SP1VerificationError> {
195        self.prover.verify(bundle, vkey)
196    }
197}