diff --git a/stwo_cairo_verifier/src/circle.cairo b/stwo_cairo_verifier/src/circle.cairo index e386054d..7acd9720 100644 --- a/stwo_cairo_verifier/src/circle.cairo +++ b/stwo_cairo_verifier/src/circle.cairo @@ -1,9 +1,10 @@ use core::num::traits::one::One; use core::num::traits::zero::Zero; use core::num::traits::{WrappingAdd, WrappingSub, WrappingMul}; +use stwo_cairo_verifier::channel::{Channel, ChannelImpl}; use stwo_cairo_verifier::fields::cm31::CM31; use stwo_cairo_verifier::fields::m31::{M31, M31Impl}; -use stwo_cairo_verifier::fields::qm31::{QM31Impl, QM31, QM31Trait}; +use stwo_cairo_verifier::fields::qm31::{QM31Impl, QM31One, QM31, QM31Trait}; use super::utils::pow; /// A generator for the circle group over [`M31`]. @@ -99,10 +100,38 @@ impl CirclePointAdd, +Sub, +Mul, +Drop, +Copy> of Add, +Drop, +Copy> of Neg> { + fn neg(a: CirclePoint) -> CirclePoint { + CirclePoint { x: a.x, y: -a.y } + } +} + pub impl CirclePointM31Impl of CirclePointTrait {} +#[generate_trait] +pub impl CirclePointQM31AddCirclePointM31Impl of CirclePointQM31AddCirclePointM31Trait { + fn add_circle_point_m31(self: CirclePoint, rhs: CirclePoint) -> CirclePoint { + CirclePoint { + x: self.x.mul_m31(rhs.x) - self.y.mul_m31(rhs.y), + y: self.x.mul_m31(rhs.y) + self.y.mul_m31(rhs.x) + } + } +} + pub impl CirclePointQM31Impl of CirclePointTrait {} +#[generate_trait] +pub impl ChannelGetRandomCirclePointImpl of ChannelGetRandomCirclePointTrait { + fn get_random_point(ref self: Channel) -> CirclePoint { + let t = self.draw_felt(); + let t_squared = t * t; + let t_squared_plus_1_inv = (t_squared + QM31One::one()).inverse(); + let x = (QM31One::one() - t_squared) * t_squared_plus_1_inv; + let y = (t + t) * t_squared_plus_1_inv; + CirclePoint { x, y } + } +} + impl CirclePointQM31PartialOrd of PartialOrd> { fn lt(lhs: CirclePoint, rhs: CirclePoint) -> bool { lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y)