lambdaworks_math/elliptic_curve/edwards/curves/bandersnatch/
curve.rs1pub use super::field::FqField;
2use crate::elliptic_curve::edwards::point::EdwardsProjectivePoint;
3use crate::elliptic_curve::traits::IsEllipticCurve;
4use crate::{elliptic_curve::edwards::traits::IsEdwards, field::element::FieldElement};
5
6pub type BaseBandersnatchFieldElement = FqField;
7
8#[derive(Clone, Debug)]
9pub struct BandersnatchCurve;
10
11impl IsEllipticCurve for BandersnatchCurve {
12 type BaseField = BaseBandersnatchFieldElement;
13 type PointRepresentation = EdwardsProjectivePoint<Self>;
14
15 fn generator() -> Self::PointRepresentation {
29 let point = Self::PointRepresentation::new([
35 FieldElement::<Self::BaseField>::new_base(
36 "29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18",
37 ),
38 FieldElement::<Self::BaseField>::new_base(
39 "2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166",
40 ),
41 FieldElement::one(),
42 ]);
43 point.unwrap()
44 }
45}
46
47impl IsEdwards for BandersnatchCurve {
48 fn a() -> FieldElement<Self::BaseField> {
49 FieldElement::<Self::BaseField>::new_base(
50 "73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFEFFFFFFFC",
51 )
52 }
53
54 fn d() -> FieldElement<Self::BaseField> {
55 FieldElement::<Self::BaseField>::new_base(
56 "6389C12633C267CBC66E3BF86BE3B6D8CB66677177E54F92B369F2F5188D58E7",
57 )
58 }
59}
60
61#[cfg(test)]
62mod tests {
63
64 use super::*;
65 use crate::{
66 cyclic_group::IsGroup, elliptic_curve::traits::EllipticCurveError,
67 field::element::FieldElement, unsigned_integer::element::U256,
68 };
69
70 #[allow(clippy::upper_case_acronyms)]
71 type FEE = FieldElement<BaseBandersnatchFieldElement>;
72
73 fn point_1() -> EdwardsProjectivePoint<BandersnatchCurve> {
74 let x = FEE::new_base("29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18");
75 let y = FEE::new_base("2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166");
76
77 BandersnatchCurve::create_point_from_affine(x, y).unwrap()
78 }
79
80 #[test]
81 fn test_scalar_mul() {
82 let g = BandersnatchCurve::generator();
83 let result1 = g.operate_with_self(5u16);
84
85 assert_eq!(
86 result1.x().clone(),
87 FEE::new_base("68CBECE0B8FB55450410CBC058928A567EED293D168FAEF44BFDE25F943AABE0")
88 );
89
90 let scalar =
91 U256::from_hex("1CFB69D4CA675F520CCE760202687600FF8F87007419047174FD06B52876E7E6")
92 .unwrap();
93 let result2 = g.operate_with_self(scalar);
94
95 assert_eq!(
96 result2.x().clone(),
97 FEE::new_base("68CBECE0B8FB55450410CBC058928A567EED293D168FAEF44BFDE25F943AABE0")
98 );
99 }
100
101 #[test]
102 fn test_create_valid_point_works() {
103 let p = BandersnatchCurve::generator();
104
105 assert_eq!(p, p.clone());
106 }
107
108 #[test]
109 fn create_valid_point_works() {
110 let p = point_1();
111 assert_eq!(
112 *p.x(),
113 FEE::new_base("29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18")
114 );
115 assert_eq!(
116 *p.y(),
117 FEE::new_base("2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166")
118 );
119 assert_eq!(*p.z(), FEE::new_base("1"));
120 }
121
122 #[test]
123 fn create_invalid_points_panics() {
124 assert_eq!(
125 BandersnatchCurve::create_point_from_affine(FEE::from(1), FEE::from(1)).unwrap_err(),
126 EllipticCurveError::InvalidPoint
127 )
128 }
129
130 #[test]
131 fn equality_works() {
132 let g = BandersnatchCurve::generator();
133 let g2 = g.operate_with(&g);
134 assert_ne!(&g2, &g);
135 assert_eq!(&g, &g);
136 }
137
138 #[test]
139 fn operate_with_self_works_1() {
140 let g = BandersnatchCurve::generator();
141 assert_eq!(
142 g.operate_with(&g).operate_with(&g),
143 g.operate_with_self(3_u16)
144 );
145 }
146}