From 541323016339aca0575501fa9556dd8f32a7f654 Mon Sep 17 00:00:00 2001 From: 0xKitetsu <105421120+0xKitetsu-smdk@users.noreply.github.com> Date: Tue, 5 Sep 2023 21:47:20 +0530 Subject: [PATCH] Impl Bandersnatch curve (#513) * bandersnatch first version without tests * test impl * switching from SW to TE * set a hex to -5 over modulus * fix * fixed * tests pass * Added some tests * clippy linting * renamed field_extension to field in bandersnatch curve --------- Co-authored-by: MatteoMer Co-authored-by: Dragan Pilipovic Co-authored-by: Matteo <30910760+MatteoMer@users.noreply.github.com> Co-authored-by: Mauro Toscano <12560266+MauroToscano@users.noreply.github.com> --- .../edwards/curves/bandersnatch/curve.rs | 129 ++++++++++++++++++ .../edwards/curves/bandersnatch/field.rs | 28 ++++ .../edwards/curves/bandersnatch/mod.rs | 2 + math/src/elliptic_curve/edwards/curves/mod.rs | 1 + 4 files changed, 160 insertions(+) create mode 100644 math/src/elliptic_curve/edwards/curves/bandersnatch/curve.rs create mode 100644 math/src/elliptic_curve/edwards/curves/bandersnatch/field.rs create mode 100644 math/src/elliptic_curve/edwards/curves/bandersnatch/mod.rs diff --git a/math/src/elliptic_curve/edwards/curves/bandersnatch/curve.rs b/math/src/elliptic_curve/edwards/curves/bandersnatch/curve.rs new file mode 100644 index 000000000..85211713a --- /dev/null +++ b/math/src/elliptic_curve/edwards/curves/bandersnatch/curve.rs @@ -0,0 +1,129 @@ +pub use super::field::FqField; +use crate::elliptic_curve::edwards::point::EdwardsProjectivePoint; +use crate::elliptic_curve::traits::IsEllipticCurve; +use crate::{elliptic_curve::edwards::traits::IsEdwards, field::element::FieldElement}; + +pub type BaseBandersnatchFieldElement = FqField; + +#[derive(Clone, Debug)] +pub struct BandersnatchCurve; + +impl IsEllipticCurve for BandersnatchCurve { + type BaseField = BaseBandersnatchFieldElement; + type PointRepresentation = EdwardsProjectivePoint; + + // Values are from https://github.com/arkworks-rs/curves/blob/5a41d7f27a703a7ea9c48512a4148443ec6c747e/ed_on_bls12_381_bandersnatch/src/curves/mod.rs#L120 + // Converted to Hex + fn generator() -> Self::PointRepresentation { + Self::PointRepresentation::new([ + FieldElement::::new_base( + "29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18", + ), + FieldElement::::new_base( + "2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166", + ), + FieldElement::one(), + ]) + } +} + +impl IsEdwards for BandersnatchCurve { + fn a() -> FieldElement { + FieldElement::::new_base( + "73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFEFFFFFFFC", + ) + } + + fn d() -> FieldElement { + FieldElement::::new_base( + "6389C12633C267CBC66E3BF86BE3B6D8CB66677177E54F92B369F2F5188D58E7", + ) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + use crate::{ + cyclic_group::IsGroup, elliptic_curve::traits::EllipticCurveError, + field::element::FieldElement, unsigned_integer::element::U256, + }; + + #[allow(clippy::upper_case_acronyms)] + type FEE = FieldElement; + + fn point_1() -> EdwardsProjectivePoint { + let x = FEE::new_base("29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18"); + let y = FEE::new_base("2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166"); + + BandersnatchCurve::create_point_from_affine(x, y).unwrap() + } + + #[test] + fn test_scalar_mul() { + let g = BandersnatchCurve::generator(); + let result1 = g.operate_with_self(5u16); + + assert_eq!( + result1.x().clone(), + FEE::new_base("68CBECE0B8FB55450410CBC058928A567EED293D168FAEF44BFDE25F943AABE0") + ); + + let scalar = + U256::from_hex("1CFB69D4CA675F520CCE760202687600FF8F87007419047174FD06B52876E7E6") + .unwrap(); + let result2 = g.operate_with_self(scalar); + + assert_eq!( + result2.x().clone(), + FEE::new_base("68CBECE0B8FB55450410CBC058928A567EED293D168FAEF44BFDE25F943AABE0") + ); + } + + #[test] + fn test_create_valid_point_works() { + let p = BandersnatchCurve::generator(); + + assert_eq!(p, p.clone()); + } + + #[test] + fn create_valid_point_works() { + let p = point_1(); + assert_eq!( + *p.x(), + FEE::new_base("29C132CC2C0B34C5743711777BBE42F32B79C022AD998465E1E71866A252AE18") + ); + assert_eq!( + *p.y(), + FEE::new_base("2A6C669EDA123E0F157D8B50BADCD586358CAD81EEE464605E3167B6CC974166") + ); + assert_eq!(*p.z(), FEE::new_base("1")); + } + + #[test] + fn create_invalid_points_panics() { + assert_eq!( + BandersnatchCurve::create_point_from_affine(FEE::from(1), FEE::from(1)).unwrap_err(), + EllipticCurveError::InvalidPoint + ) + } + + #[test] + fn equality_works() { + let g = BandersnatchCurve::generator(); + let g2 = g.operate_with(&g); + assert_ne!(&g2, &g); + assert_eq!(&g, &g); + } + + #[test] + fn operate_with_self_works_1() { + let g = BandersnatchCurve::generator(); + assert_eq!( + g.operate_with(&g).operate_with(&g), + g.operate_with_self(3_u16) + ); + } +} diff --git a/math/src/elliptic_curve/edwards/curves/bandersnatch/field.rs b/math/src/elliptic_curve/edwards/curves/bandersnatch/field.rs new file mode 100644 index 000000000..1634df248 --- /dev/null +++ b/math/src/elliptic_curve/edwards/curves/bandersnatch/field.rs @@ -0,0 +1,28 @@ +//! Base field of bandersantch -- which is also the scalar field of BLS12-381 curve. + +use crate::{ + field::{ + element::FieldElement, + fields::montgomery_backed_prime_fields::{IsModulus, MontgomeryBackendPrimeField}, + }, + unsigned_integer::element::U256, +}; + +pub const BANDERSNATCH_PRIME_FIELD_ORDER: U256 = + U256::from_hex_unchecked("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"); + +#[derive(Clone, Debug)] +pub struct FqConfig; + +impl IsModulus for FqConfig { + const MODULUS: U256 = BANDERSNATCH_PRIME_FIELD_ORDER; +} + +pub type FqField = MontgomeryBackendPrimeField; + +impl FieldElement { + pub fn new_base(a_hex: &str) -> Self { + Self::new(U256::from(a_hex)) + } +} +pub type FqElement = FieldElement; diff --git a/math/src/elliptic_curve/edwards/curves/bandersnatch/mod.rs b/math/src/elliptic_curve/edwards/curves/bandersnatch/mod.rs new file mode 100644 index 000000000..f773c8d78 --- /dev/null +++ b/math/src/elliptic_curve/edwards/curves/bandersnatch/mod.rs @@ -0,0 +1,2 @@ +pub mod curve; +pub mod field; diff --git a/math/src/elliptic_curve/edwards/curves/mod.rs b/math/src/elliptic_curve/edwards/curves/mod.rs index 55679082c..34aec6d60 100644 --- a/math/src/elliptic_curve/edwards/curves/mod.rs +++ b/math/src/elliptic_curve/edwards/curves/mod.rs @@ -1 +1,2 @@ +pub mod bandersnatch; pub mod tiny_jub_jub;