sp1_sdk/blocking/env/
mod.rs1#[cfg(feature = "network")]
7use crate::blocking::NetworkProver;
8#[cfg(feature = "cuda")]
9use crate::blocking::{cuda::builder::CudaProverBuilder, CudaProver};
10use crate::{
11 blocking::{prover::BaseProveRequest, CpuProver, LightProver, MockProver, Prover},
12 SP1ProofWithPublicValues, SP1VerificationError, StatusCode,
13};
14use sp1_core_executor::SP1CoreOpts;
15
16pub mod pk;
17pub mod prove;
19pub use pk::EnvProvingKey;
20use prove::EnvProveRequest;
21use sp1_core_machine::io::SP1Stdin;
22use sp1_core_machine::riscv::RiscvAir;
23use sp1_hypercube::Machine;
24use sp1_primitives::{Elf, SP1Field};
25use sp1_prover::{worker::SP1NodeCore, SP1VerifyingKey};
26
27#[derive(Clone)]
30pub enum EnvProver {
31 Mock(MockProver),
33 Light(LightProver),
35 Cpu(CpuProver),
37 #[cfg(feature = "cuda")]
39 Cuda(CudaProver),
40 #[cfg(feature = "network")]
42 Network(Box<NetworkProver>),
43}
44
45impl Default for EnvProver {
46 fn default() -> Self {
47 Self::new()
48 }
49}
50
51impl EnvProver {
52 #[must_use]
59 pub fn new() -> Self {
60 Self::new_with_machine(RiscvAir::machine())
61 }
62
63 #[must_use]
65 pub fn new_with_machine(machine: Machine<SP1Field, RiscvAir<SP1Field>>) -> Self {
66 Self::from_env_with_opts_and_machine(None, machine)
67 }
68
69 #[must_use]
84 pub fn with_opts(self, opts: SP1CoreOpts) -> Self {
85 Self::from_env_with_opts(Some(opts))
86 }
87
88 #[must_use]
95 pub fn from_env_with_opts(core_opts: Option<SP1CoreOpts>) -> Self {
96 Self::from_env_with_opts_and_machine(core_opts, RiscvAir::machine())
97 }
98
99 #[must_use]
101 pub fn from_env_with_opts_and_machine(
102 core_opts: Option<SP1CoreOpts>,
103 machine: Machine<SP1Field, RiscvAir<SP1Field>>,
104 ) -> Self {
105 let prover = match std::env::var("SP1_PROVER") {
106 Ok(prover) => prover,
107 Err(_) => "cpu".to_string(),
108 };
109
110 match prover.as_str() {
111 "cpu" => Self::Cpu(CpuProver::new_with_opts_and_machine(core_opts, machine)),
112 #[cfg(feature = "cuda")]
113 "cuda" => Self::Cuda(CudaProverBuilder::new_with_machine(machine).build()),
114 #[cfg(not(feature = "cuda"))]
115 "cuda" => panic!("The CUDA prover requires the `cuda` feature to be enabled"),
116 "mock" => Self::Mock(MockProver::new_with_machine(machine)),
117 "light" => Self::Light(LightProver::new_with_machine(machine)),
118 #[cfg(feature = "network")]
119 "network" => Self::Network(Box::new(
120 crate::blocking::network::builder::NetworkProverBuilder::new_with_machine(machine)
121 .build(),
122 )),
123 #[cfg(not(feature = "network"))]
124 "network" => panic!("The network prover requires the `network` feature to be enabled"),
125 _ => unreachable!(),
126 }
127 }
128}
129
130impl Prover for EnvProver {
131 type Error = anyhow::Error;
132 type ProvingKey = EnvProvingKey;
133 type ProveRequest<'a> = prove::EnvProveRequest<'a>;
134
135 fn inner(&self) -> &SP1NodeCore {
136 match self {
137 Self::Cpu(prover) => prover.inner(),
138 #[cfg(feature = "cuda")]
139 Self::Cuda(prover) => prover.inner(),
140 Self::Mock(prover) => prover.inner(),
141 Self::Light(prover) => prover.inner(),
142 #[cfg(feature = "network")]
143 Self::Network(prover) => prover.inner(),
144 }
145 }
146 fn setup(&self, elf: Elf) -> Result<Self::ProvingKey, Self::Error> {
147 match self {
148 Self::Cpu(prover) => {
149 let pk = prover.setup(elf)?;
150 Ok(EnvProvingKey::cpu(pk))
151 }
152 #[cfg(feature = "cuda")]
153 Self::Cuda(prover) => {
154 let pk = prover.setup(elf)?;
155 Ok(EnvProvingKey::cuda(pk))
156 }
157 Self::Mock(prover) => {
158 let pk = prover.setup(elf)?;
159 Ok(EnvProvingKey::mock(pk))
160 }
161 Self::Light(prover) => {
162 let pk = prover.setup(elf)?;
163 Ok(EnvProvingKey::light(pk))
164 }
165 #[cfg(feature = "network")]
166 Self::Network(prover) => {
167 let pk = prover.setup(elf)?;
168 Ok(EnvProvingKey::network(pk))
169 }
170 }
171 }
172
173 fn prove<'a>(&'a self, pk: &'a Self::ProvingKey, stdin: SP1Stdin) -> Self::ProveRequest<'a> {
174 EnvProveRequest { base: BaseProveRequest::new(self, pk, stdin) }
175 }
176
177 fn verify(
178 &self,
179 proof: &SP1ProofWithPublicValues,
180 vkey: &SP1VerifyingKey,
181 status_code: Option<StatusCode>,
182 ) -> Result<(), SP1VerificationError> {
183 match self {
184 Self::Cpu(prover) => prover.verify(proof, vkey, status_code),
185 #[cfg(feature = "cuda")]
186 Self::Cuda(prover) => prover.verify(proof, vkey, status_code),
187 Self::Mock(prover) => prover.verify(proof, vkey, status_code),
188 Self::Light(prover) => prover.verify(proof, vkey, status_code),
189 #[cfg(feature = "network")]
190 Self::Network(prover) => prover.verify(proof, vkey, status_code),
191 }
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use crate::{
198 blocking::{
199 prover::{ProveRequest, Prover},
200 MockProver,
201 },
202 utils::setup_logger,
203 SP1Stdin,
204 };
205
206 use super::EnvProver;
207
208 #[test]
213 fn test_envprover_mock_verifies_plonk_and_groth16() {
214 setup_logger();
215 let mock = MockProver::new();
216 let pk = mock.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key");
217
218 let mut stdin = SP1Stdin::new();
219 stdin.write(&10usize);
220 let plonk_proof =
221 mock.prove(&pk, stdin).plonk().run().expect("failed to create mock Plonk proof");
222
223 let mut stdin = SP1Stdin::new();
224 stdin.write(&10usize);
225 let groth16_proof =
226 mock.prove(&pk, stdin).groth16().run().expect("failed to create mock Groth16 proof");
227
228 let env = EnvProver::Mock(mock);
229 env.verify(&plonk_proof, &pk.vk, None)
230 .expect("EnvProver::Mock must verify a mock Plonk proof");
231 env.verify(&groth16_proof, &pk.vk, None)
232 .expect("EnvProver::Mock must verify a mock Groth16 proof");
233 }
234}