Skip to content
Draft
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
442 changes: 442 additions & 0 deletions src/algebra/buffer.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/algebra/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod buffer;
pub mod embedding;
pub mod fields;
pub mod linear_form;
Expand Down
15 changes: 9 additions & 6 deletions src/bin/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use clap::Parser;
use serde::Serialize;
use whir::{
algebra::{
buffer::CpuBuffer,
embedding::{Basefield, Embedding, Identity},
fields::{Field128, Field192, Field256, Field64, Field64_2, Field64_3},
linear_form::{Evaluate, LinearForm, MultilinearExtension},
Expand Down Expand Up @@ -161,12 +162,13 @@ where

HASH_COUNTER.reset();

let witness = params.commit(&mut prover_state, &[&vector]);
let vector_buffer = CpuBuffer::from_slice(&vector);
let witness = params.commit(&mut prover_state, &[&vector_buffer]);

let _ = params.prove(
&mut prover_state,
vec![Cow::Borrowed(vector.as_slice())],
vec![Cow::Owned(witness)],
&[&vector_buffer],
vec![&witness],
vec![],
Cow::Owned(vec![]),
);
Expand Down Expand Up @@ -238,7 +240,8 @@ where
HASH_COUNTER.reset();
let whir_prover_time = Instant::now();

let witness = params.commit(&mut prover_state, &[&vector]);
let vector_buffer = CpuBuffer::from_slice(&vector);
let witness = params.commit(&mut prover_state, &[&vector_buffer]);

let prove_linear_forms: Vec<Box<dyn LinearForm<M::Target>>> = points
.iter()
Expand All @@ -249,8 +252,8 @@ where

let _ = params.prove(
&mut prover_state,
vec![Cow::Borrowed(vector.as_slice())],
vec![Cow::Owned(witness)],
&[&vector_buffer],
vec![&witness],
prove_linear_forms,
Cow::Borrowed(evaluations.as_slice()),
);
Expand Down
15 changes: 9 additions & 6 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ark_std::rand::distributions::{Distribution, Standard};
use clap::Parser;
use whir::{
algebra::{
buffer::CpuBuffer,
embedding::{Basefield, Embedding, Identity},
fields::{Field128, Field192, Field256, Field64, Field64_2, Field64_3},
linear_form::{Covector, Evaluate, LinearForm, MultilinearExtension},
Expand Down Expand Up @@ -148,9 +149,10 @@ where
}

let vector = (0..num_coeffs).map(M::Source::from).collect::<Vec<_>>();
let vector_buffer = CpuBuffer::from_slice(&vector);

let whir_commit_time = Instant::now();
let witness = params.commit(&mut prover_state, &[&vector]);
let witness = params.commit(&mut prover_state, &[&vector_buffer]);
let whir_commit_time = whir_commit_time.elapsed();

// Allocate constraints
Expand Down Expand Up @@ -183,8 +185,8 @@ where
let whir_prove_time = Instant::now();
let _ = params.prove(
&mut prover_state,
vec![Cow::Borrowed(vector.as_slice())],
vec![Cow::Owned(witness)],
&[&vector_buffer],
vec![&witness],
prove_linear_forms,
Cow::Borrowed(evaluations.as_slice()),
);
Expand Down Expand Up @@ -314,14 +316,15 @@ where
}

let whir_commit_time = Instant::now();
let witness = params.commit(&mut prover_state, &[vector.as_slice()]);
let vector_buffer = CpuBuffer::from_slice(&vector);
let witness = params.commit(&mut prover_state, &[&vector_buffer]);
let whir_commit_time = whir_commit_time.elapsed();

let whir_prove_time = Instant::now();
let _ = params.prove(
&mut prover_state,
vec![Cow::Borrowed(&vector)],
witness,
&[&vector_buffer],
vec![&witness],
prove_linear_forms,
Cow::Borrowed(&evaluations),
);
Expand Down
53 changes: 37 additions & 16 deletions src/protocols/basecase.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// IGNORE CHANGES TO THIS FILE - NOT FULLY PORTED TO PROPERLY USE BUFFER ABSTRACTION.

//! Base Case Linear Opening Protocol
//!
//! It support honest verifier zero-knowledge (HVZK), but is not succinct.
Expand All @@ -11,8 +13,8 @@ use spongefish::{Decoding, VerificationResult};

use crate::{
algebra::{
dot, embedding::Identity, multilinear_extend, random_vector, scalar_mul_add_new,
univariate_evaluate,
buffer::CpuBuffer, dot, embedding::Identity, multilinear_extend, random_vector,
scalar_mul_add_new, univariate_evaluate,
},
hash::Hash,
protocols::{irs_commit, sumcheck},
Expand Down Expand Up @@ -49,9 +51,9 @@ impl<F: Field> Config<F> {
pub fn prove<H, R>(
&self,
prover_state: &mut ProverState<H, R>,
mut vector: Vec<F>,
vector: Vec<F>,
witness: &irs_commit::Witness<F>,
mut covector: Vec<F>,
covector: Vec<F>,
mut sum: F,
) -> Opening<F>
where
Expand Down Expand Up @@ -79,24 +81,33 @@ impl<F: Field> Config<F> {
// Even more trivial non-zk protocol: send f and r directly.
if !self.masked {
prover_state.prover_messages(&vector);
prover_state.prover_messages(&witness.masks);
prover_state.prover_messages(witness.masks.as_slice());
let _ = self.commit.open(prover_state, &[witness]);
let mut vector_buffer = CpuBuffer::from_vec(vector);
let mut covector_buffer = CpuBuffer::from_vec(covector);
let point = self
.sumcheck
.prove(prover_state, &mut vector, &mut covector, &mut sum, &[])
.prove(
prover_state,
&mut vector_buffer,
&mut covector_buffer,
&mut sum,
&[],
)
.round_challenges;
assert!(!vector[0].is_zero(), "Proof failed");
assert!(!vector_buffer.as_slice()[0].is_zero(), "Proof failed");
return Opening {
evaluation_points: point,
linear_form_evaluation: covector[0],
linear_form_evaluation: covector_buffer.as_slice()[0],
};
}

// Create masking vector.
let mask = random_vector(prover_state.rng(), vector.len());
let mask_buffer = CpuBuffer::from_slice(&mask);

// Commit to the masking vector.
let mask_witness = self.commit.commit(prover_state, &[&mask]);
let mask_witness = self.commit.commit(prover_state, &[&mask_buffer]);

// Compute and send linear form of mask (μ' in paper).
let mask_sum = dot(&mask, &covector);
Expand All @@ -105,24 +116,30 @@ impl<F: Field> Config<F> {
// RLC the mask with the vector
let mask_rlc = prover_state.verifier_message::<F>();
assert!(!mask_rlc.is_zero(), "Proof failed");
let mut masked_vector = scalar_mul_add_new(&mask, mask_rlc, &vector);
let masked_vector = scalar_mul_add_new(&mask, mask_rlc, &vector);
prover_state.prover_messages(&masked_vector);

// Send combined IRS randomness. (r^* in paper)
let masked_masks = scalar_mul_add_new(&mask_witness.masks, mask_rlc, &witness.masks);
let masked_masks = scalar_mul_add_new(
mask_witness.masks.as_slice(),
mask_rlc,
witness.masks.as_slice(),
);
prover_state.prover_messages(&masked_masks);

// Open the commitment and mask simultaneously.
let _ = self.commit.open(prover_state, &[&mask_witness, witness]);

// Run sumcheck to reduce linear form claim
let mut masked_sum = mask_sum + mask_rlc * sum;
let mut masked_vector_buffer = CpuBuffer::from_vec(masked_vector);
let mut covector_buffer = CpuBuffer::from_vec(covector);
let point = self
.sumcheck
.prove(
prover_state,
&mut masked_vector,
&mut covector,
&mut masked_vector_buffer,
&mut covector_buffer,
&mut masked_sum,
&[],
)
Expand All @@ -132,11 +149,14 @@ impl<F: Field> Config<F> {
// Basically the sumcheck equation has degenerated to 0 * l(r) = 0, which provides
// no constraints on l(r) that the verifier can return.
// This event is cryptographically unlikely as `F` is challenge sized.
assert!(!masked_vector[0].is_zero(), "Proof failed");
assert!(
!masked_vector_buffer.as_slice()[0].is_zero(),
"Proof failed"
);

Opening {
evaluation_points: point,
linear_form_evaluation: covector[0],
linear_form_evaluation: covector_buffer.as_slice()[0],
}
}

Expand Down Expand Up @@ -284,7 +304,8 @@ mod tests {

// Prover
let mut prover_state = ProverState::new_std(&ds);
let witness = config.commit.commit(&mut prover_state, &[&vector]);
let vector_buffer = CpuBuffer::from_slice(&vector);
let witness = config.commit.commit(&mut prover_state, &[&vector_buffer]);
let prover_result = config.prove(
&mut prover_state,
vector.clone(),
Expand Down
17 changes: 12 additions & 5 deletions src/protocols/code_switch.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// IGNORE CHANGES TO THIS FILE - NOT FULLY PORTED TO PROPERLY USE BUFFER ABSTRACTION.

//! Code-switching IOR: R_{C, C_zk, sl} → R_{C', C_zk, sl'}
//!
//! Reduces a proximity claim about oracle f (source code C) to a proximity
Expand All @@ -13,6 +15,7 @@ use tracing::instrument;

use crate::{
algebra::{
buffer::CpuBuffer,
dot,
embedding::{Embedding, Identity},
eq_weights, geometric_accumulate, lift, mixed_dot, scalar_mul, univariate_evaluate,
Expand Down Expand Up @@ -195,7 +198,8 @@ impl<M: Embedding> Config<M> {
};

// Step 1: g := Enc_{C'}(f, r') — Construction 9.7 Step 1, p.55
let target_witness = self.target.commit(prover_state, &[&message]);
let message_buffer = CpuBuffer::from_slice(&message);
let target_witness = self.target.commit(prover_state, &[&message_buffer]);

// Step 2-3: OOD challenge + answers — Construction 9.7 Steps 2-3, p.55
// y := ze_ood(ρ) · [f; r; s] = f(α) + α^ℓ · (r,s)(α)
Expand Down Expand Up @@ -484,7 +488,7 @@ mod tests {
}
// Lift ι parallel masks (total length source.mask_length × ι) and fold
// chunks of length source.mask_length down to a single chunk.
let raw = lift(config.source.embedding(), &source_witness.masks);
let raw = lift(config.source.embedding(), source_witness.masks.as_slice());
let mut mask = fold_chunks(&raw, config.source.mask_length, folding_randomness);
// Append fresh padding s of length message_mask_length - source.mask_length.
mask.extend(random_vector::<F>(
Expand Down Expand Up @@ -521,7 +525,8 @@ mod tests {
.session(&format!("Test at {}:{}", file!(), line!()))
.instance(&instance);
let mut prover_state = ProverState::new_std(&ds);
let source_witness = config.source.commit(&mut prover_state, &[&f_full]);
let f_full_buffer = CpuBuffer::from_slice(&f_full);
let source_witness = config.source.commit(&mut prover_state, &[&f_full_buffer]);

// Sample γ for sumcheck folding (length log2(ι)).
let folding_randomness = sample_folding_randomness(config, &mut rng);
Expand Down Expand Up @@ -574,7 +579,8 @@ mod tests {
.session(&format!("Test at {}:{}", file!(), line!()))
.instance(&instance);
let mut prover_state = ProverState::new_std(&ds);
let source_witness = config.source.commit(&mut prover_state, &[&f_full]);
let f_full_buffer = CpuBuffer::from_slice(&f_full);
let source_witness = config.source.commit(&mut prover_state, &[&f_full_buffer]);

let folding_randomness = sample_folding_randomness(config, &mut rng);
let folded_message =
Expand Down Expand Up @@ -642,7 +648,8 @@ mod tests {

// Commit honest f_full, fold to get the honest post-fold message.
let mut prover_state = ProverState::new_std(&ds);
let source_witness = config.source.commit(&mut prover_state, &[&f_full]);
let f_full_buffer = CpuBuffer::from_slice(&f_full);
let source_witness = config.source.commit(&mut prover_state, &[&f_full_buffer]);
let folding_randomness = sample_folding_randomness(config, &mut rng);
let folded_message =
fold_chunks(&f_full, config.source.message_length(), &folding_randomness);
Expand Down
Loading