diff --git a/src/arithmetic/hashtocurve.rs b/src/arithmetic/hashtocurve.rs index 20f042f..0b19376 100644 --- a/src/arithmetic/hashtocurve.rs +++ b/src/arithmetic/hashtocurve.rs @@ -42,15 +42,18 @@ impl, I: CurveAffine> /// /// # Panics /// Panics if z is square. - pub fn new(z: &F, isogeny_constants: [F; 13]) -> Self { - let a = I::a(); - let b = I::b(); - + pub fn new( + z: F, + isogeny_constants: [F; 13], + minus_b_over_a: F, + b_over_za: F, + theta: F, + ) -> Self { SimplifiedSWUWithDegree3Isogeny { - z: *z, - minus_b_over_a: (-b) * &(a.invert().unwrap()), - b_over_za: b * &((*z * a).invert().unwrap()), - theta: (F::ROOT_OF_UNITY.invert().unwrap() * z).sqrt().unwrap(), + z: z, + minus_b_over_a, + b_over_za, + theta, isogeny_constants: isogeny_constants, _marker_c: PhantomData, _marker_i: PhantomData, diff --git a/src/pasta/curves.rs b/src/pasta/curves.rs index 57ee84c..c5a836c 100644 --- a/src/pasta/curves.rs +++ b/src/pasta/curves.rs @@ -858,3 +858,239 @@ new_curve_impl!( [1265, 0, 0, 0], general ); + +impl IsoEpAffine { + /// Constants used for computing the isogeny from IsoEp to Ep. + pub const ISOGENY_CONSTANTS: [Fp; 13] = [ + Fp::from_raw([ + 0x775f6034aaaaaaab, + 0x4081775473d8375b, + 0xe38e38e38e38e38e, + 0x0e38e38e38e38e38, + ]), + Fp::from_raw([ + 0x8cf863b02814fb76, + 0x0f93b82ee4b99495, + 0x267c7ffa51cf412a, + 0x3509afd51872d88e, + ]), + Fp::from_raw([ + 0x0eb64faef37ea4f7, + 0x380af066cfeb6d69, + 0x98c7d7ac3d98fd13, + 0x17329b9ec5253753, + ]), + Fp::from_raw([ + 0xeebec06955555580, + 0x8102eea8e7b06eb6, + 0xc71c71c71c71c71c, + 0x1c71c71c71c71c71, + ]), + Fp::from_raw([ + 0xc47f2ab668bcd71f, + 0x9c434ac1c96b6980, + 0x5a607fcce0494a79, + 0x1d572e7ddc099cff, + ]), + Fp::from_raw([ + 0x2aa3af1eae5b6604, + 0xb4abf9fb9a1fc81c, + 0x1d13bf2a7f22b105, + 0x325669becaecd5d1, + ]), + Fp::from_raw([ + 0x5ad985b5e38e38e4, + 0x7642b01ad461bad2, + 0x4bda12f684bda12f, + 0x1a12f684bda12f68, + ]), + Fp::from_raw([ + 0xc67c31d8140a7dbb, + 0x07c9dc17725cca4a, + 0x133e3ffd28e7a095, + 0x1a84d7ea8c396c47, + ]), + Fp::from_raw([ + 0x02e2be87d225b234, + 0x1765e924f7459378, + 0x303216cce1db9ff1, + 0x3fb98ff0d2ddcadd, + ]), + Fp::from_raw([ + 0x93e53ab371c71c4f, + 0x0ac03e8e134eb3e4, + 0x7b425ed097b425ed, + 0x025ed097b425ed09, + ]), + Fp::from_raw([ + 0x5a28279b1d1b42ae, + 0x5941a3a4a97aa1b3, + 0x0790bfb3506defb6, + 0x0c02c5bcca0e6b7f, + ]), + Fp::from_raw([ + 0x4d90ab820b12320a, + 0xd976bbfabbc5661d, + 0x573b3d7f7d681310, + 0x17033d3c60c68173, + ]), + Fp::from_raw([ + 0x992d30ecfffffde5, + 0x224698fc094cf91b, + 0x0000000000000000, + 0x4000000000000000, + ]), + ]; + + /// Z = -13 + pub const Z: Fp = Fp::from_raw([ + 0x992d30ecfffffff4, + 0x224698fc094cf91b, + 0x0000000000000000, + 0x4000000000000000, + ]); + + /// `(-b) * &(a.invert().unwrap())` where a and b correspond with curve + /// constants for the isogenous curve. + pub const MINUS_B_OVER_A: Fp = Fp::from_raw([ + 0x1c3006d89470d7f8, + 0x7612d2d7211b7b10, + 0xd97cab452a13c1eb, + 0x3d115d87af7b3324, + ]); + + /// `b * &((*z * a).invert().unwrap())` where a and b correspond with curve + /// constants for the isogenous curve + pub const B_OVER_ZA: Fp = Fp::from_raw([ + 0xaf333253bca63800, + 0xf6ca6e5ce0e2b674, + 0xe9585bf1a0c67160, + 0x2c150731d26bf03d, + ]); + + /// `(F::ROOT_OF_UNITY.invert().unwrap() * z).sqrt().unwrap()` + pub const THETA: Fp = Fp::from_raw([ + 0xca330bcc09ac318e, + 0x51f64fc4dc888857, + 0x4647aef782d5cdc8, + 0x0f7bdb65814179b4, + ]); +} + +impl IsoEqAffine { + /// Constants used for computing the isogeny from IsoEq to Eq. + pub const ISOGENY_CONSTANTS: [Fq; 13] = [ + Fq::from_raw([ + 0x43cd42c800000001, + 0x0205dd51cfa0961a, + 0x8e38e38e38e38e39, + 0x38e38e38e38e38e3, + ]), + Fq::from_raw([ + 0x8b95c6aaf703bcc5, + 0x216b8861ec72bd5d, + 0xacecf10f5f7c09a2, + 0x1d935247b4473d17, + ]), + Fq::from_raw([ + 0xaeac67bbeb586a3d, + 0xd59d03d23b39cb11, + 0xed7ee4a9cdf78f8f, + 0x18760c7f7a9ad20d, + ]), + Fq::from_raw([ + 0xfb539a6f0000002b, + 0xe1c521a795ac8356, + 0x1c71c71c71c71c71, + 0x31c71c71c71c71c7, + ]), + Fq::from_raw([ + 0xb7284f7eaf21a2e9, + 0xa3ad678129b604d3, + 0x1454798a5b5c56b2, + 0x0a2de485568125d5, + ]), + Fq::from_raw([ + 0xf169c187d2533465, + 0x30cd6d53df49d235, + 0x0c621de8b91c242a, + 0x14735171ee542778, + ]), + Fq::from_raw([ + 0x6bef1642aaaaaaab, + 0x5601f4709a8adcb3, + 0xda12f684bda12f68, + 0x12f684bda12f684b, + ]), + Fq::from_raw([ + 0x8bee58e5fb81de63, + 0x21d910aefb03b31d, + 0xd6767887afbe04d1, + 0x2ec9a923da239e8b, + ]), + Fq::from_raw([ + 0x4986913ab4443034, + 0x97a3ca5c24e9ea63, + 0x66d1466e9de10e64, + 0x19b0d87e16e25788, + ]), + Fq::from_raw([ + 0x8f64842c55555533, + 0x8bc32d36fb21a6a3, + 0x425ed097b425ed09, + 0x1ed097b425ed097b, + ]), + Fq::from_raw([ + 0x58dfecce86b2745e, + 0x06a767bfc35b5bac, + 0x9e7eb64f890a820c, + 0x2f44d6c801c1b8bf, + ]), + Fq::from_raw([ + 0xd43d449776f99d2f, + 0x926847fb9ddd76a1, + 0x252659ba2b546c7e, + 0x3d59f455cafc7668, + ]), + Fq::from_raw([ + 0x8c46eb20fffffde5, + 0x224698fc0994a8dd, + 0x0000000000000000, + 0x4000000000000000, + ]), + ]; + + /// Z = -13 + pub const Z: Fq = Fq::from_raw([ + 0x8c46eb20fffffff4, + 0x224698fc0994a8dd, + 0x0000000000000000, + 0x4000000000000000, + ]); + + /// `(-b) * &(a.invert().unwrap())` where a and b correspond with curve + /// constants for the isogenous curve. + pub const MINUS_B_OVER_A: Fq = Fq::from_raw([ + 0x6dab74e8ef9dc7d3, + 0xbb4a015f2450502c, + 0x5385df3f6207bb22, + 0x23447efd3c451b98, + ]); + + /// `b * &((*z * a).invert().unwrap())` where a and b correspond with curve + /// constants for the isogenous curve + pub const B_OVER_ZA: Fq = Fq::from_raw([ + 0xb66e73e89c4736c2, + 0x6fa1dc53f442887a, + 0xcb59112c429e2216, + 0x252ca74e8e7b7846, + ]); + + /// `(F::ROOT_OF_UNITY.invert().unwrap() * z).sqrt().unwrap()` + pub const THETA: Fq = Fq::from_raw([ + 0x632cae9872df1b5d, + 0x38578ccadf03ac27, + 0x53c3808d9e2f2357, + 0x2b3483a1ee9a382f, + ]); +} diff --git a/src/pasta/pallas.rs b/src/pasta/pallas.rs index 8df350f..2361e50 100644 --- a/src/pasta/pallas.rs +++ b/src/pasta/pallas.rs @@ -3,7 +3,7 @@ use lazy_static::lazy_static; use super::{Ep, EpAffine, Fp, Fq, IsoEp, IsoEpAffine}; -use crate::arithmetic::{FieldExt, SimplifiedSWUWithDegree3Isogeny}; +use crate::arithmetic::SimplifiedSWUWithDegree3Isogeny; /// The base field of the Pallas and iso-Pallas curves. pub type Base = Fp; @@ -26,89 +26,13 @@ pub type IsoAffine = IsoEpAffine; lazy_static! { /// The iso-Pallas -> Pallas degree 3 isogeny map. pub static ref MAP: SimplifiedSWUWithDegree3Isogeny = { - let isogeny_constants: [Base; 13] = [ - Base::from_raw([ - 0x775f6034aaaaaaab, - 0x4081775473d8375b, - 0xe38e38e38e38e38e, - 0x0e38e38e38e38e38, - ]), - Base::from_raw([ - 0x8cf863b02814fb76, - 0x0f93b82ee4b99495, - 0x267c7ffa51cf412a, - 0x3509afd51872d88e, - ]), - Base::from_raw([ - 0x0eb64faef37ea4f7, - 0x380af066cfeb6d69, - 0x98c7d7ac3d98fd13, - 0x17329b9ec5253753, - ]), - Base::from_raw([ - 0xeebec06955555580, - 0x8102eea8e7b06eb6, - 0xc71c71c71c71c71c, - 0x1c71c71c71c71c71, - ]), - Base::from_raw([ - 0xc47f2ab668bcd71f, - 0x9c434ac1c96b6980, - 0x5a607fcce0494a79, - 0x1d572e7ddc099cff, - ]), - Base::from_raw([ - 0x2aa3af1eae5b6604, - 0xb4abf9fb9a1fc81c, - 0x1d13bf2a7f22b105, - 0x325669becaecd5d1, - ]), - Base::from_raw([ - 0x5ad985b5e38e38e4, - 0x7642b01ad461bad2, - 0x4bda12f684bda12f, - 0x1a12f684bda12f68, - ]), - Base::from_raw([ - 0xc67c31d8140a7dbb, - 0x07c9dc17725cca4a, - 0x133e3ffd28e7a095, - 0x1a84d7ea8c396c47, - ]), - Base::from_raw([ - 0x02e2be87d225b234, - 0x1765e924f7459378, - 0x303216cce1db9ff1, - 0x3fb98ff0d2ddcadd, - ]), - Base::from_raw([ - 0x93e53ab371c71c4f, - 0x0ac03e8e134eb3e4, - 0x7b425ed097b425ed, - 0x025ed097b425ed09, - ]), - Base::from_raw([ - 0x5a28279b1d1b42ae, - 0x5941a3a4a97aa1b3, - 0x0790bfb3506defb6, - 0x0c02c5bcca0e6b7f, - ]), - Base::from_raw([ - 0x4d90ab820b12320a, - 0xd976bbfabbc5661d, - 0x573b3d7f7d681310, - 0x17033d3c60c68173, - ]), - Base::from_raw([ - 0x992d30ecfffffde5, - 0x224698fc094cf91b, - 0x0000000000000000, - 0x4000000000000000, - ]), - ]; - - let z = -Base::from_u64(13); - SimplifiedSWUWithDegree3Isogeny::new(&z, isogeny_constants) + SimplifiedSWUWithDegree3Isogeny::new( + IsoAffine::Z, + IsoAffine::ISOGENY_CONSTANTS, + IsoAffine::MINUS_B_OVER_A, + IsoAffine::B_OVER_ZA, + IsoAffine::THETA + ) }; } @@ -154,7 +78,7 @@ fn test_iso_map() { #[test] fn test_map_to_curve_pallas() { - use crate::arithmetic::{Curve, CurveAffine}; + use crate::arithmetic::{Curve, CurveAffine, FieldExt}; use std::collections::HashSet; assert!(MAP.minus_b_over_a * IsoAffine::a() == -IsoAffine::b()); diff --git a/src/pasta/vesta.rs b/src/pasta/vesta.rs index e0e5967..a2ffc8a 100644 --- a/src/pasta/vesta.rs +++ b/src/pasta/vesta.rs @@ -3,7 +3,7 @@ use lazy_static::lazy_static; use super::{Eq, EqAffine, Fp, Fq, IsoEq, IsoEqAffine}; -use crate::arithmetic::{FieldExt, SimplifiedSWUWithDegree3Isogeny}; +use crate::arithmetic::SimplifiedSWUWithDegree3Isogeny; /// The base field of the Vesta and iso-Vesta curves. pub type Base = Fq; @@ -26,95 +26,19 @@ pub type IsoAffine = IsoEqAffine; lazy_static! { /// The iso-Vesta -> Vesta degree 3 isogeny map. pub static ref MAP: SimplifiedSWUWithDegree3Isogeny = { - let isogeny_constants: [Base; 13] = [ - Base::from_raw([ - 0x43cd42c800000001, - 0x0205dd51cfa0961a, - 0x8e38e38e38e38e39, - 0x38e38e38e38e38e3, - ]), - Base::from_raw([ - 0x8b95c6aaf703bcc5, - 0x216b8861ec72bd5d, - 0xacecf10f5f7c09a2, - 0x1d935247b4473d17, - ]), - Base::from_raw([ - 0xaeac67bbeb586a3d, - 0xd59d03d23b39cb11, - 0xed7ee4a9cdf78f8f, - 0x18760c7f7a9ad20d, - ]), - Base::from_raw([ - 0xfb539a6f0000002b, - 0xe1c521a795ac8356, - 0x1c71c71c71c71c71, - 0x31c71c71c71c71c7, - ]), - Base::from_raw([ - 0xb7284f7eaf21a2e9, - 0xa3ad678129b604d3, - 0x1454798a5b5c56b2, - 0x0a2de485568125d5, - ]), - Base::from_raw([ - 0xf169c187d2533465, - 0x30cd6d53df49d235, - 0x0c621de8b91c242a, - 0x14735171ee542778, - ]), - Base::from_raw([ - 0x6bef1642aaaaaaab, - 0x5601f4709a8adcb3, - 0xda12f684bda12f68, - 0x12f684bda12f684b, - ]), - Base::from_raw([ - 0x8bee58e5fb81de63, - 0x21d910aefb03b31d, - 0xd6767887afbe04d1, - 0x2ec9a923da239e8b, - ]), - Base::from_raw([ - 0x4986913ab4443034, - 0x97a3ca5c24e9ea63, - 0x66d1466e9de10e64, - 0x19b0d87e16e25788, - ]), - Base::from_raw([ - 0x8f64842c55555533, - 0x8bc32d36fb21a6a3, - 0x425ed097b425ed09, - 0x1ed097b425ed097b, - ]), - Base::from_raw([ - 0x58dfecce86b2745e, - 0x06a767bfc35b5bac, - 0x9e7eb64f890a820c, - 0x2f44d6c801c1b8bf, - ]), - Base::from_raw([ - 0xd43d449776f99d2f, - 0x926847fb9ddd76a1, - 0x252659ba2b546c7e, - 0x3d59f455cafc7668, - ]), - Base::from_raw([ - 0x8c46eb20fffffde5, - 0x224698fc0994a8dd, - 0x0000000000000000, - 0x4000000000000000, - ]), - ]; - - let z = -Base::from_u64(13); - SimplifiedSWUWithDegree3Isogeny::new(&z, isogeny_constants) + SimplifiedSWUWithDegree3Isogeny::new( + IsoAffine::Z, + IsoAffine::ISOGENY_CONSTANTS, + IsoAffine::MINUS_B_OVER_A, + IsoAffine::B_OVER_ZA, + IsoAffine::THETA + ) }; } #[test] fn test_map_to_curve_vesta() { - use crate::arithmetic::{Curve, CurveAffine}; + use crate::arithmetic::{Curve, CurveAffine, FieldExt}; use std::collections::HashSet; assert!(MAP.minus_b_over_a * IsoAffine::a() == -IsoAffine::b());