Skip to content

Commit

Permalink
fix 32-bit mode, faster reduce wide
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Lodder <redmike7@gmail.com>
  • Loading branch information
mikelodder7 committed Nov 1, 2023
1 parent 249d6a6 commit 3e80b45
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 28 deletions.
12 changes: 10 additions & 2 deletions curve25519-dalek/src/backend/serial/fiat_u32/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,17 @@ impl FieldElement2625 {
FieldElement2625::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// Elligator2 constant for Edwards Curve
pub const EDWARDS_MINUS_ELL_A: FieldElement2625 = FieldElement2625::from_limbs([
0xfff892e7, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff,
0xffffffff, 0x7ffff,
0x03f892e7, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff,
0x01ffffff, 0x03ffffff, 0x01ffffff,
]);
/// 1/sqrt(D) used for converting a montgomery point to edwards
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement2625 = FieldElement2625::from_limbs([
0x03457e06, 0x01812abf, 0x0350598d, 0x08a5be8, 0x0316874f, 0x01fc4f7e, 0x01846e01,
0x00d77a4f, 0x03460a00, 0x003c9bb7,
]);
/// 2^192
pub const F_2_192: FieldElement2625 =
FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0x2000, 0, 0]);
/// The scalar \\( 0 \\).
pub const ZERO: FieldElement2625 = FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// The scalar \\( 1 \\).
Expand Down
10 changes: 10 additions & 0 deletions curve25519-dalek/src/backend/serial/fiat_u64/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ impl FieldElement51 {
0x7ffffffffffff,
0x7ffffffffffff,
]);
/// 1/sqrt(D) used for converting a montgomery point to edwards
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement51 = FieldElement51::from_limbs([
0x604aaff457e06,
0x2296fa350598d,
0x7f13dfb16874f,
0x35de93d846e01,
0x0f26edf460a00,
]);
/// 2^192
pub const F_2_192: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0x0008000000000, 0]);
/// The scalar \\( 0 \\).
pub const ZERO: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0, 0]);
/// The scalar \\( 1 \\).
Expand Down
12 changes: 10 additions & 2 deletions curve25519-dalek/src/backend/serial/u32/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,17 @@ impl FieldElement2625 {
FieldElement2625::from_limbs([486662, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// Elligator2 constant for Edwards Curve
pub const EDWARDS_MINUS_ELL_A: FieldElement2625 = FieldElement2625::from_limbs([
0xfff892e7, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff, 0xffffffff, 0x7ffff,
0xffffffff, 0x7ffff,
0x03f892e7, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff, 0x01ffffff, 0x03ffffff,
0x01ffffff, 0x03ffffff, 0x01ffffff,
]);
/// 1/sqrt(D) used for converting a montgomery point to edwards
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement2625 = FieldElement2625::from_limbs([
0x03457e06, 0x01812abf, 0x0350598d, 0x08a5be8, 0x0316874f, 0x01fc4f7e, 0x01846e01,
0x00d77a4f, 0x03460a00, 0x003c9bb7,
]);
/// 2^192
pub const F_2_192: FieldElement2625 =
FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0x2000, 0, 0]);
/// The scalar \\( 0 \\).
pub const ZERO: FieldElement2625 = FieldElement2625::from_limbs([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// The scalar \\( 1 \\).
Expand Down
10 changes: 10 additions & 0 deletions curve25519-dalek/src/backend/serial/u64/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,16 @@ impl FieldElement51 {
0x7ffffffffffff,
0x7ffffffffffff,
]);
/// 1/sqrt(D) used for converting a montgomery point to edwards
pub const MONTGOMERY_TO_EDWARDS_INV_SQRT_D: FieldElement51 = FieldElement51::from_limbs([
0x604aaff457e06,
0x2296fa350598d,
0x7f13dfb16874f,
0x35de93d846e01,
0x0f26edf460a00,
]);
/// 2^192
pub const F_2_192: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0x0008000000000, 0]);
/// The scalar \\( 0 \\).
pub const ZERO: FieldElement51 = FieldElement51::from_limbs([0, 0, 0, 0, 0]);
/// The scalar \\( 1 \\).
Expand Down
29 changes: 5 additions & 24 deletions curve25519-dalek/src/edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,30 +613,16 @@ impl EdwardsPoint {
where
X: for<'a> elliptic_curve::hash2curve::ExpandMsg<'a>,
{
use elliptic_curve::{
bigint::{ArrayEncoding, Encoding, NonZero, U384},
hash2curve::Expander,
};
use elliptic_curve::hash2curve::Expander;

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

let p = NonZero::new(U384::from_be_hex("000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed")).expect("NonZero::new failed");
let u0 = U384::from_be_bytes(
<[u8; 48]>::try_from(&random_bytes[..48]).expect("try_from failed"),
) % p;
let u1 = U384::from_be_bytes(
<[u8; 48]>::try_from(&random_bytes[48..]).expect("try_from failed"),
) % p;

let mut arr = [0u8; 32];
arr.copy_from_slice(&u0.to_le_byte_array()[..32]);
let u0 = FieldElement::from_bytes(&arr);
arr.copy_from_slice(&u1.to_le_byte_array()[..32]);
let u1 = FieldElement::from_bytes(&arr);
let u0 = FieldElement::from_xmd_bytes_mod_order(&random_bytes[..48]);
let u1 = FieldElement::from_xmd_bytes_mod_order(&random_bytes[48..]);

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

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

#[cfg(feature = "group")]
fn affine_to_edwards(x: FieldElement, y: FieldElement) -> EdwardsPoint {
let t = &x * &y;
EdwardsPoint {
X: x,
Y: y,
Z: FieldElement::ONE,
T: t,
T: &x * &y,
}
}

Expand Down
23 changes: 23 additions & 0 deletions curve25519-dalek/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,29 @@ impl FieldElement {
pub(crate) fn invsqrt(&self) -> (Choice, FieldElement) {
FieldElement::sqrt_ratio_i(&FieldElement::ONE, self)
}

/// Handle 48 bytes like a big integer and reduce mod order
/// i.e. big_int(48 bytes) % p
/// but without using any reduce methods
pub(crate) fn from_xmd_bytes_mod_order(bytes: &[u8]) -> FieldElement {
assert_eq!(bytes.len(), 48);
// XMD output is expected to be big endian but FieldElement51
// expects bytes to be little endian.
// Break the array in half with the 1st half as the hi value
// and the 2nd half as the lo value
let mut arr = [0u8; 32];
for i in 0..24 {
arr[i] = bytes[23-i];
}
let mut hi = FieldElement::from_bytes(&arr);
for i in 0..24 {
arr[i] = bytes[47-i];
}
let lo = FieldElement::from_bytes(&arr);
hi *= &FieldElement::F_2_192;
&hi + &lo
}

}

#[cfg(test)]
Expand Down

0 comments on commit 3e80b45

Please sign in to comment.