Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions bin/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,17 +784,16 @@ fn cmd_verify_continuation(
return ExitCode::FAILURE;
}
};
let bundle: prover::continuation::ContinuationProof = match rkyv::from_bytes::<
prover::continuation::ContinuationProof,
rkyv::rancor::Error,
>(&proof_bytes)
{
Ok(p) => p,
Err(e) => {
eprintln!("Failed to deserialize proof: {}", e);
return ExitCode::FAILURE;
}
};
let bundle: prover::continuation::ContinuationProof =
match rkyv::from_bytes::<prover::continuation::ContinuationProof, rkyv::rancor::Error>(
&proof_bytes,
) {
Ok(p) => p,
Err(e) => {
eprintln!("Failed to deserialize proof: {}", e);
return ExitCode::FAILURE;
}
};

let opts = match GoldilocksCubicProofOptions::with_blowup(blowup) {
Ok(opts) => opts,
Expand Down
12 changes: 6 additions & 6 deletions crypto/crypto/src/fiat_shamir/default_transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use math::{
element::FieldElement,
traits::{HasDefaultTranscript, IsField, IsSubFieldOf},
},
traits::ByteConversion,
traits::AsBytes,
};
use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
use sha3::{Digest, Keccak256};
Expand All @@ -28,7 +28,7 @@ impl<F: HasDefaultTranscript> Clone for DefaultTranscript<F> {
impl<F> DefaultTranscript<F>
where
F: HasDefaultTranscript,
FieldElement<F>: ByteConversion,
FieldElement<F>: AsBytes,
{
pub fn new(data: &[u8]) -> Self {
let mut res = Self {
Expand All @@ -50,7 +50,7 @@ where
impl<F> Default for DefaultTranscript<F>
where
F: HasDefaultTranscript,
FieldElement<F>: ByteConversion,
FieldElement<F>: AsBytes,
{
fn default() -> Self {
Self::new(&[])
Expand All @@ -60,14 +60,14 @@ where
impl<F> IsTranscript<F> for DefaultTranscript<F>
where
F: HasDefaultTranscript,
FieldElement<F>: ByteConversion,
FieldElement<F>: AsBytes,
{
fn append_bytes(&mut self, new_bytes: &[u8]) {
self.hasher.update(new_bytes);
}

fn append_field_element(&mut self, element: &FieldElement<F>) {
self.append_bytes(&element.to_bytes_be());
element.stream_bytes(&mut |b| self.hasher.update(b));
}

fn state(&self) -> [u8; 32] {
Expand All @@ -94,7 +94,7 @@ where
impl<F, S> IsStarkTranscript<F, S> for DefaultTranscript<F>
where
F: HasDefaultTranscript,
FieldElement<F>: ByteConversion,
FieldElement<F>: AsBytes,
S: IsField + IsSubFieldOf<F>,
{
// nothing to implement: sample_z_ood uses the default body
Expand Down
2 changes: 1 addition & 1 deletion crypto/crypto/src/merkle_tree/backends/field_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where

fn hash_data(input: &FieldElement<F>) -> [u8; NUM_BYTES] {
let mut hasher = D::new();
hasher.update(input.as_bytes());
input.stream_bytes(&mut |b| hasher.update(b));
hasher.finalize().into()
}

Expand Down
31 changes: 22 additions & 9 deletions crypto/crypto/src/merkle_tree/backends/field_element_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ where

fn hash_data(input: &[FieldElement<F>; 2]) -> [u8; NUM_BYTES] {
let mut hasher = D::new();
hasher.update(input[0].as_bytes());
hasher.update(input[1].as_bytes());
input[0].stream_bytes(&mut |b| hasher.update(b));
input[1].stream_bytes(&mut |b| hasher.update(b));
let mut result_hash = [0_u8; NUM_BYTES];
result_hash.copy_from_slice(&hasher.finalize());
result_hash
Expand Down Expand Up @@ -86,6 +86,25 @@ where
result.copy_from_slice(&hasher.finalize());
result
}

/// Hashes the concatenation of `parts` (each a slice of field elements) as a
/// single leaf, without allocating a buffer to concatenate them first. Byte-
/// identical to hashing `parts.concat()` via [`Self::hash_data`].
pub fn hash_data_parts(parts: &[&[FieldElement<F>]]) -> [u8; NUM_BYTES]
where
F: IsField,
FieldElement<F>: AsBytes,
{
let mut hasher = D::new();
for part in parts {
for element in part.iter() {
element.stream_bytes(&mut |b| hasher.update(b));
}
}
let mut result = [0u8; NUM_BYTES];
result.copy_from_slice(&hasher.finalize());
result
}
}

impl<F, D: Digest, const NUM_BYTES: usize> IsMerkleTreeBackend
Expand All @@ -100,13 +119,7 @@ where
type Data = Vec<FieldElement<F>>;

fn hash_data(input: &Vec<FieldElement<F>>) -> [u8; NUM_BYTES] {
let mut hasher = D::new();
for element in input.iter() {
hasher.update(element.as_bytes());
}
let mut result_hash = [0_u8; NUM_BYTES];
result_hash.copy_from_slice(&hasher.finalize());
result_hash
Self::hash_data_parts(&[input.as_slice()])
}

fn hash_new_parent(left: &[u8; NUM_BYTES], right: &[u8; NUM_BYTES]) -> [u8; NUM_BYTES] {
Expand Down
18 changes: 16 additions & 2 deletions crypto/crypto/src/merkle_tree/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,28 @@ pub struct Proof<T: PartialEq + Eq> {
pub fn verify_merkle_path<B>(
merkle_path: &[B::Node],
root_hash: &B::Node,
mut index: usize,
index: usize,
value: &B::Data,
) -> bool
where
B: IsMerkleTreeBackend,
{
let mut hashed_value = B::hash_data(value);
verify_merkle_path_from_hash::<B>(merkle_path, root_hash, index, B::hash_data(value))
}

/// Same check as [`verify_merkle_path`], starting from an already-computed leaf
/// hash. Lets callers that can hash their leaf data more efficiently than the
/// backend's `hash_data` (e.g. hashing several slices without concatenating
/// them first) still walk the shared path-verification logic.
pub fn verify_merkle_path_from_hash<B>(
merkle_path: &[B::Node],
root_hash: &B::Node,
mut index: usize,
mut hashed_value: B::Node,
) -> bool
where
B: IsMerkleTreeBackend,
{
for sibling_node in merkle_path.iter() {
if index.is_multiple_of(2) {
hashed_value = B::hash_new_parent(&hashed_value, sibling_node);
Expand Down
7 changes: 7 additions & 0 deletions crypto/math/src/field/extensions_goldilocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,13 @@ impl AsBytes for FieldElement<Degree3GoldilocksExtensionField> {
fn as_bytes(&self) -> alloc::vec::Vec<u8> {
self.to_bytes_be()
}

#[inline(always)]
fn stream_bytes(&self, sink: &mut dyn FnMut(&[u8])) {
let mut buf = [0u8; 24];
crate::traits::ByteConversion::write_bytes_be(self, &mut buf);
sink(&buf);
}
}

impl HasDefaultTranscript for Degree3GoldilocksExtensionField {
Expand Down
5 changes: 5 additions & 0 deletions crypto/math/src/field/goldilocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,11 @@ impl AsBytes for FieldElement<GoldilocksField> {
fn as_bytes(&self) -> alloc::vec::Vec<u8> {
ByteConversion::to_bytes_be(self)
}

#[inline(always)]
fn stream_bytes(&self, sink: &mut dyn FnMut(&[u8])) {
sink(&self.canonical_u64().to_be_bytes());
}
}

// Implement IsPrimeField for the native Goldilocks
Expand Down
6 changes: 6 additions & 0 deletions crypto/math/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ pub trait ByteConversion {
pub trait AsBytes {
/// Default serialize without args
fn as_bytes(&self) -> alloc::vec::Vec<u8>;

/// Streams the byte representation to `sink` without heap-allocating a `Vec`.
/// Default falls back to `as_bytes`; override for zero-allocation hashing/transcript hot paths.
fn stream_bytes(&self, sink: &mut dyn FnMut(&[u8])) {
sink(&self.as_bytes());
}
}

#[cfg(feature = "alloc")]
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/fibonacci_2_cols_shifted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ use math::{
traits::AsBytes,
};
use std::marker::PhantomData;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct PublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/fibonacci_multi_column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ use math::field::{

/// Public inputs for the multi-column Fibonacci AIR.
/// Contains the initial values (first two elements) for each column.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct FibonacciMultiColumnPublicInputs<F: IsFFTField> {
/// Initial values for each column: (a0, a1) pairs
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/fibonacci_rap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ where
phantom: PhantomData<F>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct FibonacciRAPPublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/quadratic_air.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ where
phantom: PhantomData<F>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct QuadraticPublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/read_only_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,15 @@ where
phantom: PhantomData<F>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct ReadOnlyPublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/read_only_memory_logup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ where
phantom: PhantomData<(F, E)>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct LogReadOnlyPublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/simple_addition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,15 @@ where
phantom: PhantomData<F>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct SimpleAdditionPublicInputs<F>
where
Expand Down
10 changes: 9 additions & 1 deletion crypto/stark/src/examples/simple_fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@ where
phantom: PhantomData<F>,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
#[derive(
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "FieldElement<F>: serde::Serialize + serde::de::DeserializeOwned")]
pub struct FibonacciPublicInputs<F>
where
Expand Down
8 changes: 7 additions & 1 deletion crypto/stark/src/fri/fri_decommit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ use math::field::traits::IsField;
use crate::config::Commitment;

#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize
Debug,
Clone,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "")]
pub struct FriDecommitment<F: IsField> {
Expand Down
8 changes: 7 additions & 1 deletion crypto/stark/src/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,7 +1499,13 @@ impl BusInteraction {
/// For the circular constraint, `table_contribution / N` is the per-row offset
/// that makes the accumulated column wrap to zero at row N-1.
#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize
Debug,
Clone,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
#[serde(bound = "")]
pub struct BusPublicInputs<E>
Expand Down
8 changes: 7 additions & 1 deletion crypto/stark/src/proof/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ impl fmt::Display for ProofOptionsError {
/// - `fri_final_poly_log_degree`: log2 degree bound at which FRI terminates folding
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[derive(
Clone, Debug, serde::Serialize, serde::Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct ProofOptions {
pub blowup_factor: u8,
Expand Down
Loading
Loading