Skip to content

Commit

Permalink
refactor: move SP1PublicValues to sp1-primitives (#1546)
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI authored Sep 26, 2024
1 parent 40f62d4 commit 3bf0cd2
Show file tree
Hide file tree
Showing 29 changed files with 253 additions and 240 deletions.
7 changes: 6 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/core/machine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ strum = "0.26"
web-time = "1.1.0"
rayon-scan = "0.1.1"
thiserror = "1.0.63"
num-bigint = { version = "0.4.6", default-features = false }
rand = "0.8.5"
bytemuck = "1.16.0"
hashbrown = { version = "0.14.5", features = ["serde", "inline-more"] }
Expand Down
106 changes: 0 additions & 106 deletions crates/core/machine/src/io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
use crate::utils::Buffer;
use k256::sha2::{Digest, Sha256};
use num_bigint::BigUint;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use sp1_stark::{baby_bear_poseidon2::BabyBearPoseidon2, ShardProof, StarkVerifyingKey};

Expand All @@ -14,12 +11,6 @@ pub struct SP1Stdin {
pub proofs: Vec<(ShardProof<BabyBearPoseidon2>, StarkVerifyingKey<BabyBearPoseidon2>)>,
}

/// Public values for the prover.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SP1PublicValues {
buffer: Buffer,
}

impl SP1Stdin {
/// Create a new `SP1Stdin`.
pub const fn new() -> Self {
Expand Down Expand Up @@ -70,83 +61,6 @@ impl SP1Stdin {
}
}

impl SP1PublicValues {
/// Create a new `SP1PublicValues`.
pub const fn new() -> Self {
Self { buffer: Buffer::new() }
}

pub fn raw(&self) -> String {
format!("0x{}", hex::encode(self.buffer.data.clone()))
}

/// Create a `SP1PublicValues` from a slice of bytes.
pub fn from(data: &[u8]) -> Self {
Self { buffer: Buffer::from(data) }
}

pub fn as_slice(&self) -> &[u8] {
self.buffer.data.as_slice()
}

pub fn to_vec(&self) -> Vec<u8> {
self.buffer.data.clone()
}

/// Read a value from the buffer.
pub fn read<T: Serialize + DeserializeOwned>(&mut self) -> T {
self.buffer.read()
}

/// Read a slice of bytes from the buffer.
pub fn read_slice(&mut self, slice: &mut [u8]) {
self.buffer.read_slice(slice);
}

/// Write a value to the buffer.
pub fn write<T: Serialize>(&mut self, data: &T) {
self.buffer.write(data);
}

/// Write a slice of bytes to the buffer.
pub fn write_slice(&mut self, slice: &[u8]) {
self.buffer.write_slice(slice);
}

/// Hash the public values.
pub fn hash(&self) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(self.buffer.data.as_slice());
hasher.finalize().to_vec()
}

/// Hash the public values, mask the top 3 bits and return a BigUint. Matches the implementation
/// of `hashPublicValues` in the Solidity verifier.
///
/// ```solidity
/// sha256(publicValues) & bytes32(uint256((1 << 253) - 1));
/// ```
pub fn hash_bn254(&self) -> BigUint {
// Hash the public values.
let mut hasher = Sha256::new();
hasher.update(self.buffer.data.as_slice());
let hash_result = hasher.finalize();
let mut hash = hash_result.to_vec();

// Mask the top 3 bits.
hash[0] &= 0b00011111;

// Return the masked hash as a BigUint.
BigUint::from_bytes_be(&hash)
}
}

impl AsRef<[u8]> for SP1PublicValues {
fn as_ref(&self) -> &[u8] {
&self.buffer.data
}
}

pub mod proof_serde {
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
use sp1_stark::{MachineProof, StarkGenericConfig};
Expand Down Expand Up @@ -183,23 +97,3 @@ pub mod proof_serde {
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_hash_public_values() {
let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
let test_bytes = hex::decode(test_hex).unwrap();

let mut public_values = SP1PublicValues::new();
public_values.write_slice(&test_bytes);
let hash = public_values.hash_bn254();

let expected_hash = "1ce987d0a7fcc2636fe87e69295ba12b1cc46c256b369ae7401c51b805ee91bd";
let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());

assert_eq!(hash, expected_hash_biguint);
}
}
3 changes: 2 additions & 1 deletion crates/core/machine/src/syscall/precompiles/keccak256/air.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ where
#[cfg(test)]
mod test {
use crate::{
io::{SP1PublicValues, SP1Stdin},
io::SP1Stdin,
riscv::RiscvAir,
utils::{prove, setup_logger, tests::KECCAK256_ELF},
};
use sp1_primitives::io::SP1PublicValues;

use rand::{Rng, SeedableRng};
use sp1_core_executor::Program;
Expand Down
56 changes: 0 additions & 56 deletions crates/core/machine/src/utils/buffer.rs

This file was deleted.

2 changes: 0 additions & 2 deletions crates/core/machine/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
mod buffer;
pub mod concurrency;
mod logger;
#[cfg(any(test, feature = "programs"))]
Expand All @@ -7,7 +6,6 @@ mod prove;
mod span;
mod tracer;

pub use buffer::*;
pub use logger::*;
pub use prove::*;
use sp1_curves::params::Limbs;
Expand Down
5 changes: 3 additions & 2 deletions crates/core/machine/src/utils/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ use thiserror::Error;
use p3_baby_bear::BabyBear;
use p3_field::PrimeField32;

use crate::riscv::cost::CostEstimator;
use crate::{
io::{SP1PublicValues, SP1Stdin},
io::SP1Stdin,
riscv::cost::CostEstimator,
utils::{chunk_vec, concurrency::TurnBasedSync},
};
use sp1_core_executor::events::sorted_table_lines;
use sp1_primitives::io::SP1PublicValues;

use sp1_core_executor::{
subproof::NoOpSubproofVerifier, ExecutionError, ExecutionRecord, ExecutionReport, Executor,
Expand Down
5 changes: 5 additions & 0 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ keywords = { workspace = true }
categories = { workspace = true }

[dependencies]
bincode = "1.3.3"
hex = "0.4.3"
lazy_static = "1.5.0"
num-bigint = { version = "0.4.6", default-features = false }
p3-field = { workspace = true }
p3-baby-bear = { workspace = true }
p3-poseidon2 = { workspace = true }
p3-symmetric = { workspace = true }
serde = { version = "1.0.207", features = ["derive"] }
sha2 = "0.10.8"
itertools = "0.13.0"
107 changes: 107 additions & 0 deletions crates/primitives/src/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use crate::types::Buffer;
use num_bigint::BigUint;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use sha2::{Digest, Sha256};

/// Public values for the prover.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SP1PublicValues {
buffer: Buffer,
}

impl SP1PublicValues {
/// Create a new `SP1PublicValues`.
pub const fn new() -> Self {
Self { buffer: Buffer::new() }
}

pub fn raw(&self) -> String {
format!("0x{}", hex::encode(self.buffer.data.clone()))
}

/// Create a `SP1PublicValues` from a slice of bytes.
pub fn from(data: &[u8]) -> Self {
Self { buffer: Buffer::from(data) }
}

pub fn as_slice(&self) -> &[u8] {
self.buffer.data.as_slice()
}

pub fn to_vec(&self) -> Vec<u8> {
self.buffer.data.clone()
}

/// Read a value from the buffer.
pub fn read<T: Serialize + DeserializeOwned>(&mut self) -> T {
self.buffer.read()
}

/// Read a slice of bytes from the buffer.
pub fn read_slice(&mut self, slice: &mut [u8]) {
self.buffer.read_slice(slice);
}

/// Write a value to the buffer.
pub fn write<T: Serialize>(&mut self, data: &T) {
self.buffer.write(data);
}

/// Write a slice of bytes to the buffer.
pub fn write_slice(&mut self, slice: &[u8]) {
self.buffer.write_slice(slice);
}

/// Hash the public values.
pub fn hash(&self) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(self.buffer.data.as_slice());
hasher.finalize().to_vec()
}

/// Hash the public values, mask the top 3 bits and return a BigUint. Matches the implementation
/// of `hashPublicValues` in the Solidity verifier.
///
/// ```solidity
/// sha256(publicValues) & bytes32(uint256((1 << 253) - 1));
/// ```
pub fn hash_bn254(&self) -> BigUint {
// Hash the public values.
let mut hasher = Sha256::new();
hasher.update(self.buffer.data.as_slice());
let hash_result = hasher.finalize();
let mut hash = hash_result.to_vec();

// Mask the top 3 bits.
hash[0] &= 0b00011111;

// Return the masked hash as a BigUint.
BigUint::from_bytes_be(&hash)
}
}

impl AsRef<[u8]> for SP1PublicValues {
fn as_ref(&self) -> &[u8] {
&self.buffer.data
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_hash_public_values() {
let test_hex = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
let test_bytes = hex::decode(test_hex).unwrap();

let mut public_values = SP1PublicValues::new();
public_values.write_slice(&test_bytes);
let hash = public_values.hash_bn254();

let expected_hash = "1ce987d0a7fcc2636fe87e69295ba12b1cc46c256b369ae7401c51b805ee91bd";
let expected_hash_biguint = BigUint::from_bytes_be(&hex::decode(expected_hash).unwrap());

assert_eq!(hash, expected_hash_biguint);
}
}
1 change: 1 addition & 0 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use p3_field::AbstractField;
use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixGeneral};

pub mod consts;
pub mod io;
pub mod types;

lazy_static! {
Expand Down
Loading

0 comments on commit 3bf0cd2

Please sign in to comment.