Skip to content

Commit 1feb427

Browse files
committed
Add EdwardsPoint::from_uniform_bytes()
1 parent c3a82a8 commit 1feb427

File tree

5 files changed

+31
-15
lines changed

5 files changed

+31
-15
lines changed

curve25519-dalek/src/backend/serial/u32/constants.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625::from_limbs([
3131
]);
3232

3333
/// sqrt(-486664)
34-
#[cfg(feature = "digest")]
3534
pub(crate) const ED25519_SQRTAM2: FieldElement2625 = FieldElement2625::from_limbs([
3635
54885894, 25242303, 55597453, 9067496, 51808079, 33312638, 25456129, 14121551, 54921728,
3736
3972023,
@@ -78,14 +77,12 @@ pub(crate) const SQRT_M1: FieldElement2625 = FieldElement2625::from_limbs([
7877
pub(crate) const APLUS2_OVER_FOUR: FieldElement2625 =
7978
FieldElement2625::from_limbs([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
8079

81-
#[cfg(feature = "digest")]
8280
/// `MONTGOMERY_A` is equal to 486662, which is a constant of the curve equation
8381
/// for Curve25519 in its Montgomery form. (This is used internally within the
8482
/// Elligator map.)
8583
pub(crate) const MONTGOMERY_A: FieldElement2625 =
8684
FieldElement2625::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
8785

88-
#[cfg(feature = "digest")]
8986
/// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the
9087
/// Elligator map.)
9188
pub(crate) const MONTGOMERY_A_NEG: FieldElement2625 = FieldElement2625::from_limbs([

curve25519-dalek/src/backend/serial/u64/constants.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub(crate) const MINUS_ONE: FieldElement51 = FieldElement51::from_limbs([
3232
]);
3333

3434
/// sqrt(-486664)
35-
#[cfg(feature = "digest")]
3635
pub(crate) const ED25519_SQRTAM2: FieldElement51 = FieldElement51::from_limbs([
3736
1693982333959686,
3837
608509411481997,
@@ -108,13 +107,11 @@ pub(crate) const SQRT_M1: FieldElement51 = FieldElement51::from_limbs([
108107
pub(crate) const APLUS2_OVER_FOUR: FieldElement51 =
109108
FieldElement51::from_limbs([121666, 0, 0, 0, 0]);
110109

111-
#[cfg(feature = "digest")]
112110
/// `MONTGOMERY_A` is equal to 486662, which is a constant of the curve equation
113111
/// for Curve25519 in its Montgomery form. (This is used internally within the
114112
/// Elligator map.)
115113
pub(crate) const MONTGOMERY_A: FieldElement51 = FieldElement51::from_limbs([486662, 0, 0, 0, 0]);
116114

117-
#[cfg(feature = "digest")]
118115
/// `MONTGOMERY_A_NEG` is equal to -486662. (This is used internally within the
119116
/// Elligator map.)
120117
pub(crate) const MONTGOMERY_A_NEG: FieldElement51 = FieldElement51::from_limbs([

curve25519-dalek/src/constants.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ mod test {
175175

176176
/// Test that ED25519_SQRTAM2 squared is MONTGOMERY_A_NEG - 2
177177
#[test]
178-
#[cfg(feature = "digest")]
179178
fn test_sqrt_a_minus_2() {
180179
let one = FieldElement::ONE;
181180
let a_minus_two = &(&constants::MONTGOMERY_A_NEG - &one) - &one;

curve25519-dalek/src/edwards.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ impl TryFrom<&[u8]> for CompressedEdwardsY {
273273
// structs containing `EdwardsPoint`s and use Serde's derived
274274
// serializers to serialize those structures.
275275

276-
#[cfg(feature = "digest")]
277276
use constants::ED25519_SQRTAM2;
278277
#[cfg(feature = "serde")]
279278
use serde::de::Visitor;
@@ -634,7 +633,6 @@ impl EdwardsPoint {
634633
.collect()
635634
}
636635

637-
#[cfg(feature = "digest")]
638636
// The function `map_to_curve` calculates an [EdwardsPoint] from a [FieldElement].
639637
fn map_to_curve(fe: FieldElement) -> EdwardsPoint {
640638
let c1 = ED25519_SQRTAM2;
@@ -763,6 +761,34 @@ impl EdwardsPoint {
763761
}
764762
}
765763
}
764+
765+
/// Construct a `EdwardsPoint` from 64 bytes of data.
766+
///
767+
/// If the input bytes are uniformly distributed, the resulting
768+
/// point will be uniformly distributed over the group, and its
769+
/// discrete log with respect to other points should be unknown.
770+
///
771+
/// # Implementation
772+
///
773+
/// This function splits the input array into two 32-byte halves,
774+
/// takes the low 255 bits of each half mod p, applies the Elligator2
775+
/// map to each, and adds the results.
776+
pub fn from_uniform_bytes(bytes: &[u8; 64]) -> EdwardsPoint {
777+
// https://www.rfc-editor.org/rfc/rfc9380.html#section-3-4.1.2
778+
779+
let mut q = [0u8; 32];
780+
781+
q.copy_from_slice(&bytes[0..32]);
782+
let q0 = FieldElement::from_bytes(&q);
783+
let Q0 = Self::map_to_curve(q0);
784+
785+
q.copy_from_slice(&bytes[32..64]);
786+
let q1 = FieldElement::from_bytes(&q);
787+
let Q1 = Self::map_to_curve(q1);
788+
789+
let R = Q0 + Q1;
790+
R.mul_by_cofactor()
791+
}
766792
}
767793

768794
// ------------------------------------------------------------------------

curve25519-dalek/src/montgomery.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ use core::{
5454
ops::{Mul, MulAssign},
5555
};
5656

57-
use crate::constants::APLUS2_OVER_FOUR;
58-
#[cfg(feature = "digest")]
59-
use crate::constants::{MONTGOMERY_A, MONTGOMERY_A_NEG, SQRT_M1};
57+
use crate::constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG, SQRT_M1};
6058
use crate::edwards::{CompressedEdwardsY, EdwardsPoint};
6159
use crate::field::FieldElement;
6260
use crate::scalar::{Scalar, clamp_integer};
@@ -71,11 +69,11 @@ use subtle::ConstantTimeEq;
7169
use zeroize::Zeroize;
7270

7371
// We need the const 2^((p+3)/8) for elligator_encode. These defs are checked in tests::consts()
74-
#[cfg(all(curve25519_dalek_bits = "32", feature = "digest"))]
72+
#[cfg(curve25519_dalek_bits = "32")]
7573
const FE_C2: FieldElement = FieldElement::from_limbs([
7674
34513073, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, 31548777, 326685, 11406482,
7775
]);
78-
#[cfg(all(curve25519_dalek_bits = "64", feature = "digest"))]
76+
#[cfg(curve25519_dalek_bits = "64")]
7977
const FE_C2: FieldElement = FieldElement::from_limbs([
8078
1718705420411057,
8179
234908883556509,
@@ -268,7 +266,6 @@ impl MontgomeryPoint {
268266
}
269267
}
270268

271-
#[cfg(feature = "digest")]
272269
/// Perform the Elligator2 mapping to a tuple `(xn, xd, yn, yd)` such that
273270
/// `(xn / xd, yn / yd)` is a point on curve25519.
274271
///

0 commit comments

Comments
 (0)