From 993b16b92ece61d99a3573652d680a034ef2123b Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Mon, 14 Nov 2022 17:48:46 +0100 Subject: [PATCH] only ever interpolate and evaluate over `Domain`s of `BFieldElements` Only accept generators of type `BFieldElement`, not any Finite Field. Remove duplicate FRI domain in struct `Stark`. --- triton-vm/src/cross_table_arguments.rs | 12 ++++++------ triton-vm/src/domain.rs | 12 +++++++++--- triton-vm/src/fri.rs | 2 +- triton-vm/src/stark.rs | 19 ++++++++----------- triton-vm/src/table/base_table.rs | 15 ++++++--------- triton-vm/src/table/extension_table.rs | 21 +++++++++++---------- triton-vm/src/table/hash_table.rs | 4 ++-- triton-vm/src/table/instruction_table.rs | 4 ++-- triton-vm/src/table/jump_stack_table.rs | 4 ++-- triton-vm/src/table/op_stack_table.rs | 4 ++-- triton-vm/src/table/processor_table.rs | 4 ++-- triton-vm/src/table/program_table.rs | 4 ++-- triton-vm/src/table/ram_table.rs | 4 ++-- triton-vm/src/table/table_collection.rs | 10 +++++----- 14 files changed, 60 insertions(+), 59 deletions(-) diff --git a/triton-vm/src/cross_table_arguments.rs b/triton-vm/src/cross_table_arguments.rs index 98772699f..1a6268b06 100644 --- a/triton-vm/src/cross_table_arguments.rs +++ b/triton-vm/src/cross_table_arguments.rs @@ -44,8 +44,8 @@ pub trait CrossTableArg { fn terminal_quotient( &self, ext_codeword_tables: &ExtTableCollection, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, ) -> Vec { let from_codeword = self.combined_from_codeword(ext_codeword_tables); let to_codeword = self.combined_to_codeword(ext_codeword_tables); @@ -55,7 +55,7 @@ pub trait CrossTableArg { .into_iter() .map(|x| x - omicron.inverse()) .collect(); - let zerofier_inverse = XFieldElement::batch_inversion(zerofier); + let zerofier_inverse = BFieldElement::batch_inversion(zerofier); zerofier_inverse .into_iter() @@ -453,8 +453,8 @@ impl GrandCrossTableArg { pub fn terminal_quotient_codeword( &self, ext_codeword_tables: &ExtTableCollection, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, ) -> Vec { let mut non_linear_sum_codeword = vec![XFieldElement::zero(); fri_domain.length]; @@ -502,7 +502,7 @@ impl GrandCrossTableArg { .into_iter() .map(|x| x - omicron.inverse()) .collect(); - let zerofier_inverse = XFieldElement::batch_inversion(zerofier); + let zerofier_inverse = BFieldElement::batch_inversion(zerofier); zerofier_inverse .into_iter() diff --git a/triton-vm/src/domain.rs b/triton-vm/src/domain.rs index 1e5c9cae6..b9c064c1b 100644 --- a/triton-vm/src/domain.rs +++ b/triton-vm/src/domain.rs @@ -29,12 +29,18 @@ where } } - pub fn evaluate(&self, polynomial: &Polynomial) -> Vec { + pub fn evaluate(&self, polynomial: &Polynomial) -> Vec + where + GF: FiniteField + From + MulAssign, + { polynomial.fast_coset_evaluate(&self.offset, self.generator, self.length) } - pub fn interpolate(&self, values: &[FF]) -> Polynomial { - Polynomial::::fast_coset_interpolate(&self.offset, self.generator, values) + pub fn interpolate(&self, values: &[GF]) -> Polynomial + where + GF: FiniteField + From + MulAssign, + { + Polynomial::::fast_coset_interpolate(&self.offset, self.generator, values) } pub fn domain_value(&self, index: u32) -> FF { diff --git a/triton-vm/src/fri.rs b/triton-vm/src/fri.rs index 051fc7ac2..514b9b1c7 100644 --- a/triton-vm/src/fri.rs +++ b/triton-vm/src/fri.rs @@ -50,7 +50,7 @@ pub struct Fri { // nearest power of 2. pub expansion_factor: usize, pub colinearity_checks_count: usize, - pub domain: Domain, + pub domain: Domain, _hasher: PhantomData, } diff --git a/triton-vm/src/stark.rs b/triton-vm/src/stark.rs index b8f84cb64..0eb1a1be6 100644 --- a/triton-vm/src/stark.rs +++ b/triton-vm/src/stark.rs @@ -24,7 +24,6 @@ use triton_profiler::{prof_itr0, prof_start, prof_stop}; use crate::cross_table_arguments::{ CrossTableArg, EvalArg, GrandCrossTableArg, NUM_CROSS_TABLE_ARGS, NUM_PUBLIC_EVAL_ARGS, }; -use crate::domain::Domain; use crate::fri::{Fri, FriValidationError}; use crate::proof::{Claim, Proof}; use crate::proof_item::ProofItem; @@ -108,7 +107,6 @@ pub struct Stark { parameters: StarkParameters, claim: Claim, max_degree: Degree, - fri_domain: Domain, fri: Fri, } @@ -122,7 +120,6 @@ impl Stark { let omega = BFieldElement::primitive_root_of_unity(fri_domain_length.try_into().unwrap()).unwrap(); let coset_offset = BFieldElement::generator(); - let fri_domain: Domain = Domain::new(coset_offset, omega, fri_domain_length); let fri = Fri::new( coset_offset, omega, @@ -134,7 +131,6 @@ impl Stark { parameters, claim, max_degree, - fri_domain, fri, } } @@ -153,7 +149,7 @@ impl Stark { prof_start!(maybe_profiler, "LDE 1"); let base_fri_domain_tables = base_trace_tables - .to_fri_domain_tables(&self.fri_domain, self.parameters.num_trace_randomizers); + .to_fri_domain_tables(&self.fri.domain, self.parameters.num_trace_randomizers); let base_fri_domain_codewords = base_fri_domain_tables.get_all_base_columns(); let randomizer_and_base_fri_domain_codewords = vec![b_rand_codewords, base_fri_domain_codewords.clone()].concat(); @@ -557,7 +553,7 @@ impl Stark { } fn shift_codeword( - fri_x_values: &Vec, + fri_x_values: &Vec, codeword: &Vec, shift: u32, ) -> Vec { @@ -627,7 +623,7 @@ impl Stark { fn get_randomizer_codewords(&self) -> (Vec, Vec>) { let randomizer_coefficients = random_elements(self.max_degree as usize + 1); - let randomizer_polynomial = Polynomial::new(randomizer_coefficients); + let randomizer_polynomial = Polynomial::::new(randomizer_coefficients); let x_randomizer_codeword = self.fri.domain.evaluate(&randomizer_polynomial); let mut b_randomizer_codewords = vec![vec![], vec![], vec![]]; @@ -870,7 +866,7 @@ impl Stark { let base_offset = self.parameters.num_randomizer_polynomials; let ext_offset = base_offset + num_base_polynomials; let final_offset = ext_offset + num_extension_polynomials; - let omicron: XFieldElement = derive_omicron(padded_height as u64); + let omicron = derive_omicron(padded_height as u64); let omicron_inverse = omicron.inverse(); for (combination_check_index, revealed_combination_leaf) in combination_check_indices .into_iter() @@ -1029,7 +1025,8 @@ impl Stark { .zip_eq(terminal_quotient_degree_bounds.iter()) { let shift = self.max_degree - degree_bound; - let quotient = evaluated_termc / (current_fri_domain_value - omicron_inverse); + let quotient = + evaluated_termc / (current_fri_domain_value - omicron_inverse).lift(); let quotient_shifted = quotient * current_fri_domain_value.mod_pow_u32(shift as u32); summands.push(quotient); @@ -1049,8 +1046,8 @@ impl Stark { let shift = self.max_degree - grand_cross_table_arg_degree_bound; let grand_cross_table_arg_evaluated = grand_cross_table_arg.evaluate_non_linear_sum_of_differences(&cross_slice_by_table); - let grand_cross_table_arg_quotient = - grand_cross_table_arg_evaluated / (current_fri_domain_value - omicron_inverse); + let grand_cross_table_arg_quotient = grand_cross_table_arg_evaluated + / (current_fri_domain_value - omicron_inverse).lift(); let grand_cross_table_arg_quotient_shifted = grand_cross_table_arg_quotient * current_fri_domain_value.mod_pow_u32(shift as u32); summands.push(grand_cross_table_arg_quotient); diff --git a/triton-vm/src/table/base_table.rs b/triton-vm/src/table/base_table.rs index d596a2606..63d981e34 100644 --- a/triton-vm/src/table/base_table.rs +++ b/triton-vm/src/table/base_table.rs @@ -1,6 +1,5 @@ use super::super::domain::Domain; -use itertools::Itertools; -use num_traits::Zero; +use num_traits::{One, Zero}; use rand_distr::{Distribution, Standard}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use std::ops::{Mul, MulAssign, Range}; @@ -270,8 +269,8 @@ where fn low_degree_extension( &self, - fri_domain: &Domain, - omicron: FF, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, columns: Range, ) -> Vec> { @@ -287,7 +286,7 @@ where /// if it is called with a subset, it *will* fail. fn interpolate_columns( &self, - omicron: FF, + omicron: BFieldElement, num_trace_randomizers: usize, columns: Range, ) -> Vec> { @@ -303,10 +302,8 @@ where self.name() ); - // FIXME: Use Domain::new(…).domain_values() (needs some refactoring) - let trace_domain = (0..padded_height) - .map(|i| omicron.mod_pow_u32(i as u32)) - .collect_vec(); + let trace_domain = + Domain::new(BFieldElement::one(), omicron, padded_height).domain_values(); let num_trace_randomizers = num_trace_randomizers; let randomizer_domain = disjoint_domain(num_trace_randomizers, &trace_domain); diff --git a/triton-vm/src/table/extension_table.rs b/triton-vm/src/table/extension_table.rs index 4160b74fc..10e1a37c5 100644 --- a/triton-vm/src/table/extension_table.rs +++ b/triton-vm/src/table/extension_table.rs @@ -6,6 +6,7 @@ use rayon::iter::{ IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, ParallelIterator, }; use triton_profiler::triton_profiler::TritonProfiler; +use twenty_first::shared_math::b_field_element::BFieldElement; use twenty_first::shared_math::mpolynomial::{Degree, MPolynomial}; use twenty_first::shared_math::traits::{FiniteField, Inverse, ModPowU32}; use twenty_first::shared_math::x_field_element::XFieldElement; @@ -192,7 +193,7 @@ pub trait Quotientable: ExtensionTable + Evaluable { fn initial_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, transposed_codewords: &[Vec], challenges: &AllChallenges, ) -> Vec> { @@ -222,7 +223,7 @@ pub trait Quotientable: ExtensionTable + Evaluable { fn consistency_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, transposed_codewords: &[Vec], challenges: &AllChallenges, padded_height: usize, @@ -253,10 +254,10 @@ pub trait Quotientable: ExtensionTable + Evaluable { fn transition_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, transposed_codewords: &[Vec], challenges: &AllChallenges, - omicron: XFieldElement, + omicron: BFieldElement, padded_height: usize, ) -> Vec> { debug_assert_eq!(fri_domain.length, transposed_codewords.len()); @@ -300,10 +301,10 @@ pub trait Quotientable: ExtensionTable + Evaluable { fn terminal_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, transposed_codewords: &[Vec], challenges: &AllChallenges, - omicron: XFieldElement, + omicron: BFieldElement, ) -> Vec> { debug_assert_eq!(fri_domain.length, transposed_codewords.len()); @@ -314,7 +315,7 @@ pub trait Quotientable: ExtensionTable + Evaluable { .into_iter() .map(|x| x - omicron.inverse()) .collect_vec(); - let zerofier_inverse = XFieldElement::batch_inversion(zerofier_codeword); + let zerofier_inverse = BFieldElement::batch_inversion(zerofier_codeword); let transposed_quotient_codewords: Vec<_> = zerofier_inverse .par_iter() @@ -333,10 +334,10 @@ pub trait Quotientable: ExtensionTable + Evaluable { fn all_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, transposed_codewords: Vec>, challenges: &AllChallenges, - omicron: XFieldElement, + omicron: BFieldElement, padded_height: usize, maybe_profiler: &mut Option, ) -> Vec> { @@ -404,7 +405,7 @@ pub trait Quotientable: ExtensionTable + Evaluable { /// probably the result of un-clean division. fn debug_fri_domain_bound_check( &self, - fri_domain: &Domain, + fri_domain: &Domain, quotient_codewords: &[Vec], quotient_type: &str, ) { diff --git a/triton-vm/src/table/hash_table.rs b/triton-vm/src/table/hash_table.rs index c3ac384c4..a74e1db1e 100644 --- a/triton-vm/src/table/hash_table.rs +++ b/triton-vm/src/table/hash_table.rs @@ -786,8 +786,8 @@ impl HashTable { impl ExtHashTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/instruction_table.rs b/triton-vm/src/table/instruction_table.rs index 15729dccd..4637e6d8e 100644 --- a/triton-vm/src/table/instruction_table.rs +++ b/triton-vm/src/table/instruction_table.rs @@ -471,8 +471,8 @@ impl InstructionTable { impl ExtInstructionTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/jump_stack_table.rs b/triton-vm/src/table/jump_stack_table.rs index 633d449fe..ecf92c18a 100644 --- a/triton-vm/src/table/jump_stack_table.rs +++ b/triton-vm/src/table/jump_stack_table.rs @@ -450,8 +450,8 @@ impl JumpStackTable { impl ExtJumpStackTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/op_stack_table.rs b/triton-vm/src/table/op_stack_table.rs index 36ad4718f..43f8d8d27 100644 --- a/triton-vm/src/table/op_stack_table.rs +++ b/triton-vm/src/table/op_stack_table.rs @@ -396,8 +396,8 @@ impl OpStackTable { impl ExtOpStackTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/processor_table.rs b/triton-vm/src/table/processor_table.rs index b94c85c21..d4e5255a4 100644 --- a/triton-vm/src/table/processor_table.rs +++ b/triton-vm/src/table/processor_table.rs @@ -352,8 +352,8 @@ impl ProcessorTable { impl ExtProcessorTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/program_table.rs b/triton-vm/src/table/program_table.rs index 4e9ed618b..a6219f45b 100644 --- a/triton-vm/src/table/program_table.rs +++ b/triton-vm/src/table/program_table.rs @@ -293,8 +293,8 @@ impl ProgramTable { impl ExtProgramTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/ram_table.rs b/triton-vm/src/table/ram_table.rs index 96ee47963..dc90526b9 100644 --- a/triton-vm/src/table/ram_table.rs +++ b/triton-vm/src/table/ram_table.rs @@ -211,8 +211,8 @@ impl RamTable { impl ExtRamTable { pub fn to_fri_domain_table( &self, - fri_domain: &Domain, - omicron: XFieldElement, + fri_domain: &Domain, + omicron: BFieldElement, num_trace_randomizers: usize, ) -> Self { let ext_columns = self.base_width()..self.full_width(); diff --git a/triton-vm/src/table/table_collection.rs b/triton-vm/src/table/table_collection.rs index 71917565f..6921bec1e 100644 --- a/triton-vm/src/table/table_collection.rs +++ b/triton-vm/src/table/table_collection.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use twenty_first::shared_math::b_field_element::BFieldElement; use twenty_first::shared_math::mpolynomial::Degree; use twenty_first::shared_math::other::{is_power_of_two, roundup_npo2}; -use twenty_first::shared_math::traits::FiniteField; +use twenty_first::shared_math::traits::PrimitiveRootOfUnity; use twenty_first::shared_math::x_field_element::XFieldElement; use triton_profiler::triton_profiler::TritonProfiler; @@ -79,13 +79,13 @@ pub fn interpolant_degree(padded_height: usize, num_trace_randomizers: usize) -> (padded_height + num_trace_randomizers - 1) as Degree } -pub fn derive_omicron(padded_height: u64) -> FF { +pub fn derive_omicron(padded_height: u64) -> BFieldElement { debug_assert!( 0 == padded_height || is_power_of_two(padded_height), "The padded height was: {}", padded_height ); - FF::primitive_root_of_unity(padded_height).unwrap() + BFieldElement::primitive_root_of_unity(padded_height).unwrap() } impl BaseTableCollection { @@ -350,7 +350,7 @@ impl ExtTableCollection { /// Heads up: only extension columns are being low degree extended. todo: better naming. pub fn to_fri_domain_tables( &self, - fri_domain: &Domain, + fri_domain: &Domain, num_trace_randomizers: usize, ) -> Self { let padded_height = self.padded_height; @@ -429,7 +429,7 @@ impl ExtTableCollection { pub fn get_all_quotients( &self, - fri_domain: &Domain, + fri_domain: &Domain, challenges: &AllChallenges, maybe_profiler: &mut Option, ) -> Vec> {