Skip to content

Commit

Permalink
perf!: Halve number of combination codeword checks
Browse files Browse the repository at this point in the history
In line with #285 we only need to verify the combination codeword in
`num_collinearity_checks` many points and not in 2 times this number.
This is because inside of FRI, we explicitly commit to the FRI codeword
in `2 * num_collinearity_checks` many points.

This also reduces the number of trace randomizers needed.

Co-authored-by: Ferdinand Sauer <[email protected]>
  • Loading branch information
jan-ferdinand committed May 29, 2024
1 parent 3bf3325 commit deecc22
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 44 deletions.
34 changes: 8 additions & 26 deletions triton-vm/src/fri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,6 @@ impl<'stream, H: AlgebraicHasher> FriProver<'stream, H> {
.sample_indices(indices_upper_bound, self.num_collinearity_checks);
}

fn all_top_level_collinearity_check_indices(&self) -> Vec<usize> {
let a_indices = self.first_round_collinearity_check_indices.clone();
let b_indices = self.collinearity_check_b_indices_for_round(0);
a_indices.into_iter().chain(b_indices).collect()
}

fn collinearity_check_b_indices_for_round(&self, round_number: usize) -> Vec<usize> {
let domain_length = self.rounds[round_number].domain.length;
self.first_round_collinearity_check_indices
Expand Down Expand Up @@ -499,21 +493,10 @@ impl<'stream, H: AlgebraicHasher> FriVerifier<'stream, H> {
}

fn first_round_partially_revealed_codeword(&self) -> Vec<(usize, XFieldElement)> {
let partial_codeword_a = self.rounds[0].partial_codeword_a.clone();
let partial_codeword_b = self.rounds[0].partial_codeword_b.clone();

let indices_a = self.collinearity_check_a_indices_for_round(0).into_iter();

let first_round_codeword_b_has_been_revealed = self.num_rounds > 0;
let indices_b = match first_round_codeword_b_has_been_revealed {
true => self.collinearity_check_b_indices_for_round(0).into_iter(),
false => vec![].into_iter(),
};

let codeword_a = indices_a.zip_eq(partial_codeword_a);
let codeword_b = indices_b.zip_eq(partial_codeword_b);

codeword_a.chain(codeword_b).collect()
self.collinearity_check_a_indices_for_round(0)
.into_iter()
.zip_eq(self.rounds[0].partial_codeword_a.clone())
.collect()
}
}

Expand Down Expand Up @@ -545,7 +528,7 @@ impl<H: AlgebraicHasher> Fri<H> {
Ok(fri)
}

/// Create a FRI proof and return indices of revealed elements of round 0.
/// Create a FRI proof and return a-indices of revealed elements of round 0.
pub fn prove(
&self,
codeword: &[XFieldElement],
Expand All @@ -562,8 +545,7 @@ impl<H: AlgebraicHasher> Fri<H> {
// it is important to modify the sponge state the same way.
prover.proof_stream.sample_scalars(1);

let indices = prover.all_top_level_collinearity_check_indices();
Ok(indices)
Ok(prover.first_round_collinearity_check_indices)
}

fn prover<'stream>(&'stream self, proof_stream: &'stream mut ProofStream) -> FriProver<H> {
Expand Down Expand Up @@ -1074,8 +1056,8 @@ mod tests {
#[proptest]
fn codeword_corresponding_to_high_degree_polynomial_results_in_verification_failure(
#[strategy(arbitrary_fri())] fri: Fri<Tip5>,
#[strategy(Just(#fri.first_round_max_degree() as i64 + 1))] _max_degree: i64,
#[strategy(#_max_degree..2 * #_max_degree)] _degree: i64,
#[strategy(Just(#fri.first_round_max_degree() as i64 + 1))] _min_fail_deg: i64,
#[strategy(#_min_fail_deg..2 * #_min_fail_deg)] _degree: i64,
#[strategy(arbitrary_polynomial_of_degree(#_degree))] poly: Polynomial<XFieldElement>,
) {
let codeword = fri.domain.evaluate(&poly);
Expand Down
26 changes: 8 additions & 18 deletions triton-vm/src/stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ pub struct Stark {

/// The number of collinearity checks to perform in FRI.
pub num_collinearity_checks: usize,

/// The number of combination codeword checks. These checks link the (DEEP) ALI part and the
/// FRI part of the zk-STARK. The number of combination codeword checks directly depends on the
/// number of collinearity checks and the FRI folding factor.
pub num_combination_codeword_checks: usize,
}

impl Stark {
Expand All @@ -92,20 +87,15 @@ impl Stark {
let fri_expansion_factor = 1 << log2_of_fri_expansion_factor;
let num_collinearity_checks = security_level / log2_of_fri_expansion_factor;

// For now, the FRI folding factor is hardcoded in our zk-STARK.
let fri_folding_factor = 2;
let num_combination_codeword_checks = num_collinearity_checks * fri_folding_factor;

let num_out_of_domain_rows = 2;
let num_trace_randomizers = num_combination_codeword_checks
+ num_out_of_domain_rows * x_field_element::EXTENSION_DEGREE;
let num_trace_randomizers =
num_collinearity_checks + num_out_of_domain_rows * x_field_element::EXTENSION_DEGREE;

Stark {
security_level,
fri_expansion_factor,
num_trace_randomizers,
num_collinearity_checks,
num_combination_codeword_checks,
}
}

Expand Down Expand Up @@ -362,7 +352,7 @@ impl Stark {
let revealed_current_row_indices =
fri.prove(&fri_combination_codeword, &mut proof_stream)?;
assert_eq!(
self.num_combination_codeword_checks,
self.num_collinearity_checks,
revealed_current_row_indices.len()
);
profiler!(stop "FRI");
Expand Down Expand Up @@ -960,19 +950,19 @@ impl Stark {
profiler!(stop "check leafs");

profiler!(start "linear combination");
if self.num_combination_codeword_checks != revealed_current_row_indices.len() {
if self.num_collinearity_checks != revealed_current_row_indices.len() {
return Err(VerificationError::IncorrectNumberOfRowIndices);
};
if self.num_combination_codeword_checks != revealed_fri_values.len() {
if self.num_collinearity_checks != revealed_fri_values.len() {
return Err(VerificationError::IncorrectNumberOfFRIValues);
};
if self.num_combination_codeword_checks != revealed_quotient_segments_elements.len() {
if self.num_collinearity_checks != revealed_quotient_segments_elements.len() {
return Err(VerificationError::IncorrectNumberOfQuotientSegmentElements);
};
if self.num_combination_codeword_checks != base_table_rows.len() {
if self.num_collinearity_checks != base_table_rows.len() {
return Err(VerificationError::IncorrectNumberOfBaseTableRows);
};
if self.num_combination_codeword_checks != ext_table_rows.len() {
if self.num_collinearity_checks != ext_table_rows.len() {
return Err(VerificationError::IncorrectNumberOfExtTableRows);
};

Expand Down

0 comments on commit deecc22

Please sign in to comment.