1use crate::types::Buffer;
2use alloc::{format, string::String, vec::Vec};
3use num_bigint::BigUint;
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use sha2::{Digest, Sha256};
6
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
9pub struct SP1PublicValues {
10 buffer: Buffer,
11}
12
13impl SP1PublicValues {
14 pub const fn new() -> Self {
16 Self { buffer: Buffer::new() }
17 }
18
19 pub fn raw(&self) -> String {
20 format!("0x{}", hex::encode(self.as_slice()))
21 }
22
23 pub fn from(data: &[u8]) -> Self {
25 Self { buffer: Buffer::from(data) }
26 }
27
28 pub fn as_slice(&self) -> &[u8] {
29 self.buffer.data.as_slice()
30 }
31
32 pub fn to_vec(&self) -> Vec<u8> {
33 self.buffer.data.clone()
34 }
35
36 pub fn read<T: Serialize + DeserializeOwned>(&mut self) -> T {
38 self.buffer.read()
39 }
40
41 pub fn read_slice(&mut self, slice: &mut [u8]) {
43 self.buffer.read_slice(slice);
44 }
45
46 pub fn write<T: Serialize>(&mut self, data: &T) {
48 self.buffer.write(data);
49 }
50
51 pub fn write_slice(&mut self, slice: &[u8]) {
53 self.buffer.write_slice(slice);
54 }
55
56 pub fn hash(&self) -> Vec<u8> {
58 sha256_hash(self.buffer.data.as_slice())
59 }
60
61 pub fn blake3_hash(&self) -> Vec<u8> {
63 blake3_hash(self.buffer.data.as_slice())
64 }
65
66 pub fn hash_bn254(&self) -> BigUint {
73 self.hash_bn254_with_fn(sha256_hash)
74 }
75
76 pub fn hash_bn254_with_fn<F>(&self, hasher: F) -> BigUint
79 where
80 F: Fn(&[u8]) -> Vec<u8>,
81 {
82 let mut hash = hasher(self.buffer.data.as_slice());
84
85 hash[0] &= 0b00011111;
87
88 BigUint::from_bytes_be(hash.as_slice())
90 }
91}
92
93impl AsRef<[u8]> for SP1PublicValues {
94 fn as_ref(&self) -> &[u8] {
95 &self.buffer.data
96 }
97}
98
99pub fn sha256_hash(input: &[u8]) -> Vec<u8> {
101 let mut hasher = Sha256::new();
102 hasher.update(input);
103 hasher.finalize().to_vec()
104}
105
106pub fn blake3_hash(input: &[u8]) -> Vec<u8> {
108 blake3::hash(input).as_bytes().to_vec()
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_hash_public_values() {
117 let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
118 let test_bytes = hex::decode(test_hex).unwrap();
119
120 let mut public_values = SP1PublicValues::new();
121 public_values.write_slice(&test_bytes);
122 let hash = public_values.hash_bn254();
123
124 let expected_hash = "1ce987d0a7fcc2636fe87e69295ba12b1cc46c256b369ae7401c51b805ee91bd";
125 let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());
126
127 assert_eq!(hash, expected_hash_biguint);
128 }
129
130 #[test]
131 fn test_hash_public_values_blake3() {
132 let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
133 let test_bytes = hex::decode(test_hex).unwrap();
134
135 let mut public_values = SP1PublicValues::new();
136 public_values.write_slice(&test_bytes);
137 let hash = public_values.hash_bn254_with_fn(blake3_hash);
138
139 let expected_hash = "1639647ab9e42519f0cbdcf343033482b018c0c1ed48f8367f32381c60913447";
140 let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());
141
142 assert_eq!(hash, expected_hash_biguint);
143 }
144}