sp1_primitives/
io.rs

1use crate::types::Buffer;
2use num_bigint::BigUint;
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5
6/// Public values for the prover.
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8pub struct SP1PublicValues {
9    buffer: Buffer,
10}
11
12impl SP1PublicValues {
13    /// Create a new `SP1PublicValues`.
14    pub const fn new() -> Self {
15        Self { buffer: Buffer::new() }
16    }
17
18    pub fn raw(&self) -> String {
19        format!("0x{}", hex::encode(self.as_slice()))
20    }
21
22    /// Create a `SP1PublicValues` from a slice of bytes.
23    pub fn from(data: &[u8]) -> Self {
24        Self { buffer: Buffer::from(data) }
25    }
26
27    pub fn as_slice(&self) -> &[u8] {
28        self.buffer.data.as_slice()
29    }
30
31    pub fn to_vec(&self) -> Vec<u8> {
32        self.buffer.data.clone()
33    }
34
35    /// Read a value from the buffer.    
36    pub fn read<T: Serialize + DeserializeOwned>(&mut self) -> T {
37        self.buffer.read()
38    }
39
40    /// Read a slice of bytes from the buffer.
41    pub fn read_slice(&mut self, slice: &mut [u8]) {
42        self.buffer.read_slice(slice);
43    }
44
45    /// Write a value to the buffer.
46    pub fn write<T: Serialize>(&mut self, data: &T) {
47        self.buffer.write(data);
48    }
49
50    /// Write a slice of bytes to the buffer.
51    pub fn write_slice(&mut self, slice: &[u8]) {
52        self.buffer.write_slice(slice);
53    }
54
55    /// Hash the public values using SHA256.
56    pub fn hash(&self) -> Vec<u8> {
57        sha256_hash(self.buffer.data.as_slice())
58    }
59
60    /// Hash the public values using Blake3.
61    pub fn blake3_hash(&self) -> Vec<u8> {
62        blake3_hash(self.buffer.data.as_slice())
63    }
64
65    /// Hash the public values using SHA256, mask the top 3 bits and return a BigUint.
66    /// Matches the implementation of `hashPublicValues` in the Solidity verifier.
67    ///
68    /// ```solidity
69    /// sha256(publicValues) & bytes32(uint256((1 << 253) - 1));
70    /// ```
71    pub fn hash_bn254(&self) -> BigUint {
72        self.hash_bn254_with_fn(sha256_hash)
73    }
74
75    /// Hash the public values using the provided `hasher` function, mask the top 3 bits and
76    /// return a BigUint.
77    pub fn hash_bn254_with_fn<F>(&self, hasher: F) -> BigUint
78    where
79        F: Fn(&[u8]) -> Vec<u8>,
80    {
81        // Hash the public values.
82        let mut hash = hasher(self.buffer.data.as_slice());
83
84        // Mask the top 3 bits.
85        hash[0] &= 0b00011111;
86
87        // Return the masked hash as a BigUint.
88        BigUint::from_bytes_be(hash.as_slice())
89    }
90}
91
92impl AsRef<[u8]> for SP1PublicValues {
93    fn as_ref(&self) -> &[u8] {
94        &self.buffer.data
95    }
96}
97
98/// Hash the input using SHA256.
99pub fn sha256_hash(input: &[u8]) -> Vec<u8> {
100    let mut hasher = Sha256::new();
101    hasher.update(input);
102    hasher.finalize().to_vec()
103}
104
105/// Hash the input using Blake3.
106pub fn blake3_hash(input: &[u8]) -> Vec<u8> {
107    blake3::hash(input).as_bytes().to_vec()
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_hash_public_values() {
116        let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
117        let test_bytes = hex::decode(test_hex).unwrap();
118
119        let mut public_values = SP1PublicValues::new();
120        public_values.write_slice(&test_bytes);
121        let hash = public_values.hash_bn254();
122
123        let expected_hash = "1ce987d0a7fcc2636fe87e69295ba12b1cc46c256b369ae7401c51b805ee91bd";
124        let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());
125
126        assert_eq!(hash, expected_hash_biguint);
127    }
128
129    #[test]
130    fn test_hash_public_values_blake3() {
131        let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
132        let test_bytes = hex::decode(test_hex).unwrap();
133
134        let mut public_values = SP1PublicValues::new();
135        public_values.write_slice(&test_bytes);
136        let hash = public_values.hash_bn254_with_fn(blake3_hash);
137
138        let expected_hash = "1639647ab9e42519f0cbdcf343033482b018c0c1ed48f8367f32381c60913447";
139        let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());
140
141        assert_eq!(hash, expected_hash_biguint);
142    }
143}