Skip to content

Commit

Permalink
Add Ed448-Goldilocks elliptic curve
Browse files Browse the repository at this point in the history
  • Loading branch information
techiepriyansh committed Sep 18, 2023
1 parent eea6d8d commit 80979b2
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
102 changes: 102 additions & 0 deletions math/src/elliptic_curve/edwards/curves/ed448_goldilocks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::{
elliptic_curve::{
edwards::{point::EdwardsProjectivePoint, traits::IsEdwards},
traits::IsEllipticCurve,
},
field::{element::FieldElement, fields::p448_goldilocks_prime_field::P448GoldilocksPrimeField},
};

#[derive(Debug, Clone)]
pub struct Ed448Goldilocks;

impl IsEllipticCurve for Ed448Goldilocks {
type BaseField = P448GoldilocksPrimeField;
type PointRepresentation = EdwardsProjectivePoint<Self>;

/// Taken from https://www.rfc-editor.org/rfc/rfc7748#page-6
fn generator() -> Self::PointRepresentation {
Self::PointRepresentation::new([
FieldElement::<Self::BaseField>::new_base("4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e"),
FieldElement::<Self::BaseField>::new_base("693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14"),
FieldElement::one(),
])
}
}

impl IsEdwards for Ed448Goldilocks {
fn a() -> FieldElement<Self::BaseField> {
FieldElement::one()
}

fn d() -> FieldElement<Self::BaseField> {
-FieldElement::from(39081)
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{
cyclic_group::IsGroup, elliptic_curve::traits::EllipticCurveError,
field::element::FieldElement,
};

#[allow(clippy::upper_case_acronyms)]
type FEE = FieldElement<P448GoldilocksPrimeField>;

fn generator_times_5() -> EdwardsProjectivePoint<Ed448Goldilocks> {
let x = FEE::new_base("7a9f9335a48dcb0e2ba7601eedb50def80cbcf728562ada756d761e8958812808bc0d57a920c3c96f07b2d8cefc6f950d0a99d1092030034");
let y = FEE::new_base("adfd751a2517edd3b9109ce4fd580ade260ca1823ab18fced86551f7b698017127d7a4ee59d2b33c58405512881f225443b4731472f435eb");
Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
}

fn point_1() -> EdwardsProjectivePoint<Ed448Goldilocks> {
let x = FEE::new_base("c591e0987244569fbb80a8edda5f9c5b30d9e7862acbb19ac0f24b766fe29c5e5782efc0e7a169f0c55c5524f8a9f9333ca985ec56404926");
let y = FEE::new_base("f969573bf05f19ac5824718d7483d3b83a3ece5847e25487ae2a176290ad2b1cb9c7f4dd55f6ca6c50209556d7fc16e0683c3177356ac9bc");
Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
}

fn point_1_times_7() -> EdwardsProjectivePoint<Ed448Goldilocks> {
let x = FEE::new_base("63c9cd1d79f027458015c2013fc819dd0f46f71c21a11fee0c32998acd17bac5b06d0f2f1e1539cfc33223a6e989b2b119dae9bbb16c3743");
let y = FEE::new_base("654de66ab8be9fbeec6e72798a0ba2bb39c1888b99104de6cb0acf4516ea5e018bd292a1855f0fea673a5d8e8724d1b19ca52817db624f06");
Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
}

#[test]
fn generator_satisfies_defining_equation() {
let g = Ed448Goldilocks::generator().to_affine();
assert_eq!(
Ed448Goldilocks::defining_equation(g.x(), g.y()),
FEE::zero()
);
}

#[test]
fn adding_generator_five_times_works() {
let g_times_5 = Ed448Goldilocks::generator().operate_with_self(5_u16);
assert_eq!(g_times_5, generator_times_5());
}

#[test]
fn adding_point_1_seven_times_works() {
let point_1 = point_1();
let point_1_times_7 = point_1_times_7();
assert_eq!(point_1.operate_with_self(7_u16), point_1_times_7);
}

#[test]
fn create_valid_point_works() {
let p = point_1();
assert_eq!(*p.x(), FEE::new_base("c591e0987244569fbb80a8edda5f9c5b30d9e7862acbb19ac0f24b766fe29c5e5782efc0e7a169f0c55c5524f8a9f9333ca985ec56404926"));
assert_eq!(*p.y(), FEE::new_base("f969573bf05f19ac5824718d7483d3b83a3ece5847e25487ae2a176290ad2b1cb9c7f4dd55f6ca6c50209556d7fc16e0683c3177356ac9bc"));
assert_eq!(*p.z(), FEE::one());
}

#[test]
fn create_invalid_points_panics() {
assert_eq!(
Ed448Goldilocks::create_point_from_affine(FEE::from(1), FEE::from(1)).unwrap_err(),
EllipticCurveError::InvalidPoint
)
}
}
1 change: 1 addition & 0 deletions math/src/elliptic_curve/edwards/curves/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod bandersnatch;
pub mod ed448_goldilocks;
pub mod tiny_jub_jub;
8 changes: 7 additions & 1 deletion math/src/field/fields/p448_goldilocks_prime_field.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::field::errors::FieldError;
use crate::field::traits::IsField;
use crate::field::{element::FieldElement, errors::FieldError};
use crate::unsigned_integer::element::UnsignedInteger;

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -247,6 +247,12 @@ impl U56x8 {
}
}

impl FieldElement<P448GoldilocksPrimeField> {
pub fn new_base(a_hex: &str) -> Self {
Self::new(U56x8::from(a_hex))
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 80979b2

Please sign in to comment.