Skip to content

Commit

Permalink
Merge pull request #351 from isislovecruft/fix/cleanup-elligator
Browse files Browse the repository at this point in the history
Trivial cleanups to Elligator2 encoding
  • Loading branch information
isislovecruft committed Apr 13, 2021
2 parents cecc821 + ee90202 commit 5eca140
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
12 changes: 10 additions & 2 deletions src/backend/serial/u32/constants.rs
Expand Up @@ -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([
Expand Down
16 changes: 14 additions & 2 deletions src/backend/serial/u64/constants.rs
Expand Up @@ -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([
Expand Down
18 changes: 10 additions & 8 deletions src/montgomery.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -157,27 +157,29 @@ 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 */

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 */

Expand Down

0 comments on commit 5eca140

Please sign in to comment.