Skip to content

Commit

Permalink
Refactor FRI implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewmilson committed Oct 13, 2024
1 parent accb393 commit 0bc3f0a
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 395 deletions.
17 changes: 7 additions & 10 deletions stwo_cairo_verifier/src/channel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,12 @@ pub impl ChannelImpl of ChannelTrait {
fn draw_random_bytes(ref self: Channel) -> Array<u8> {
let mut cur: u256 = self.draw_felt252().into();
let mut bytes = array![];
let mut i: usize = 0;
while i < 31 {
let (q, r) = DivRem::div_rem(cur, 256);
bytes.append(r.try_into().unwrap());
cur = q;
i += 1;
};
for _ in 0_usize
..31 {
let (q, r) = DivRem::div_rem(cur, 256);
bytes.append(r.try_into().unwrap());
cur = q;
};
bytes
}
}
Expand Down Expand Up @@ -224,9 +223,7 @@ mod tests {
let initial_digest = 0;
let mut channel = ChannelTrait::new(initial_digest);

let mut n: usize = 10;
while n > 0 {
n -= 1;
for _ in 0_usize..10 {
channel.draw_felt();
};

Expand Down
70 changes: 57 additions & 13 deletions stwo_cairo_verifier/src/circle.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub impl CosetImpl of CosetTrait {
}

/// Creates a coset of the form `G_4n + <G_n>`.
///
///
/// For example, for `n=8`, we get the point indices `[1,5,9,13,17,21,25,29]`.
/// Its conjugate will be `[3,7,11,15,19,23,27,31]`.
fn half_odds(log_size: u32) -> Coset {
Expand Down Expand Up @@ -240,20 +240,22 @@ mod tests {
use stwo_cairo_verifier::fields::m31::m31;
use stwo_cairo_verifier::fields::qm31::{QM31One, qm31};
use stwo_cairo_verifier::utils::pow;
use super::{M31_CIRCLE_GEN, CirclePointQM31Impl, QM31_CIRCLE_GEN, M31_CIRCLE_ORDER, CirclePoint, CirclePointM31Impl, CirclePointIndexImpl, Coset, CosetImpl, QM31_CIRCLE_ORDER};
use super::{
M31_CIRCLE_GEN, CirclePointQM31Impl, QM31_CIRCLE_GEN, M31_CIRCLE_ORDER, CirclePoint,
CirclePointM31Impl, CirclePointIndexImpl, Coset, CosetImpl, QM31_CIRCLE_ORDER
};

#[test]
fn test_add_1() {
let i = CirclePoint { x: m31(0), y: m31(1) };
let result = i + i;

assert_eq!(result, CirclePoint { x: -m31(1), y: m31(0) });
let g4 = CirclePoint { x: m31(0), y: m31(1) };
assert_eq!(g4 + g4, CirclePoint { x: -m31(1), y: m31(0) });
}

#[test]
fn test_add_2() {
let point_1 = CirclePoint { x: m31(750649172), y: m31(1991648574) };
let point_2 = CirclePoint { x: m31(1737427771), y: m31(309481134) };

let result = point_1 + point_2;

assert_eq!(result, CirclePoint { x: m31(1476625263), y: m31(1040927458) });
Expand All @@ -270,6 +272,7 @@ mod tests {
fn test_zero_2() {
let point_1 = CirclePoint { x: m31(750649172), y: m31(1991648574) };
let point_2 = CirclePointM31Impl::zero();

let result = point_1 + point_2;

assert_eq!(result, point_1.clone());
Expand All @@ -278,6 +281,7 @@ mod tests {
#[test]
fn test_mul_1() {
let point_1 = CirclePoint { x: m31(750649172), y: m31(1991648574) };

let result = point_1.mul(5);

assert_eq!(result, point_1 + point_1 + point_1 + point_1 + point_1);
Expand All @@ -286,6 +290,7 @@ mod tests {
#[test]
fn test_mul_2() {
let point_1 = CirclePoint { x: m31(750649172), y: m31(1991648574) };

let result = point_1.mul(8);

assert_eq!(
Expand All @@ -296,6 +301,7 @@ mod tests {
#[test]
fn test_mul_3() {
let point_1 = CirclePoint { x: m31(750649172), y: m31(1991648574) };

let result = point_1.mul(418776494);

assert_eq!(result, CirclePoint { x: m31(1987283985), y: m31(1500510905) });
Expand All @@ -304,6 +310,7 @@ mod tests {
#[test]
fn test_generator_order() {
let half_order = M31_CIRCLE_ORDER / 2;

let mut result = M31_CIRCLE_GEN.mul(half_order.into());

// Assert `M31_CIRCLE_GEN^{2^30}` equals `-1`.
Expand All @@ -319,7 +326,12 @@ mod tests {

#[test]
fn test_coset_index_at() {
let coset = Coset { initial_index: CirclePointIndexImpl::new(16777216), log_size: 5, step_size: CirclePointIndexImpl::new(67108864) };
let coset = Coset {
initial_index: CirclePointIndexImpl::new(16777216),
log_size: 5,
step_size: CirclePointIndexImpl::new(67108864)
};

let result = coset.index_at(8);

assert_eq!(result, CirclePointIndexImpl::new(553648128));
Expand All @@ -329,36 +341,68 @@ mod tests {
fn test_coset_constructor() {
let result = CosetImpl::new(CirclePointIndexImpl::new(16777216), 5);

assert_eq!(result, Coset { initial_index: CirclePointIndexImpl::new(16777216), log_size: 5, step_size: CirclePointIndexImpl::new(67108864) });
assert_eq!(
result,
Coset {
initial_index: CirclePointIndexImpl::new(16777216),
log_size: 5,
step_size: CirclePointIndexImpl::new(67108864)
}
);
}

#[test]
fn test_coset_double() {
let coset = Coset { initial_index: CirclePointIndexImpl::new(16777216), step_size: CirclePointIndexImpl::new(67108864), log_size: 5 };
let coset = Coset {
initial_index: CirclePointIndexImpl::new(16777216),
step_size: CirclePointIndexImpl::new(67108864),
log_size: 5
};

let result = coset.double();

assert_eq!(result, Coset { initial_index: CirclePointIndexImpl::new(33554432), step_size: CirclePointIndexImpl::new(134217728), log_size: 4 });
assert_eq!(
result,
Coset {
initial_index: CirclePointIndexImpl::new(33554432),
step_size: CirclePointIndexImpl::new(134217728),
log_size: 4
}
);
}

#[test]
fn test_coset_at() {
let coset = Coset { initial_index: CirclePointIndexImpl::new(16777216), step_size: CirclePointIndexImpl::new(67108864), log_size: 5 };
let coset = Coset {
initial_index: CirclePointIndexImpl::new(16777216),
step_size: CirclePointIndexImpl::new(67108864),
log_size: 5
};

let result = coset.at(17);

assert_eq!(result, CirclePoint { x: m31(7144319), y: m31(1742797653) });
}

#[test]
fn test_coset_size() {
let coset = Coset { initial_index: CirclePointIndexImpl::new(16777216), step_size: CirclePointIndexImpl::new(67108864), log_size: 5 };
let coset = Coset {
initial_index: CirclePointIndexImpl::new(16777216),
step_size: CirclePointIndexImpl::new(67108864),
log_size: 5
};

let result = coset.size();

assert_eq!(result, 32);
}

#[test]
fn test_qm31_circle_gen() {
assert_eq!(QM31_CIRCLE_GEN.mul(QM31_CIRCLE_ORDER / 2), CirclePoint { x: -qm31(1, 0, 0, 0), y: qm31(0, 0, 0, 0) });
assert_eq!(
QM31_CIRCLE_GEN.mul(QM31_CIRCLE_ORDER / 2),
CirclePoint { x: -qm31(1, 0, 0, 0), y: qm31(0, 0, 0, 0) }
);
}
}

22 changes: 2 additions & 20 deletions stwo_cairo_verifier/src/fields/qm31.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,11 @@ pub impl QM31Impl of QM31Trait {
QM31 { a: CM31 { a: a, b: b }, b: CM31 { a: c, b: d } }
}

fn from_u32(arr: [u32; 4]) -> QM31 {
let [a, b, c, d] = arr;
let a_mod_p = M31Impl::reduce_u32(a);
let b_mod_p = M31Impl::reduce_u32(b);
let c_mod_p = M31Impl::reduce_u32(c);
let d_mod_p = M31Impl::reduce_u32(d);

QM31 { a: CM31 { a: a_mod_p, b: b_mod_p }, b: CM31 { a: c_mod_p, b: d_mod_p } }
}
#[inline]
fn to_array(self: QM31) -> [M31; 4] {
[self.a.a, self.a.b, self.b.a, self.b.b]
}

fn inverse(self: QM31) -> QM31 {
assert_ne!(self, Zero::zero());
let b2 = self.b * self.b;
Expand All @@ -43,6 +35,7 @@ pub impl QM31Impl of QM31Trait {
let denom_inverse = denom.inverse();
QM31 { a: self.a * denom_inverse, b: -self.b * denom_inverse }
}

fn mul_m31(self: QM31, multiplier: M31) -> QM31 {
QM31 {
a: CM31 { a: self.a.a * multiplier, b: self.a.b * multiplier },
Expand Down Expand Up @@ -139,15 +132,4 @@ mod tests {
assert_eq!(qm1 * m.inverse().into(), qm1 * qm.inverse());
assert_eq!(qm1.mul_m31(m), qm1 * m.into());
}

#[test]
fn test_qm31_from_u32() {
let arr = [2147483648, 2, 3, 4];
let felt = QM31Impl::from_u32(arr);
let expected_felt = QM31 {
a: CM31 { a: m31(1), b: m31(2) }, b: CM31 { a: m31(3), b: m31(4) }
};

assert_eq!(felt, expected_felt)
}
}
Loading

0 comments on commit 0bc3f0a

Please sign in to comment.