Skip to content

Commit 73ab30f

Browse files
committed
fix 32-bit mode, faster reduce wide
Signed-off-by: Michael Lodder <redmike7@gmail.com>
1 parent bcedf26 commit 73ab30f

File tree

6 files changed

+68
-28
lines changed

6 files changed

+68
-28
lines changed

curve25519-dalek/src/backend/serial/fiat_u32/field.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,17 @@ impl FieldElement2625 {
198198
FieldElement2625::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
199199
/// Elligator2 constant for Edwards Curve
200200
pub const EDWARDS_MINUS_ELL_A: FieldElement2625 = FieldElement2625::from_limbs([
201-
0xfff892e7, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff,
202-
0xffffffff, 0x7ffff,
201+
0x03f892e7, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff,
202+
0x01ffffff, 0x03ffffff, 0x01ffffff,
203203
]);
204+
/// 1/sqrt(D) used for converting a montgomery point to edwards
205+
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement2625 = FieldElement2625::from_limbs([
206+
0x03457e06, 0x01812abf, 0x0350598d, 0x08a5be8, 0x0316874f, 0x01fc4f7e, 0x01846e01,
207+
0x00d77a4f, 0x03460a00, 0x003c9bb7,
208+
]);
209+
/// 2^192
210+
pub const F_2_192: FieldElement2625 =
211+
FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0x2000, 0, 0]);
204212
/// The scalar \\( 0 \\).
205213
pub const ZERO: FieldElement2625 = FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
206214
/// The scalar \\( 1 \\).

curve25519-dalek/src/backend/serial/fiat_u64/field.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ impl FieldElement51 {
182182
0x7ffffffffffff,
183183
0x7ffffffffffff,
184184
]);
185+
/// 1/sqrt(D) used for converting a montgomery point to edwards
186+
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement51 = FieldElement51::from_limbs([
187+
0x604aaff457e06,
188+
0x2296fa350598d,
189+
0x7f13dfb16874f,
190+
0x35de93d846e01,
191+
0x0f26edf460a00,
192+
]);
193+
/// 2^192
194+
pub const F_2_192: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0x0008000000000, 0]);
185195
/// The scalar \\( 0 \\).
186196
pub const ZERO: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0, 0]);
187197
/// The scalar \\( 1 \\).

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,17 @@ impl FieldElement2625 {
293293
FieldElement2625::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
294294
/// Elligator2 constant for Edwards Curve
295295
pub const EDWARDS_MINUS_ELL_A: FieldElement2625 = FieldElement2625::from_limbs([
296-
0xfff892e7, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff,
297-
0xffffffff, 0x7ffff,
296+
0x03f892e7, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff,
297+
0x01ffffff, 0x03ffffff, 0x01ffffff,
298298
]);
299+
/// 1/sqrt(D) used for converting a montgomery point to edwards
300+
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement2625 = FieldElement2625::from_limbs([
301+
0x03457e06, 0x01812abf, 0x0350598d, 0x08a5be8, 0x0316874f, 0x01fc4f7e, 0x01846e01,
302+
0x00d77a4f, 0x03460a00, 0x003c9bb7,
303+
]);
304+
/// 2^192
305+
pub const F_2_192: FieldElement2625 =
306+
FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0x2000, 0, 0]);
299307
/// The scalar \\( 0 \\).
300308
pub const ZERO: FieldElement2625 = FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
301309
/// The scalar \\( 1 \\).

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,16 @@ impl FieldElement51 {
269269
0x7ffffffffffff,
270270
0x7ffffffffffff,
271271
]);
272+
/// 1/sqrt(D) used for converting a montgomery point to edwards
273+
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement51 = FieldElement51::from_limbs([
274+
0x604aaff457e06,
275+
0x2296fa350598d,
276+
0x7f13dfb16874f,
277+
0x35de93d846e01,
278+
0x0f26edf460a00,
279+
]);
280+
/// 2^192
281+
pub const F_2_192: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0x0008000000000, 0]);
272282
/// The scalar \\( 0 \\).
273283
pub const ZERO: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0, 0]);
274284
/// The scalar \\( 1 \\).

curve25519-dalek/src/edwards.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -613,30 +613,16 @@ impl EdwardsPoint {
613613
where
614614
X: for<'a> elliptic_curve::hash2curve::ExpandMsg<'a>,
615615
{
616-
use elliptic_curve::{
617-
bigint::{ArrayEncoding, Encoding, NonZero, U384},
618-
hash2curve::Expander,
619-
};
616+
use elliptic_curve::hash2curve::Expander;
620617

621618
let dst = [dst];
622619
let mut random_bytes = [0u8; 96];
623620
let mut expander =
624621
X::expand_message(&[msg], &dst, random_bytes.len()).expect("expand_message failed");
625622
expander.fill_bytes(&mut random_bytes);
626623

627-
let p = NonZero::new(U384::from_be_hex("000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed")).expect("NonZero::new failed");
628-
let u0 = U384::from_be_bytes(
629-
<[u8; 48]>::try_from(&random_bytes[..48]).expect("try_from failed"),
630-
) % p;
631-
let u1 = U384::from_be_bytes(
632-
<[u8; 48]>::try_from(&random_bytes[48..]).expect("try_from failed"),
633-
) % p;
634-
635-
let mut arr = [0u8; 32];
636-
arr.copy_from_slice(&u0.to_le_byte_array()[..32]);
637-
let u0 = FieldElement::from_bytes(&arr);
638-
arr.copy_from_slice(&u1.to_le_byte_array()[..32]);
639-
let u1 = FieldElement::from_bytes(&arr);
624+
let u0 = FieldElement::from_xmd_bytes_mod_order(&random_bytes[..48]);
625+
let u1 = FieldElement::from_xmd_bytes_mod_order(&random_bytes[48..]);
640626

641627
let q0 = map_to_edwards(u0);
642628
let q1 = map_to_edwards(u1);
@@ -674,11 +660,7 @@ fn elligator_encode(e: FieldElement) -> (FieldElement, FieldElement) {
674660

675661
#[cfg(feature = "group")]
676662
fn montgomery_to_edwards(u: FieldElement, v: FieldElement) -> (FieldElement, FieldElement) {
677-
let inv_sqr_d = FieldElement::from_bytes(&[
678-
6, 126, 69, 255, 170, 4, 110, 204, 130, 26, 125, 75, 209, 211, 161, 197, 126, 79, 252, 3,
679-
220, 8, 123, 210, 187, 6, 160, 96, 244, 237, 38, 15,
680-
]);
681-
let x = &(&v.invert() * &u) * &inv_sqr_d;
663+
let x = &(&v.invert() * &u) * &FieldElement::MONTGOMERY_TO_EDWARDS_INV_SQRT_D;
682664
let u1 = &u - &FieldElement::ONE;
683665
let u2 = &u + &FieldElement::ONE;
684666
let y = &u1 * &u2.invert();
@@ -687,12 +669,11 @@ fn montgomery_to_edwards(u: FieldElement, v: FieldElement) -> (FieldElement, Fie
687669

688670
#[cfg(feature = "group")]
689671
fn affine_to_edwards(x: FieldElement, y: FieldElement) -> EdwardsPoint {
690-
let t = &x * &y;
691672
EdwardsPoint {
692673
X: x,
693674
Y: y,
694675
Z: FieldElement::ONE,
695-
T: t,
676+
T: &x * &y,
696677
}
697678
}
698679

curve25519-dalek/src/field.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,29 @@ impl FieldElement {
305305
pub(crate) fn invsqrt(&self) -> (Choice, FieldElement) {
306306
FieldElement::sqrt_ratio_i(&FieldElement::ONE, self)
307307
}
308+
309+
/// Handle 48 bytes like a big integer and reduce mod order
310+
/// i.e. big_int(48 bytes) % p
311+
/// but without using any reduce methods
312+
pub(crate) fn from_xmd_bytes_mod_order(bytes: &[u8]) -> FieldElement {
313+
assert_eq!(bytes.len(), 48);
314+
// XMD output is expected to be big endian but FieldElement51
315+
// expects bytes to be little endian.
316+
// Break the array in half with the 1st half as the hi value
317+
// and the 2nd half as the lo value
318+
let mut arr = [0u8; 32];
319+
for i in 0..24 {
320+
arr[i] = bytes[23-i];
321+
}
322+
let mut hi = FieldElement::from_bytes(&arr);
323+
for i in 0..24 {
324+
arr[i] = bytes[47-i];
325+
}
326+
let lo = FieldElement::from_bytes(&arr);
327+
hi *= &FieldElement::F_2_192;
328+
&hi + &lo
329+
}
330+
308331
}
309332

310333
#[cfg(test)]

0 commit comments

Comments
 (0)