Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trivial cleanups to Elligator2 encoding #351

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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