Skip to content

Commit

Permalink
Remove pow function
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewmilson committed Nov 19, 2024
1 parent 80f4447 commit bdd8199
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 84 deletions.
6 changes: 3 additions & 3 deletions stwo_cairo_verifier/src/circle.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use stwo_cairo_verifier::fields::Invertible;
use stwo_cairo_verifier::fields::cm31::CM31;
use stwo_cairo_verifier::fields::m31::{M31, M31Impl};
use stwo_cairo_verifier::fields::qm31::{QM31, QM31Impl, QM31One, QM31Trait};
use super::utils::pow;
use super::utils::POW_2;

/// A generator for the circle group over [`M31`].
pub const M31_CIRCLE_GEN: CirclePoint<M31> = CirclePoint {
Expand Down Expand Up @@ -168,7 +168,7 @@ pub impl CosetImpl of CosetTrait {

/// Returns the size of the coset.
fn size(self: @Coset) -> usize {
pow(2, *self.log_size)
*POW_2.span()[*self.log_size]
}

/// Creates a coset of the form `G_2n + <G_n>`.
Expand Down Expand Up @@ -216,7 +216,7 @@ pub impl CirclePointIndexImpl of CirclePointIndexTrait {

fn subgroup_gen(log_size: u32) -> CirclePointIndex {
assert!(log_size <= M31_CIRCLE_LOG_ORDER);
CirclePointIndex { index: pow(2, M31_CIRCLE_LOG_ORDER - log_size) }
CirclePointIndex { index: *POW_2.span()[M31_CIRCLE_LOG_ORDER - log_size] }
}

// TODO(andrew): When associated types are supported, support the Mul<Self, u32>.
Expand Down
4 changes: 2 additions & 2 deletions stwo_cairo_verifier/src/fri.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use stwo_cairo_verifier::poly::line::{
use stwo_cairo_verifier::poly::line::{LinePoly, LinePolyImpl};
use stwo_cairo_verifier::queries::SparseSubCircleDomain;
use stwo_cairo_verifier::queries::{Queries, QueriesImpl};
use stwo_cairo_verifier::utils::{ArrayImpl, OptionImpl, SpanExTrait, bit_reverse_index, find, pow};
use stwo_cairo_verifier::utils::{ArrayImpl, OptionImpl, SpanExTrait, bit_reverse_index, find, POW_2};
use stwo_cairo_verifier::vcs::hasher::PoseidonMerkleHasher;
use stwo_cairo_verifier::vcs::verifier::{MerkleDecommitment, MerkleVerifier, MerkleVerifierTrait};

Expand Down Expand Up @@ -270,7 +270,7 @@ pub impl FriVerifierImpl of FriVerifierTrait {
return Result::Err(FriVerificationError::InvalidNumFriLayers);
}

if proof.last_layer_poly.len() != pow(2, config.log_last_layer_degree_bound) {
if proof.last_layer_poly.len() != *POW_2.span()[config.log_last_layer_degree_bound] {
return Result::Err(FriVerificationError::LastLayerDegreeInvalid);
}

Expand Down
5 changes: 2 additions & 3 deletions stwo_cairo_verifier/src/pcs/quotients.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ mod tests {
};
use stwo_cairo_verifier::queries::SubCircleDomainImpl;
use stwo_cairo_verifier::queries::{SparseSubCircleDomain, SubCircleDomain};
use stwo_cairo_verifier::utils::{DictImpl, pow};
use stwo_cairo_verifier::utils::{DictImpl, POW_2};
use super::{
ColumnSampleBatch, ColumnSampleBatchImpl, ComplexConjugateLineCoeffsImpl, PointSample,
QuotientConstantsImpl, accumulate_row_quotients, fri_answers, fri_answers_for_log_size,
Expand Down Expand Up @@ -777,7 +777,6 @@ mod tests {
let n_columns = 1000;
let log_fold_step = CIRCLE_TO_LINE_FOLD_STEP;
let random_coeff = qm31(9, 8, 7, 6);
assert!(n_queries < pow(2, log_size), "Query indices need to be unique");
assert!(n_columns >= 3, "First three columns are manually created");
let mut query_subdomains = array![];
for coset_index in 0..n_queries {
Expand All @@ -797,7 +796,7 @@ mod tests {
let col2_samples = array![sample0, sample2];
let mut samples_per_column = array![@col0_samples, @col1_samples, @col2_samples];
let mut col_query_values = array![];
for i in 0..n_queries * pow(2, log_fold_step) {
for i in 0..n_queries * *POW_2.span()[log_fold_step] {
col_query_values.append(m31(i));
};
let col0_query_values = col_query_values.clone();
Expand Down
4 changes: 2 additions & 2 deletions stwo_cairo_verifier/src/poly/circle.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use stwo_cairo_verifier::fields::BatchInvertible;
use stwo_cairo_verifier::fields::m31::M31;
use stwo_cairo_verifier::fields::qm31::QM31;
use stwo_cairo_verifier::poly::utils::ibutterfly;
use stwo_cairo_verifier::utils::pow;
use stwo_cairo_verifier::utils::POW_2;

/// A valid domain for circle polynomial interpolation and evaluation.
///
Expand All @@ -28,7 +28,7 @@ pub impl CircleDomainImpl of CircleDomainTrait {
/// Returns the size of the domain.
#[inline]
fn size(self: @CircleDomain) -> usize {
pow(2, self.log_size())
*POW_2.span()[self.log_size()]
}

/// Returns the log size of the domain.
Expand Down
6 changes: 3 additions & 3 deletions stwo_cairo_verifier/src/poly/line.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use stwo_cairo_verifier::fields::m31::{M31, m31};
use stwo_cairo_verifier::fields::qm31::{QM31, QM31Impl, QM31Zero};
use stwo_cairo_verifier::fields::{BaseField, SecureField};
use stwo_cairo_verifier::poly::utils::{butterfly, fold, ibutterfly};
use stwo_cairo_verifier::utils::pow;
use stwo_cairo_verifier::utils::POW_2;

/// A univariate polynomial defined on a [LineDomain].
#[derive(Debug, Drop, Clone)]
Expand Down Expand Up @@ -55,7 +55,7 @@ pub impl LinePolyImpl of LinePolyTrait {
let log_domain_size = domain.log_size();
let log_degree_bound = *self.log_size;
let n_skipped_layers = log_domain_size - log_degree_bound;
let duplicity = pow(2, n_skipped_layers);
let duplicity = *POW_2.span()[n_skipped_layers];
let coeffs = repeat_value(self.coeffs.span(), duplicity);

LineEvaluationImpl::new(domain, line_fft(coeffs, domain, n_skipped_layers))
Expand Down Expand Up @@ -164,7 +164,7 @@ pub impl LinePolySerde of Serde<LinePoly> {
};

// Check the sizes match.
if res.coeffs.len() != pow(2, res.log_size) {
if res.coeffs.len() != *POW_2.span()[res.log_size] {
return Option::None;
}

Expand Down
14 changes: 7 additions & 7 deletions stwo_cairo_verifier/src/queries.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use stwo_cairo_verifier::channel::{Channel, ChannelTrait};
use stwo_cairo_verifier::circle::CosetImpl;
use stwo_cairo_verifier::poly::circle::{CircleDomain, CircleDomainImpl};
use super::utils::{ArrayImpl, bit_reverse_index, find, pow};
use super::utils::{ArrayImpl, bit_reverse_index, find, POW_2};


/// An ordered set of query indices over a bit reversed [CircleDomain].
Expand All @@ -16,7 +16,7 @@ pub impl QueriesImpl of QueriesImplTrait {
/// Randomizes a set of query indices uniformly over the range [0, 2^`log_query_size`).
fn generate(ref channel: Channel, log_domain_size: u32, n_queries: usize) -> Queries {
let mut unsorted_positions = array![];
let max_query = pow(2, log_domain_size) - 1;
let max_query = *POW_2.span()[log_domain_size] - 1;
let mut finished = false;
loop {
let random_bytes = channel.draw_random_bytes();
Expand Down Expand Up @@ -51,7 +51,7 @@ pub impl QueriesImpl of QueriesImplTrait {
fn fold(self: @Queries, n_folds: u32) -> Queries {
assert!(n_folds <= *self.log_domain_size);
assert!(self.positions.len() > 0);
let folding_factor = pow(2, n_folds);
let folding_factor = *POW_2.span()[n_folds];
let mut new_last_position = *self.positions[0] / folding_factor;
let mut new_positions = array![new_last_position];
let mut i = 1;
Expand All @@ -68,7 +68,7 @@ pub impl QueriesImpl of QueriesImplTrait {

fn opening_positions(self: @Queries, fri_step_size: u32) -> SparseSubCircleDomain {
assert!(fri_step_size > 0);
let fold_factor = pow(2, fri_step_size);
let fold_factor = *POW_2.span()[fri_step_size];
let mut domains = array![];
let snap_positions = self.positions;
let mut already_added = array![];
Expand Down Expand Up @@ -103,7 +103,7 @@ pub struct SubCircleDomain {
pub impl SubCircleDomainImpl of SubCircleDomainTrait {
/// Calculates the decommitment positions needed for each query given the fri step size.
fn to_decommitment_positions(self: @SubCircleDomain) -> Array<usize> {
let sub_circle_size = pow(2, *self.log_size);
let sub_circle_size = *POW_2.span()[*self.log_size];
let start = *self.coset_index * sub_circle_size;
let end = start + sub_circle_size;
let mut res = array![];
Expand All @@ -115,15 +115,15 @@ pub impl SubCircleDomainImpl of SubCircleDomainTrait {

/// Returns the represented [CircleDomain].
fn to_circle_domain(self: @SubCircleDomain, query_domain: CircleDomain) -> CircleDomain {
let index = *self.coset_index * pow(2, *self.log_size);
let index = *self.coset_index * *POW_2.span()[*self.log_size];
let query = bit_reverse_index(index, query_domain.log_size());
let initial_index = query_domain.index_at(query);
let half_coset = CosetImpl::new(initial_index, *self.log_size - 1);
CircleDomainImpl::new(half_coset)
}

fn size(self: @SubCircleDomain) -> usize {
pow(2, *self.log_size).into()
*POW_2.span()[*self.log_size].into()
}
}

Expand Down
101 changes: 37 additions & 64 deletions stwo_cairo_verifier/src/utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,42 @@ use core::num::traits::BitSize;
use core::traits::DivRem;
use core::traits::PanicDestruct;
use stwo_cairo_verifier::BaseField;
use stwo_cairo_verifier::fields::qm31::{QM31, qm31};

/// Look up table where index `i` stores value `2^i`.
pub const POW_2: [u32; 32] = [
0b1,
0b10,
0b100,
0b1000,
0b10000,
0b100000,
0b1000000,
0b10000000,
0b100000000,
0b1000000000,
0b10000000000,
0b100000000000,
0b1000000000000,
0b10000000000000,
0b100000000000000,
0b1000000000000000,
0b10000000000000000,
0b100000000000000000,
0b1000000000000000000,
0b10000000000000000000,
0b100000000000000000000,
0b1000000000000000000000,
0b10000000000000000000000,
0b100000000000000000000000,
0b1000000000000000000000000,
0b10000000000000000000000000,
0b100000000000000000000000000,
0b1000000000000000000000000000,
0b10000000000000000000000000000,
0b100000000000000000000000000000,
0b1000000000000000000000000000000,
0b10000000000000000000000000000000,
];

#[generate_trait]
pub impl DictImpl<T, +Felt252DictValue<T>, +PanicDestruct<T>> of DictTrait<T> {
Expand Down Expand Up @@ -153,22 +188,6 @@ pub fn pack4(cur: felt252, values: [BaseField; 4]) -> felt252 {
+ x3.into()
}

pub fn pow(base: u32, mut exponent: u32) -> u32 {
let mut result = 1;
let mut base_power = base;
loop {
if exponent & 1 == 1 {
result *= base_power;
}
exponent = exponent / 2;
if exponent == 0 {
break;
}
base_power = base_power * base_power;
};
result
}

pub fn bit_reverse_index(mut index: usize, mut bits: u32) -> usize {
assert!(bits <= BitSize::<usize>::bits());

Expand Down Expand Up @@ -197,34 +216,9 @@ pub fn find(n: u32, a: Span<u32>) -> bool {
res
}

pub fn pow_qm31(base: QM31, mut exponent: u32) -> QM31 {
let mut result = qm31(1, 0, 0, 0);
let mut base_power = base;
loop {
if exponent & 1 == 1 {
result = result * base_power;
}
exponent = exponent / 2;
if exponent == 0 {
break;
}
base_power = base_power * base_power;
};
result
}

#[cfg(test)]
mod tests {
use super::{ArrayImpl, bit_reverse_index, pow, pow_qm31, qm31};

#[test]
fn test_pow() {
assert_eq!(25, pow(5, 2));
assert_eq!(16, pow(2, 4));
assert_eq!(1024, pow(2, 10));
assert_eq!(4096, pow(2, 12));
assert_eq!(1048576, pow(2, 20));
}
use super::{ArrayImpl, bit_reverse_index, qm31};

#[test]
fn test_bit_reverse() {
Expand All @@ -251,27 +245,6 @@ mod tests {
assert_eq!(16448250, bit_reverse_index(800042880, 31));
}

#[test]
fn test_pow_qm31_1() {
let result = pow_qm31(qm31(1, 2, 3, 4), 0);
let expected_result = qm31(1, 0, 0, 0);
assert_eq!(expected_result, result)
}

#[test]
fn test_pow_qm31_2() {
let result = pow_qm31(qm31(1, 2, 3, 4), 1);
let expected_result = qm31(1, 2, 3, 4);
assert_eq!(expected_result, result)
}

#[test]
fn test_pow_qm31_3() {
let result = pow_qm31(qm31(1, 2, 3, 4), 37);
let expected_result = qm31(1394542587, 260510989, 997191897, 2127074080);
assert_eq!(expected_result, result)
}

#[test]
fn test_sort_ascending() {
assert_eq!(array![6_usize, 5, 1, 4, 2, 3].sort_ascending(), array![1, 2, 3, 4, 5, 6]);
Expand Down

0 comments on commit bdd8199

Please sign in to comment.