1pub mod builder;
6
7use sp1_core_machine::io::SP1Stdin;
8use sp1_core_machine::riscv::RiscvAir;
9use sp1_hypercube::Machine;
10use sp1_primitives::SP1Field;
11use sp1_prover::{
12 worker::{SP1LightNode, SP1NodeCore},
13 Groth16Bn254Proof, PlonkBn254Proof, SP1VerifyingKey,
14};
15
16use crate::{
17 blocking::{
18 block_on,
19 cpu::CPUProverError,
20 prover::{BaseProveRequest, ProveRequest, Prover},
21 },
22 proof::verify_mock_public_inputs,
23 SP1Proof, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerificationError, StatusCode,
24};
25
26#[derive(Clone)]
28pub struct MockProver {
29 inner: SP1LightNode,
30}
31
32impl Default for MockProver {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl MockProver {
39 #[must_use]
41 pub fn new() -> Self {
42 Self::new_with_machine(RiscvAir::machine())
43 }
44
45 #[must_use]
47 pub fn new_with_machine(machine: Machine<SP1Field, RiscvAir<SP1Field>>) -> Self {
48 tracing::info!("initializing mock prover");
49 Self { inner: block_on(SP1LightNode::new_with_machine(machine)) }
50 }
51
52 pub(crate) fn from_node(inner: SP1LightNode) -> Self {
54 Self { inner }
55 }
56}
57
58impl Prover for MockProver {
59 type ProvingKey = SP1ProvingKey;
60
61 type Error = CPUProverError;
62
63 type ProveRequest<'a> = MockProveRequest<'a>;
64
65 fn inner(&self) -> &SP1NodeCore {
66 self.inner.inner()
67 }
68
69 fn prove<'a>(&'a self, pk: &'a Self::ProvingKey, stdin: SP1Stdin) -> Self::ProveRequest<'a> {
70 MockProveRequest { base: BaseProveRequest::new(self, pk, stdin) }
71 }
72
73 fn setup(&self, elf: sp1_build::Elf) -> Result<Self::ProvingKey, Self::Error> {
74 let vk = block_on(self.inner.setup(&elf))?;
75 Ok(SP1ProvingKey { vk, elf })
76 }
77
78 fn verify(
79 &self,
80 proof: &SP1ProofWithPublicValues,
81 vkey: &SP1VerifyingKey,
82 _status_code: Option<StatusCode>,
83 ) -> Result<(), SP1VerificationError> {
84 match &proof.proof {
85 SP1Proof::Plonk(PlonkBn254Proof { public_inputs, .. }) => {
86 verify_mock_public_inputs(vkey, &proof.public_values, public_inputs)
88 .map_err(SP1VerificationError::Plonk)
89 }
90 SP1Proof::Groth16(Groth16Bn254Proof { public_inputs, .. }) => {
91 verify_mock_public_inputs(vkey, &proof.public_values, public_inputs)
93 .map_err(SP1VerificationError::Groth16)
94 }
95 _ => Ok(()),
96 }
97 }
98}
99
100pub struct MockProveRequest<'a> {
102 pub(crate) base: BaseProveRequest<'a, MockProver>,
103}
104
105impl<'a> ProveRequest<'a, MockProver> for MockProveRequest<'a> {
106 fn base(&mut self) -> &mut BaseProveRequest<'a, MockProver> {
107 &mut self.base
108 }
109
110 fn run(self) -> Result<SP1ProofWithPublicValues, CPUProverError> {
111 let BaseProveRequest { prover, pk, mode, stdin, context_builder } = self.base;
112 tracing::info!(mode = ?mode, "generating mock proof");
113 let mut req = prover.execute(pk.elf.clone(), stdin);
114 req.context_builder = context_builder;
115 let (public_values, _) = req.run()?;
116 Ok(SP1ProofWithPublicValues::create_mock_proof(
117 &pk.vk,
118 public_values,
119 mode,
120 prover.version(),
121 ))
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use crate::{
128 blocking::prover::{ProveRequest, Prover},
129 utils::setup_logger,
130 SP1Stdin,
131 };
132
133 use super::MockProver;
134
135 #[test]
137 fn test_mock_proof_all_types() {
138 setup_logger();
139 let prover = MockProver::new();
140 let pk = prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key");
141
142 let mut stdin = SP1Stdin::new();
144 stdin.write(&10usize);
145 let core_proof =
146 prover.prove(&pk, stdin).core().run().expect("failed to create mock Core proof");
147 prover.verify(&core_proof, &pk.vk, None).expect("failed to verify mock Core proof");
148
149 let mut stdin = SP1Stdin::new();
151 stdin.write(&10usize);
152 let compressed_proof = prover
153 .prove(&pk, stdin)
154 .compressed()
155 .run()
156 .expect("failed to create mock Compressed proof");
157 prover
158 .verify(&compressed_proof, &pk.vk, None)
159 .expect("failed to verify mock Compressed proof");
160
161 let mut stdin = SP1Stdin::new();
163 stdin.write(&10usize);
164 let plonk_proof =
165 prover.prove(&pk, stdin).plonk().run().expect("failed to create mock Plonk proof");
166 prover.verify(&plonk_proof, &pk.vk, None).expect("failed to verify mock Plonk proof");
167
168 let mut stdin = SP1Stdin::new();
170 stdin.write(&10usize);
171 let groth16_proof =
172 prover.prove(&pk, stdin).groth16().run().expect("failed to create mock Groth16 proof");
173 prover.verify(&groth16_proof, &pk.vk, None).expect("failed to verify mock Groth16 proof");
174 }
175
176 #[test]
178 fn test_mock_proof_public_values() {
179 setup_logger();
180 let prover = MockProver::new();
181 let pk = prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key");
182 let mut stdin = SP1Stdin::new();
183 stdin.write(&10usize);
184
185 let (expected_pv, _) =
187 prover.execute(pk.elf.clone(), stdin.clone()).run().expect("failed to execute program");
188
189 let proof =
191 prover.prove(&pk, stdin).core().run().expect("failed to create mock Core proof");
192
193 assert_eq!(proof.public_values.as_slice(), expected_pv.as_slice());
195 }
196
197 #[test]
199 fn test_mock_plonk_proof_wrong_vkey_fails() {
200 setup_logger();
201 let prover = MockProver::new();
202
203 let pk1 =
205 prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key 1");
206 let pk2 =
207 prover.setup(test_artifacts::HELLO_WORLD_ELF).expect("failed to setup proving key 2");
208
209 let mut stdin = SP1Stdin::new();
211 stdin.write(&10usize);
212 let proof =
213 prover.prove(&pk1, stdin).plonk().run().expect("failed to create mock Plonk proof");
214
215 let result = prover.verify(&proof, &pk2.vk, None);
217 assert!(result.is_err(), "Verification should fail with wrong vkey");
218 }
219
220 #[test]
222 fn test_mock_groth16_proof_wrong_vkey_fails() {
223 setup_logger();
224 let prover = MockProver::new();
225
226 let pk1 =
228 prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key 1");
229 let pk2 =
230 prover.setup(test_artifacts::HELLO_WORLD_ELF).expect("failed to setup proving key 2");
231
232 let mut stdin = SP1Stdin::new();
234 stdin.write(&10usize);
235 let proof =
236 prover.prove(&pk1, stdin).groth16().run().expect("failed to create mock Groth16 proof");
237
238 let result = prover.verify(&proof, &pk2.vk, None);
240 assert!(result.is_err(), "Verification should fail with wrong vkey");
241 }
242
243 #[test]
245 fn test_mock_plonk_proof_tampered_public_values_fails() {
246 setup_logger();
247 let prover = MockProver::new();
248 let pk = prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key");
249
250 let mut stdin = SP1Stdin::new();
252 stdin.write(&10usize);
253 let mut proof =
254 prover.prove(&pk, stdin).plonk().run().expect("failed to create mock Plonk proof");
255
256 proof.public_values = sp1_primitives::io::SP1PublicValues::from(&[0xDE, 0xAD, 0xBE, 0xEF]);
258
259 let result = prover.verify(&proof, &pk.vk, None);
261 assert!(result.is_err(), "Verification should fail with tampered public values");
262 }
263
264 #[test]
266 fn test_mock_groth16_proof_tampered_public_values_fails() {
267 setup_logger();
268 let prover = MockProver::new();
269 let pk = prover.setup(test_artifacts::FIBONACCI_ELF).expect("failed to setup proving key");
270
271 let mut stdin = SP1Stdin::new();
273 stdin.write(&10usize);
274 let mut proof =
275 prover.prove(&pk, stdin).groth16().run().expect("failed to create mock Groth16 proof");
276
277 proof.public_values = sp1_primitives::io::SP1PublicValues::from(&[0xDE, 0xAD, 0xBE, 0xEF]);
279
280 let result = prover.verify(&proof, &pk.vk, None);
282 assert!(result.is_err(), "Verification should fail with tampered public values");
283 }
284}