diff --git a/curve25519-dalek/src/backend/serial/u32/constants.rs b/curve25519-dalek/src/backend/serial/u32/constants.rs index ff6e4ec37..662ad8344 100644 --- a/curve25519-dalek/src/backend/serial/u32/constants.rs +++ b/curve25519-dalek/src/backend/serial/u32/constants.rs @@ -31,7 +31,6 @@ pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625::from_limbs([ ]); /// sqrt(-486664) -#[cfg(feature = "digest")] pub(crate) const ED25519_SQRTAM2: FieldElement2625 = FieldElement2625::from_limbs([ 54885894, 25242303, 55597453, 9067496, 51808079, 33312638, 25456129, 14121551, 54921728, 3972023, @@ -78,14 +77,12 @@ pub(crate) const SQRT_M1: FieldElement2625 = FieldElement2625::from_limbs([ pub(crate) const APLUS2_OVER_FOUR: FieldElement2625 = FieldElement2625::from_limbs([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]); -#[cfg(feature = "digest")] /// `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::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]); -#[cfg(feature = "digest")] /// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the /// Elligator map.) pub(crate) const MONTGOMERY_A_NEG: FieldElement2625 = FieldElement2625::from_limbs([ diff --git a/curve25519-dalek/src/backend/serial/u64/constants.rs b/curve25519-dalek/src/backend/serial/u64/constants.rs index cd27b8ff2..190c337a8 100644 --- a/curve25519-dalek/src/backend/serial/u64/constants.rs +++ b/curve25519-dalek/src/backend/serial/u64/constants.rs @@ -32,7 +32,6 @@ pub(crate) const MINUS_ONE: FieldElement51 = FieldElement51::from_limbs([ ]); /// sqrt(-486664) -#[cfg(feature = "digest")] pub(crate) const ED25519_SQRTAM2: FieldElement51 = FieldElement51::from_limbs([ 1693982333959686, 608509411481997, @@ -108,13 +107,11 @@ pub(crate) const SQRT_M1: FieldElement51 = FieldElement51::from_limbs([ pub(crate) const APLUS2_OVER_FOUR: FieldElement51 = FieldElement51::from_limbs([121666, 0, 0, 0, 0]); -#[cfg(feature = "digest")] /// `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::from_limbs([486662, 0, 0, 0, 0]); -#[cfg(feature = "digest")] /// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the /// Elligator map.) pub(crate) const MONTGOMERY_A_NEG: FieldElement51 = FieldElement51::from_limbs([ diff --git a/curve25519-dalek/src/constants.rs b/curve25519-dalek/src/constants.rs index 0a1162419..ff666890f 100644 --- a/curve25519-dalek/src/constants.rs +++ b/curve25519-dalek/src/constants.rs @@ -175,7 +175,6 @@ mod test { /// Test that ED25519_SQRTAM2 squared is MONTGOMERY_A_NEG - 2 #[test] - #[cfg(feature = "digest")] fn test_sqrt_a_minus_2() { let one = FieldElement::ONE; let a_minus_two = &(&constants::MONTGOMERY_A_NEG - &one) - &one; diff --git a/curve25519-dalek/src/edwards.rs b/curve25519-dalek/src/edwards.rs index f7d2e6906..32ddd0df1 100644 --- a/curve25519-dalek/src/edwards.rs +++ b/curve25519-dalek/src/edwards.rs @@ -273,7 +273,6 @@ impl TryFrom<&[u8]> for CompressedEdwardsY { // structs containing `EdwardsPoint`s and use Serde's derived // serializers to serialize those structures. -#[cfg(feature = "digest")] use constants::ED25519_SQRTAM2; #[cfg(feature = "serde")] use serde::de::Visitor; @@ -634,7 +633,6 @@ impl EdwardsPoint { .collect() } - #[cfg(feature = "digest")] // The function `map_to_curve` calculates an [EdwardsPoint] from a [FieldElement]. fn map_to_curve(fe: FieldElement) -> EdwardsPoint { let c1 = ED25519_SQRTAM2; @@ -763,6 +761,34 @@ impl EdwardsPoint { } } } + + /// Construct a `EdwardsPoint` from 64 bytes of data. + /// + /// If the input bytes are uniformly distributed, the resulting + /// point will be uniformly distributed over the group, and its + /// discrete log with respect to other points should be unknown. + /// + /// # Implementation + /// + /// This function splits the input array into two 32-byte halves, + /// takes the low 255 bits of each half mod p, applies the Elligator2 + /// map to each, and adds the results. + pub fn from_uniform_bytes(bytes: &[u8; 64]) -> EdwardsPoint { + // https://www.rfc-editor.org/rfc/rfc9380.html#section-3-4.1.2 + + let mut q = [0u8; 32]; + + q.copy_from_slice(&bytes[0..32]); + let q0 = FieldElement::from_bytes(&q); + let Q0 = Self::map_to_curve(q0); + + q.copy_from_slice(&bytes[32..64]); + let q1 = FieldElement::from_bytes(&q); + let Q1 = Self::map_to_curve(q1); + + let R = Q0 + Q1; + R.mul_by_cofactor() + } } // ------------------------------------------------------------------------ diff --git a/curve25519-dalek/src/montgomery.rs b/curve25519-dalek/src/montgomery.rs index 46a6b1272..2f5f7494d 100644 --- a/curve25519-dalek/src/montgomery.rs +++ b/curve25519-dalek/src/montgomery.rs @@ -54,9 +54,7 @@ use core::{ ops::{Mul, MulAssign}, }; -use crate::constants::APLUS2_OVER_FOUR; -#[cfg(feature = "digest")] -use crate::constants::{MONTGOMERY_A, MONTGOMERY_A_NEG, SQRT_M1}; +use crate::constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG, SQRT_M1}; use crate::edwards::{CompressedEdwardsY, EdwardsPoint}; use crate::field::FieldElement; use crate::scalar::{Scalar, clamp_integer}; @@ -71,11 +69,11 @@ use subtle::ConstantTimeEq; use zeroize::Zeroize; // We need the const 2^((p+3)/8) for elligator_encode. These defs are checked in tests::consts() -#[cfg(all(curve25519_dalek_bits = "32", feature = "digest"))] +#[cfg(curve25519_dalek_bits = "32")] const FE_C2: FieldElement = FieldElement::from_limbs([ 34513073, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, 31548777, 326685, 11406482, ]); -#[cfg(all(curve25519_dalek_bits = "64", feature = "digest"))] +#[cfg(curve25519_dalek_bits = "64")] const FE_C2: FieldElement = FieldElement::from_limbs([ 1718705420411057, 234908883556509, @@ -268,7 +266,6 @@ impl MontgomeryPoint { } } -#[cfg(feature = "digest")] /// Perform the Elligator2 mapping to a tuple `(xn, xd, yn, yd)` such that /// `(xn / xd, yn / yd)` is a point on curve25519. ///