sp1_core_machine/
io.rs

1use serde::{de::DeserializeOwned, Deserialize, Serialize};
2use sp1_stark::{baby_bear_poseidon2::BabyBearPoseidon2, SP1ReduceProof, StarkVerifyingKey};
3
4/// Standard input for the prover.
5#[derive(Debug, Clone, Serialize, Deserialize, Default)]
6pub struct SP1Stdin {
7    /// Input stored as a vec of vec of bytes. It's stored this way because the read syscall reads
8    /// a vec of bytes at a time.
9    pub buffer: Vec<Vec<u8>>,
10    pub ptr: usize,
11    pub proofs: Vec<(SP1ReduceProof<BabyBearPoseidon2>, StarkVerifyingKey<BabyBearPoseidon2>)>,
12}
13
14impl SP1Stdin {
15    /// Create a new `SP1Stdin`.
16    pub const fn new() -> Self {
17        Self { buffer: Vec::new(), ptr: 0, proofs: Vec::new() }
18    }
19
20    /// Create a `SP1Stdin` from a slice of bytes.
21    pub fn from(data: &[u8]) -> Self {
22        Self { buffer: vec![data.to_vec()], ptr: 0, proofs: Vec::new() }
23    }
24
25    /// Read a value from the buffer.
26    pub fn read<T: DeserializeOwned>(&mut self) -> T {
27        let result: T =
28            bincode::deserialize(&self.buffer[self.ptr]).expect("failed to deserialize");
29        self.ptr += 1;
30        result
31    }
32
33    /// Read a slice of bytes from the buffer.
34    pub fn read_slice(&mut self, slice: &mut [u8]) {
35        slice.copy_from_slice(&self.buffer[self.ptr]);
36        self.ptr += 1;
37    }
38
39    /// Write a value to the buffer.
40    pub fn write<T: Serialize>(&mut self, data: &T) {
41        let mut tmp = Vec::new();
42        bincode::serialize_into(&mut tmp, data).expect("serialization failed");
43        self.buffer.push(tmp);
44    }
45
46    /// Write a slice of bytes to the buffer.
47    pub fn write_slice(&mut self, slice: &[u8]) {
48        self.buffer.push(slice.to_vec());
49    }
50
51    pub fn write_vec(&mut self, vec: Vec<u8>) {
52        self.buffer.push(vec);
53    }
54
55    pub fn write_proof(
56        &mut self,
57        proof: SP1ReduceProof<BabyBearPoseidon2>,
58        vk: StarkVerifyingKey<BabyBearPoseidon2>,
59    ) {
60        self.proofs.push((proof, vk));
61    }
62}
63
64pub mod proof_serde {
65    use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
66    use sp1_stark::{MachineProof, StarkGenericConfig};
67
68    pub fn serialize<S, SC: StarkGenericConfig + Serialize>(
69        proof: &MachineProof<SC>,
70        serializer: S,
71    ) -> Result<S::Ok, S::Error>
72    where
73        S: serde::Serializer,
74    {
75        if serializer.is_human_readable() {
76            let bytes = bincode::serialize(proof).unwrap();
77            let hex_bytes = hex::encode(bytes);
78            serializer.serialize_str(&hex_bytes)
79        } else {
80            proof.serialize(serializer)
81        }
82    }
83
84    pub fn deserialize<'de, D, SC: StarkGenericConfig + DeserializeOwned>(
85        deserializer: D,
86    ) -> Result<MachineProof<SC>, D::Error>
87    where
88        D: Deserializer<'de>,
89    {
90        if deserializer.is_human_readable() {
91            let hex_bytes = String::deserialize(deserializer).unwrap();
92            let bytes = hex::decode(hex_bytes).unwrap();
93            let proof = bincode::deserialize(&bytes).map_err(serde::de::Error::custom)?;
94            Ok(proof)
95        } else {
96            MachineProof::<SC>::deserialize(deserializer)
97        }
98    }
99}