lambdaworks_math/elliptic_curve/edwards/curves/
ed448_goldilocks.rs1use crate::{
2 elliptic_curve::{
3 edwards::{point::EdwardsProjectivePoint, traits::IsEdwards},
4 traits::IsEllipticCurve,
5 },
6 field::{element::FieldElement, fields::p448_goldilocks_prime_field::P448GoldilocksPrimeField},
7};
8
9#[derive(Debug, Clone)]
10pub struct Ed448Goldilocks;
11
12impl IsEllipticCurve for Ed448Goldilocks {
13 type BaseField = P448GoldilocksPrimeField;
14 type PointRepresentation = EdwardsProjectivePoint<Self>;
15
16 fn generator() -> Self::PointRepresentation {
27 let point= Self::PointRepresentation::new([
32 FieldElement::<Self::BaseField>::from_hex("4f1970c66bed0ded221d15a622bf36da9e146570470f1767ea6de324a3d3a46412ae1af72ab66511433b80e18b00938e2626a82bc70cc05e").unwrap(),
33 FieldElement::<Self::BaseField>::from_hex("693f46716eb6bc248876203756c9c7624bea73736ca3984087789c1e05a0c2d73ad3ff1ce67c39c4fdbd132c4ed7c8ad9808795bf230fa14").unwrap(),
34 FieldElement::one(),
35 ]);
36 point.unwrap()
37 }
38}
39
40impl IsEdwards for Ed448Goldilocks {
41 fn a() -> FieldElement<Self::BaseField> {
42 FieldElement::one()
43 }
44
45 fn d() -> FieldElement<Self::BaseField> {
46 -FieldElement::from(39081)
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::{
54 cyclic_group::IsGroup, elliptic_curve::traits::EllipticCurveError,
55 field::element::FieldElement,
56 };
57
58 #[allow(clippy::upper_case_acronyms)]
59 type FE = FieldElement<P448GoldilocksPrimeField>;
60
61 fn generator_times_5() -> EdwardsProjectivePoint<Ed448Goldilocks> {
62 let x = FE::from_hex("7a9f9335a48dcb0e2ba7601eedb50def80cbcf728562ada756d761e8958812808bc0d57a920c3c96f07b2d8cefc6f950d0a99d1092030034").unwrap();
63 let y = FE::from_hex("adfd751a2517edd3b9109ce4fd580ade260ca1823ab18fced86551f7b698017127d7a4ee59d2b33c58405512881f225443b4731472f435eb").unwrap();
64 Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
65 }
66
67 fn point_1() -> EdwardsProjectivePoint<Ed448Goldilocks> {
68 let x = FE::from_hex("c591e0987244569fbb80a8edda5f9c5b30d9e7862acbb19ac0f24b766fe29c5e5782efc0e7a169f0c55c5524f8a9f9333ca985ec56404926").unwrap();
69 let y = FE::from_hex("f969573bf05f19ac5824718d7483d3b83a3ece5847e25487ae2a176290ad2b1cb9c7f4dd55f6ca6c50209556d7fc16e0683c3177356ac9bc").unwrap();
70 Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
71 }
72
73 fn point_1_times_7() -> EdwardsProjectivePoint<Ed448Goldilocks> {
74 let x = FE::from_hex("63c9cd1d79f027458015c2013fc819dd0f46f71c21a11fee0c32998acd17bac5b06d0f2f1e1539cfc33223a6e989b2b119dae9bbb16c3743").unwrap();
75 let y = FE::from_hex("654de66ab8be9fbeec6e72798a0ba2bb39c1888b99104de6cb0acf4516ea5e018bd292a1855f0fea673a5d8e8724d1b19ca52817db624f06").unwrap();
76 Ed448Goldilocks::create_point_from_affine(x, y).unwrap()
77 }
78
79 #[test]
80 fn generator_satisfies_defining_equation() {
81 let g = Ed448Goldilocks::generator().to_affine();
82 assert_eq!(Ed448Goldilocks::defining_equation(g.x(), g.y()), FE::zero());
83 }
84
85 #[test]
86 fn adding_generator_five_times_works() {
87 let g_times_5 = Ed448Goldilocks::generator().operate_with_self(5_u16);
88 assert_eq!(g_times_5, generator_times_5());
89 }
90
91 #[test]
92 fn adding_point_1_seven_times_works() {
93 let point_1 = point_1();
94 let point_1_times_7 = point_1_times_7();
95 assert_eq!(point_1.operate_with_self(7_u16), point_1_times_7);
96 }
97
98 #[test]
99 fn create_valid_point_works() {
100 let p = point_1();
101 assert_eq!(*p.x(), FE::from_hex("c591e0987244569fbb80a8edda5f9c5b30d9e7862acbb19ac0f24b766fe29c5e5782efc0e7a169f0c55c5524f8a9f9333ca985ec56404926").unwrap());
102 assert_eq!(*p.y(), FE::from_hex("f969573bf05f19ac5824718d7483d3b83a3ece5847e25487ae2a176290ad2b1cb9c7f4dd55f6ca6c50209556d7fc16e0683c3177356ac9bc").unwrap());
103 assert_eq!(*p.z(), FE::one());
104 }
105
106 #[test]
107 fn create_invalid_points_panics() {
108 assert_eq!(
109 Ed448Goldilocks::create_point_from_affine(FE::from(1), FE::from(1)).unwrap_err(),
110 EllipticCurveError::InvalidPoint
111 )
112 }
113}