Skip to content

Commit

Permalink
curves: Second curve group and some test (#49)
Browse files Browse the repository at this point in the history
* chore: tests + scalar multiplication

* fmt

* wip: compiles, but generator point is broken

* wip

* fix mul, generator and add hardcoded tests (#51)

* fix mul, generator and add hardcoded tests

* fix generator test

* wip

* fix: test fails when rng has no inverse

---------

Co-authored-by: Sambhav <[email protected]>
  • Loading branch information
0xJepsen and lonerapier authored May 9, 2024
1 parent def9371 commit 2637594
Show file tree
Hide file tree
Showing 9 changed files with 495 additions and 72 deletions.
7 changes: 3 additions & 4 deletions math/field.sage
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ F_2 = GF(101 ^ 2, name="t", modulus=P)
print("extension field:", F_2, "of order:", F_2.order())

# Primitive element
f_2_primitive_element = F_2.primitive_element()
print("Primitive element of F_2:", f_2_primitive_element, f_2_primitive_element.order())
f_2_primitive_element = F_2([2, 1])
print("Primitive element of F_2:", f_2_primitive_element, f_2_primitive_element.multiplicative_order())

# 100th root of unity
F_2_order = F_2.order()
Expand All @@ -65,5 +65,4 @@ quotient = (F_2_order-1)//root_of_unity_order
f_2_omega_n = f_2_primitive_element ^ quotient
print("The", root_of_unity_order, "th root of unity of extension field is: ", f_2_omega_n)

######################################################################

######################################################################
117 changes: 117 additions & 0 deletions src/curves/g1_curve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use std::ops::Add;

use super::CurveParams;
use crate::field::{gf_101::GF101, FiniteField};

/// The Elliptic curve $y^2=x^3+3$, i.e.
/// - a = 0
/// - b = 3
/// - generator todo
/// - order todo
/// - field element type todo, but mock with u64 - bad thor, u64 does not implement p3_field
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
pub struct C101;

impl CurveParams for C101 {
type FieldElement = GF101;

const EQUATION_A: Self::FieldElement = GF101::new(0);
const EQUATION_B: Self::FieldElement = GF101::new(3);
const GENERATOR: (Self::FieldElement, Self::FieldElement) = (GF101::new(1), Self::TWO);
const ORDER: u32 = GF101::ORDER;
const THREE: Self::FieldElement = GF101::new(3);
const TWO: Self::FieldElement = GF101::new(2);
}

mod test {
use super::*;
use crate::curves::AffinePoint;
type F = GF101;

#[test]
fn point_doubling() {
let g = AffinePoint::<C101>::generator();

let two_g = g.point_doubling();
let expected_2g = AffinePoint::<C101>::new(F::new(68), F::new(74));
let expected_negative_2g = AffinePoint::<C101>::new(F::new(68), F::new(27));
assert_eq!(two_g, expected_2g);
assert_eq!(-two_g, expected_negative_2g);

let four_g = two_g.point_doubling();
let expected_4g = AffinePoint::<C101>::new(F::new(65), F::new(98));
let expected_negative_4g = AffinePoint::<C101>::new(F::new(65), F::new(3));
assert_eq!(four_g, expected_4g);
assert_eq!(-four_g, expected_negative_4g);

let eight_g = four_g.point_doubling();
let expected_8g = AffinePoint::<C101>::new(F::new(18), F::new(49));
let expected_negative_8g = AffinePoint::<C101>::new(F::new(18), F::new(52));
assert_eq!(eight_g, expected_8g);
assert_eq!(-eight_g, expected_negative_8g);

let sixteen_g = eight_g.point_doubling();
let expected_16g = AffinePoint::<C101>::new(F::new(1), F::new(99));
let expected_negative_16g = AffinePoint::<C101>::new(F::new(1), F::new(2));
assert_eq!(sixteen_g, expected_16g);
assert_eq!(-sixteen_g, expected_negative_16g);
assert_eq!(g, -sixteen_g);
}

#[test]
fn order_17() {
let g = AffinePoint::<C101>::generator();
let mut g_double = g.point_doubling();
let mut count = 2;
while g_double != g && -g_double != g {
g_double = g_double.point_doubling();
count *= 2;
}
assert_eq!(count + 1, 17);
}

#[test]
fn point_addition() {
let g = AffinePoint::<C101>::generator();
let two_g = g.point_doubling();
let three_g = g + two_g;
let expected_3g = AffinePoint::<C101>::new(F::new(26), F::new(45));
let expected_negative_3g = AffinePoint::<C101>::new(F::new(26), F::new(56));
assert_eq!(three_g, expected_3g);
assert_eq!(-three_g, expected_negative_3g);

let four_g = g + three_g;
let expected_4g = AffinePoint::<C101>::new(F::new(65), F::new(98));
let expected_negative_4g = AffinePoint::<C101>::new(F::new(65), F::new(3));
assert_eq!(four_g, expected_4g);
assert_eq!(-four_g, expected_negative_4g);

let five_g = g + four_g;
let expected_5g = AffinePoint::<C101>::new(F::new(12), F::new(32));
let expected_negative_5g = AffinePoint::<C101>::new(F::new(12), F::new(69));
assert_eq!(five_g, expected_5g);
assert_eq!(-five_g, expected_negative_5g);

assert_eq!(g + AffinePoint::new_infty(), g);
assert_eq!(AffinePoint::new_infty() + g, g);
assert_eq!(g + (-g), AffinePoint::new_infty());
}

#[test]
fn scalar_multiplication_rhs() {
let g = AffinePoint::<C101>::generator();
let two_g = g * 2;
let expected_2g = g.point_doubling();
assert_eq!(two_g, expected_2g);
assert_eq!(-two_g, -expected_2g);
}

#[test]
fn scalar_multiplication_lhs() {
let g = AffinePoint::<C101>::generator();
let two_g = 2 * g;
let expected_2g = g.point_doubling();
assert_eq!(two_g, expected_2g);
assert_eq!(-two_g, -expected_2g);
}
}
83 changes: 83 additions & 0 deletions src/curves/g2_curve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::ops::Add;

use super::CurveParams;
use crate::field::{gf_101::GF101, gf_101_2::QuadraticPlutoField, ExtensionField, FiniteField};

#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
pub struct G2Curve {}
// The Elliptic curve $y^2=x^3+3$, i.e.
// - a = 0
// - b = 3

impl CurveParams for G2Curve {
type FieldElement = QuadraticPlutoField<GF101>;

const EQUATION_A: Self::FieldElement = QuadraticPlutoField::<GF101>::ZERO;
const EQUATION_B: Self::FieldElement =
QuadraticPlutoField::<GF101>::new(GF101::new(3), GF101::ZERO);
const GENERATOR: (Self::FieldElement, Self::FieldElement) = (
QuadraticPlutoField::<GF101>::new(GF101::new(36), GF101::ZERO),
QuadraticPlutoField::<GF101>::new(GF101::ZERO, GF101::new(31)),
);
const ORDER: u32 = 289;
// extension field subgroup should have order r^2 where r is order of first group
const THREE: QuadraticPlutoField<GF101> =
QuadraticPlutoField::<GF101>::new(GF101::new(3), GF101::ZERO);
const TWO: QuadraticPlutoField<GF101> =
QuadraticPlutoField::<GF101>::new(GF101::TWO, GF101::ZERO);
}

// a naive impl with affine point

impl G2Curve {
pub fn on_curve(
x: QuadraticPlutoField<GF101>,
y: QuadraticPlutoField<GF101>,
) -> (QuadraticPlutoField<GF101>, QuadraticPlutoField<GF101>) {
println!("X: {:?}, Y: {:?}", x, y);
// TODO Continue working on this
// ( x ) ( y ) ( x , y )
// example: plug in ((36, 0), (0, 31)): (36, 31t)
// x = 36, y = 31t,
// curve : y^2=x^3+3,

// y = (31t)^2 = 52 * t^2
// check if there are any x terms, if not, element is in base field
let mut LHS = x;
let mut RHS = y;
if x.value[1] != GF101::ZERO {
LHS = x * x * (-GF101::new(2)) - Self::EQUATION_B;
} else {
LHS = x * x * x - Self::EQUATION_B;
}
if y.value[1] != GF101::ZERO {
// y has degree two so if there is a x -> there will be an x^2 term which we substitude with
// -2 since... TODO explain this and relationship to embedding degree
RHS *= -GF101::new(2);
}
// minus
LHS -= Self::EQUATION_B;
assert_eq!(LHS, RHS, "Point is not on curve");
(x, y)
}
}

mod test {
use super::*;
use crate::curves::AffinePoint;

// #[test]
// fn on_curve() {
// let gen = G2Curve::on_curve(G2Curve::GENERATOR.0, G2Curve::GENERATOR.1);
// }

// #[test]
// fn doubling() {
// let g = AffinePoint::<G2Curve>::generator();
// println!("g: {:?}", g)

// // want to asset that g = (36, 31*X)
// // right now this ^ fails to construct as it doesn't believe that the generator is a valid
// point on the curve // want to asset that 2g = (90 , 82*X)
// }
}
Loading

0 comments on commit 2637594

Please sign in to comment.