From ee90202a58d355a54983ab71651481e028983ebf Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 13 Apr 2021 00:24:50 +0000 Subject: [PATCH] Trivial cleanups to Elligator2 encoding. cf. https://github.com/dalek-cryptography/curve25519-dalek/pull/336 --- src/backend/serial/u32/constants.rs | 12 ++++++++++-- src/backend/serial/u64/constants.rs | 16 ++++++++++++++-- src/montgomery.rs | 18 ++++++++++-------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/backend/serial/u32/constants.rs b/src/backend/serial/u32/constants.rs index 9ffb79370..584853905 100644 --- a/src/backend/serial/u32/constants.rs +++ b/src/backend/serial/u32/constants.rs @@ -64,10 +64,18 @@ pub(crate) const SQRT_M1: FieldElement2625 = FieldElement2625([ pub(crate) const APLUS2_OVER_FOUR: FieldElement2625 = FieldElement2625([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]); -/// `MONT_A` is a constant of Curve25519. (This is used internally within the Elligator map.) -pub(crate) const MONT_A: FieldElement2625 = +/// `MONTGOMERY_A` is equal to 486662, which is a constant of the curve equation +/// for Curve25519 in its Montgomery form. (This is used internally within the +/// Elligator map.) +pub(crate) const MONTGOMERY_A: FieldElement2625 = FieldElement2625([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]); +/// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the +/// Elligator map.) +pub(crate) const MONTGOMERY_A_NEG: FieldElement2625 = FieldElement2625([ + 66622183, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, +]); + /// `L` is the order of base point, i.e. 2^252 + /// 27742317777372353535851937790883648493 pub(crate) const L: Scalar29 = Scalar29([ diff --git a/src/backend/serial/u64/constants.rs b/src/backend/serial/u64/constants.rs index c89a52138..261ca6bc5 100644 --- a/src/backend/serial/u64/constants.rs +++ b/src/backend/serial/u64/constants.rs @@ -92,8 +92,20 @@ pub(crate) const SQRT_M1: FieldElement51 = FieldElement51([ /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) pub(crate) const APLUS2_OVER_FOUR: FieldElement51 = FieldElement51([121666, 0, 0, 0, 0]); -/// `MONT_A` is a constant of Curve25519. (This is used internally within the Elligator map.) -pub(crate) const MONT_A: FieldElement51 = FieldElement51([486662, 0, 0, 0, 0]); +/// `MONTGOMERY_A` is equal to 486662, which is a constant of the curve equation +/// for Curve25519 in its Montgomery form. (This is used internally within the +/// Elligator map.) +pub(crate) const MONTGOMERY_A: FieldElement51 = FieldElement51([486662, 0, 0, 0, 0]); + +/// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the +/// Elligator map.) +pub(crate) const MONTGOMERY_A_NEG: FieldElement51 = FieldElement51([ + 2251799813198567, + 2251799813685247, + 2251799813685247, + 2251799813685247, + 2251799813685247, +]); /// `L` is the order of base point, i.e. 2^252 + 27742317777372353535851937790883648493 pub(crate) const L: Scalar52 = Scalar52([ diff --git a/src/montgomery.rs b/src/montgomery.rs index 17b86772b..de0f8b7c0 100644 --- a/src/montgomery.rs +++ b/src/montgomery.rs @@ -51,7 +51,7 @@ use core::ops::{Mul, MulAssign}; -use constants::{APLUS2_OVER_FOUR, MONT_A}; +use constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG}; use edwards::{CompressedEdwardsY, EdwardsPoint}; use field::FieldElement; use scalar::Scalar; @@ -157,19 +157,21 @@ impl MontgomeryPoint { } } -/// Perform the Elligator2 mapping to a Montgomery point +/// Perform the Elligator2 mapping to a Montgomery point. /// -/// See -/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-6.7.1 +/// See https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-10#section-6.7.1 +// +// TODO Determine how much of the hash-to-group API should be exposed after the CFRG +// draft gets into a more polished/accepted state. +#[allow(unused)] pub(crate) fn elligator_encode(r_0: &FieldElement) -> MontgomeryPoint { - let minus_a = -&MONT_A; /* A = 486662 */ let one = FieldElement::one(); let d_1 = &one + &r_0.square2(); /* 2r^2 */ - let d = &minus_a * &(d_1.invert()); /* A/(1+2r^2) */ + let d = &MONTGOMERY_A_NEG * &(d_1.invert()); /* A/(1+2r^2) */ let d_sq = &d.square(); - let au = &MONT_A * &d; + let au = &MONTGOMERY_A * &d; let inner = &(d_sq + &au) + &one; let eps = &d * &inner; /* eps = d^3 + Ad^2 + d */ @@ -177,7 +179,7 @@ pub(crate) fn elligator_encode(r_0: &FieldElement) -> MontgomeryPoint { let (eps_is_sq, _eps) = FieldElement::sqrt_ratio_i(&eps, &one); let zero = FieldElement::zero(); - let Atemp = FieldElement::conditional_select(&MONT_A, &zero, eps_is_sq); /* 0, or A if nonsquare*/ + let Atemp = FieldElement::conditional_select(&MONTGOMERY_A, &zero, eps_is_sq); /* 0, or A if nonsquare*/ let mut u = &d + &Atemp; /* d, or d+A if nonsquare */ u.conditional_negate(!eps_is_sq); /* d, or -d-A if nonsquare */