1use crate::types::Buffer;
2use num_bigint::BigUint;
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8pub struct SP1PublicValues {
9 buffer: Buffer,
10}
11
12impl SP1PublicValues {
13 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 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 pub fn read<T: Serialize + DeserializeOwned>(&mut self) -> T {
37 self.buffer.read()
38 }
39
40 pub fn read_slice(&mut self, slice: &mut [u8]) {
42 self.buffer.read_slice(slice);
43 }
44
45 pub fn write<T: Serialize>(&mut self, data: &T) {
47 self.buffer.write(data);
48 }
49
50 pub fn write_slice(&mut self, slice: &[u8]) {
52 self.buffer.write_slice(slice);
53 }
54
55 pub fn hash(&self) -> Vec<u8> {
57 sha256_hash(self.buffer.data.as_slice())
58 }
59
60 pub fn blake3_hash(&self) -> Vec<u8> {
62 blake3_hash(self.buffer.data.as_slice())
63 }
64
65 pub fn hash_bn254(&self) -> BigUint {
72 self.hash_bn254_with_fn(sha256_hash)
73 }
74
75 pub fn hash_bn254_with_fn<F>(&self, hasher: F) -> BigUint
78 where
79 F: Fn(&[u8]) -> Vec<u8>,
80 {
81 let mut hash = hasher(self.buffer.data.as_slice());
83
84 hash[0] &= 0b00011111;
86
87 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
98pub fn sha256_hash(input: &[u8]) -> Vec<u8> {
100 let mut hasher = Sha256::new();
101 hasher.update(input);
102 hasher.finalize().to_vec()
103}
104
105pub 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}