Merge remote-tracking branch 'chain/feature/prune-constants' into develop

This commit is contained in:
Isis Lovecruft 2017-11-09 01:48:21 +00:00
commit 28c1576a15
Failed to extract signature
8 changed files with 98 additions and 194 deletions

View file

@ -11,11 +11,22 @@
//! This module contains various constants (such as curve parameters //! This module contains various constants (such as curve parameters
//! and useful field elements like `sqrt(-1)`), as well as //! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points. //! lookup tables of pre-computed points.
//!
//! Most of the constants are given with
//! `LONG_DESCRIPTIVE_UPPER_CASE_NAMES`, but they can be brought into
//! scope using a `let` binding:
//!
//! ```
//! use curve25519_dalek::constants;
//! use curve25519_dalek::edwards::IsIdentity;
//!
//! let B = &constants::RISTRETTO_BASEPOINT_TABLE;
//! let l = &constants::BASEPOINT_ORDER;
//!
//! let A = l * B;
//! assert!(A.is_identity());
//! ```
#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(missing_docs)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
use edwards::CompressedEdwardsY; use edwards::CompressedEdwardsY;
@ -28,20 +39,6 @@ pub use constants_64bit::*;
#[cfg(not(feature="radix_51"))] #[cfg(not(feature="radix_51"))]
pub use constants_32bit::*; pub use constants_32bit::*;
/// (p-1)/2, in little-endian bytes.
pub const HALF_P_MINUS_1_BYTES: [u8; 32] =
[0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f];
/// `HALF_Q_MINUS_1_BYTES` is (2^255-20)/2 expressed in little endian form.
pub const HALF_Q_MINUS_1_BYTES: [u8; 32] = [ // halfQMinus1Bytes
0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, ];
/// Basepoint has y = 4/5. /// Basepoint has y = 4/5.
/// ///
/// Generated with Sage: these are the bytes of 4/5 in 𝔽_p. The /// Generated with Sage: these are the bytes of 4/5 in 𝔽_p. The
@ -64,26 +61,30 @@ pub const BASE_COMPRESSED_MONTGOMERY: CompressedMontgomeryU =
/// `_TABLE`, which provides fast scalar multiplication. /// `_TABLE`, which provides fast scalar multiplication.
pub const RISTRETTO_BASEPOINT_POINT: RistrettoPoint = RistrettoPoint(ED25519_BASEPOINT_POINT); pub const RISTRETTO_BASEPOINT_POINT: RistrettoPoint = RistrettoPoint(ED25519_BASEPOINT_POINT);
/// `l` is the order of base point, i.e. 2^252 + /// `BASEPOINT_ORDER` is the order of base point, i.e. `l = 2^252 +
/// 27742317777372353535851937790883648493, in little-endian form /// 27742317777372353535851937790883648493`, in little-endian bytes.
pub const l: Scalar = Scalar([ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, pub const BASEPOINT_ORDER: Scalar = Scalar([
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ]); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
]);
/// `l_minus_1` is the order of base point minus one, i.e. 2^252 + /// `BASEPOINT_ORDER_MINUS_1` is the order of base point minus one, i.e. `l-1`, in little-endian bytes.
/// 27742317777372353535851937790883648493 - 1, in little-endian form pub const BASEPOINT_ORDER_MINUS_1: Scalar = Scalar([
pub const l_minus_1: Scalar = Scalar([ 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ]); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
]);
/// `lminus1` is the order of base point minus two, i.e. 2^252 + /// `BASEPOINT_ORDER_MINUS_2` is the order of base point minus two, i.e. `l-2`, in little-endian bytes.
/// 27742317777372353535851937790883648493 - 2, in little-endian form pub const BASEPOINT_ORDER_MINUS_2: Scalar = Scalar([
pub const l_minus_2: Scalar = Scalar([ 0xeb, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xeb, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ]); 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
]);
/// The Ed25519 basepoint, as a RistrettoPoint /// The Ed25519 basepoint, as a RistrettoPoint
pub const RISTRETTO_BASEPOINT_TABLE: RistrettoBasepointTable pub const RISTRETTO_BASEPOINT_TABLE: RistrettoBasepointTable
@ -123,13 +124,6 @@ mod test {
} }
} }
#[test]
fn test_half() {
let one = FieldElement::one();
let two = &one + &one;
assert_eq!(one, &two * &constants::HALF);
}
/// Test that the constant for sqrt(-486664) really is a square /// Test that the constant for sqrt(-486664) really is a square
/// root of -486664. /// root of -486664.
#[test] #[test]
@ -155,27 +149,22 @@ mod test {
} }
#[test] #[test]
/// Test that SQRT_M1 and MSQRT_M1 are square roots of -1 /// Test that SQRT_M1 is a square root of -1
fn test_sqrt_minus_one() { fn test_sqrt_minus_one() {
let minus_one = FieldElement::minus_one(); let minus_one = FieldElement::minus_one();
let sqrt_m1_sq = &constants::SQRT_M1 * &constants::SQRT_M1; let sqrt_m1_sq = &constants::SQRT_M1 * &constants::SQRT_M1;
let msqrt_m1_sq = &constants::MSQRT_M1 * &constants::MSQRT_M1;
assert_eq!(minus_one, sqrt_m1_sq); assert_eq!(minus_one, sqrt_m1_sq);
assert_eq!(minus_one, msqrt_m1_sq);
} }
#[test] #[test]
fn test_sqrt_constants_sign() { fn test_sqrt_constants_sign() {
let one = FieldElement::one();
let minus_one = FieldElement::minus_one(); let minus_one = FieldElement::minus_one();
let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt(); let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt();
assert_eq!(was_nonzero_square, 1u8); assert_eq!(was_nonzero_square, 1u8);
let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1; let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1;
let sign_test_msqrt = &invsqrt_m1 * &constants::MSQRT_M1;
// XXX it seems we have flipped the sign relative to // XXX it seems we have flipped the sign relative to
// the invsqrt function? // the invsqrt function?
assert_eq!(sign_test_sqrt, minus_one); assert_eq!(sign_test_sqrt, minus_one);
assert_eq!(sign_test_msqrt, one);
} }
/// Test that d = -121665/121666 /// Test that d = -121665/121666
@ -187,8 +176,8 @@ mod test {
let b = FieldElement32([ 121666,0,0,0,0,0,0,0,0,0]); let b = FieldElement32([ 121666,0,0,0,0,0,0,0,0,0]);
let d = &a * &b.invert(); let d = &a * &b.invert();
let d2 = &d + &d; let d2 = &d + &d;
assert_eq!(d, constants::d); assert_eq!(d, constants::EDWARDS_D);
assert_eq!(d2, constants::d2); assert_eq!(d2, constants::EDWARDS_D2);
} }
/// Test that d = -121665/121666 /// Test that d = -121665/121666
@ -200,35 +189,16 @@ mod test {
let b = FieldElement64([121666,0,0,0,0]); let b = FieldElement64([121666,0,0,0,0]);
let d = &a * &b.invert(); let d = &a * &b.invert();
let d2 = &d + &d; let d2 = &d + &d;
assert_eq!(d, constants::d); assert_eq!(d, constants::EDWARDS_D);
assert_eq!(d2, constants::d2); assert_eq!(d2, constants::EDWARDS_D2);
}
#[test]
fn test_d4() {
let mut four = FieldElement::zero();
// XXX should have a way to create small field elements
four.0[0] = 4;
assert_eq!(&constants::d * &four, constants::d4);
} }
#[test] #[test]
fn test_sqrt_ad_minus_one() { fn test_sqrt_ad_minus_one() {
let a = FieldElement::minus_one(); let a = FieldElement::minus_one();
let ad_minus_one = &(&a * &constants::d) + &a; let ad_minus_one = &(&a * &constants::EDWARDS_D) + &a;
let should_be_ad_minus_one = constants::sqrt_ad_minus_one.square(); let should_be_ad_minus_one = constants::SQRT_AD_MINUS_ONE.square();
assert_eq!(should_be_ad_minus_one, ad_minus_one); assert_eq!(should_be_ad_minus_one, ad_minus_one);
} }
#[test]
fn test_a_minus_d() {
let a = FieldElement::minus_one();
let a_minus_d = &a - &constants::d;
assert_eq!(a_minus_d, constants::a_minus_d);
let (_, invsqrt_a_minus_d) = constants::a_minus_d.invsqrt();
assert_eq!(invsqrt_a_minus_d, constants::invsqrt_a_minus_d);
let inv_a_minus_d = invsqrt_a_minus_d.square();
assert_eq!(inv_a_minus_d, constants::inv_a_minus_d);
assert_eq!(&inv_a_minus_d * &a_minus_d, FieldElement::one());
}
} }

View file

@ -12,10 +12,6 @@
//! and useful field elements like `sqrt(-1)`), as well as //! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points. //! lookup tables of pre-computed points.
#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(missing_docs)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
use field_32bit::FieldElement32; use field_32bit::FieldElement32;
@ -23,85 +19,47 @@ use edwards::ExtendedPoint;
use edwards::AffineNielsPoint; use edwards::AffineNielsPoint;
use edwards::EdwardsBasepointTable; use edwards::EdwardsBasepointTable;
pub const d: FieldElement32 = FieldElement32([ /// Edwards `d` value, equal to `-121665/121666 mod p`.
pub(crate) const EDWARDS_D: FieldElement32 = FieldElement32([
-10913610, 13857413, -15372611, 6949391, 114729, -10913610, 13857413, -15372611, 6949391, 114729,
-8787816, -6275908, -3247719, -18696448, -12055116, ]); -8787816, -6275908, -3247719, -18696448, -12055116, ]);
pub const d2: FieldElement32 = FieldElement32([ /// Edwards `2*d` value, equal to `2*(-121665/121666) mod p`.
pub(crate) const EDWARDS_D2: FieldElement32 = FieldElement32([
-21827239, -5839606, -30745221, 13898782, 229458, -21827239, -5839606, -30745221, 13898782, 229458,
15978800, -12551817, -6495438, 29715968, 9444199, ]); 15978800, -12551817, -6495438, 29715968, 9444199, ]);
pub const d4: FieldElement32 = FieldElement32([ /// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
23454405, -11679213, 5618422, -5756869, 458917, pub(crate) const SQRT_AD_MINUS_ONE: FieldElement32 = FieldElement32([
-1596832, -25103633, -12990876, -7676928, -14666033 ]);
pub const a_minus_d: FieldElement32 = FieldElement32([
10913609, -13857413, 15372611, -6949391, -114729,
8787816, 6275908, 3247719, 18696448, 12055116, ]);
pub const sqrt_ad_minus_one: FieldElement32 = FieldElement32([
24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639 24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639
]); ]);
pub const invsqrt_a_minus_d: FieldElement32 = FieldElement32([ /// `= 1/sqrt(a-d)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
pub(crate) const INVSQRT_A_MINUS_D: FieldElement32 = FieldElement32([
6111485, 4156064, -27798727, 12243468, -25904040, 6111485, 4156064, -27798727, 12243468, -25904040,
120897, 20826367, -7060776, 6093568, -1986012 120897, 20826367, -7060776, 6093568, -1986012
]); ]);
#[cfg(not(feature="radix_51"))]
pub const inv_a_minus_d: FieldElement32 = FieldElement32([
-121666, 0, 0, 0, 0, 0, 0, 0, 0, 0
]);
/// (p-1)/2, in little-endian bytes.
pub const HALF_P_MINUS_1_BYTES: [u8; 32] =
[0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f];
/// Precomputed value of one of the square roots of -1 (mod p) /// Precomputed value of one of the square roots of -1 (mod p)
pub const SQRT_M1: FieldElement32 = FieldElement32([ pub(crate) const SQRT_M1: FieldElement32 = FieldElement32([
-32595792, -7943725, 9377950, 3500415, 12389472, -32595792, -7943725, 9377950, 3500415, 12389472,
-272473, -25146209, -2005654, 326686, 11406482, ]); -272473, -25146209, -2005654, 326686, 11406482, ]);
/// Precomputed value of the other square root of -1 (mod p),
/// i.e., `MSQRT_M1 = -SQRT_M1`.
pub const MSQRT_M1: FieldElement32 = FieldElement32([
32595792, 7943725, -9377950, -3500415, -12389472,
272473, 25146209, 2005654, -326686, -11406482, ]);
/// Precomputed value of 1/2 (mod p).
pub const HALF: FieldElement32 = FieldElement32([
10, 0, 0, 0, 0, 0, 0, 0, 0, -16777216, ]);
/// In Montgomery form y² = x³+Ax²+x, Curve25519 has A=486662. /// In Montgomery form y² = x³+Ax²+x, Curve25519 has A=486662.
pub const A: FieldElement32 = FieldElement32([ pub(crate) const MONTGOMERY_A: FieldElement32 = FieldElement32([
486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]); 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]);
/// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.)
pub const APLUS2_OVER_FOUR: FieldElement32 = FieldElement32([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]); pub(crate) const APLUS2_OVER_FOUR: FieldElement32 = FieldElement32([121666, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// `SQRT_MINUS_A` is sqrt(-486662)
// XXX I think that this was used in Adam's code for his elligator
// implementation, but that should maybe be using sqrt(-486664)
// instead...? - hdevalence
pub const SQRT_MINUS_A: FieldElement32 = FieldElement32([ // sqrtMinusA
12222970, 8312128, 11511410, -9067497, 15300785,
241793, -25456130, -14121551, 12187136, -3972024, ]);
/// `SQRT_MINUS_APLUS2` is sqrt(-486664) /// `SQRT_MINUS_APLUS2` is sqrt(-486664)
pub const SQRT_MINUS_APLUS2: FieldElement32 = FieldElement32([ pub(crate) const SQRT_MINUS_APLUS2: FieldElement32 = FieldElement32([
-12222970, -8312128, -11511410, 9067497, -15300785, -12222970, -8312128, -11511410, 9067497, -15300785,
-241793, 25456130, 14121551, -12187136, 3972024]); -241793, 25456130, 14121551, -12187136, 3972024]);
/// `SQRT_MINUS_HALF` is sqrt(-1/2) /// The Ed25519 basepoint has y = 4/5. This is called `_POINT` to
pub const SQRT_MINUS_HALF: FieldElement32 = FieldElement32([ // sqrtMinusHalf /// distinguish it from `_TABLE`, which should be used for scalar
-17256545, 3971863, 28865457, -1750208, 27359696, /// multiplication (it's much faster).
-16640980, 12573105, 1002827, -163343, 11073975, ]);
/// Basepoint has y = 4/5. This is called `_POINT` to distinguish it from `_TABLE`, which should
/// be used for scalar multiplication (it's much faster).
pub const ED25519_BASEPOINT_POINT: ExtendedPoint = ExtendedPoint{ pub const ED25519_BASEPOINT_POINT: ExtendedPoint = ExtendedPoint{
X: FieldElement32([-14297830, -7645148, 16144683, -16471763, 27570974, -2696100, -26142465, 8378389, 20764389, 8758491]), X: FieldElement32([-14297830, -7645148, 16144683, -16471763, 27570974, -2696100, -26142465, 8378389, 20764389, 8758491]),
Y: FieldElement32([-26843541, -6710886, 13421773, -13421773, 26843546, 6710886, -13421773, 13421773, -26843546, -6710886]), Y: FieldElement32([-26843541, -6710886, 13421773, -13421773, 26843546, 6710886, -13421773, 13421773, -26843546, -6710886]),
@ -167,7 +125,8 @@ pub const EIGHT_TORSION: [ExtendedPoint; 8] = [
}, },
]; ];
pub const bi: [AffineNielsPoint; 8] = [ /// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B]`.
pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: [AffineNielsPoint; 8] = [
AffineNielsPoint{ AffineNielsPoint{
y_plus_x: FieldElement32([25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605]), y_plus_x: FieldElement32([25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605]),
y_minus_x: FieldElement32([-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378]), y_minus_x: FieldElement32([-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378]),

View file

@ -12,10 +12,6 @@
//! and useful field elements like `sqrt(-1)`), as well as //! and useful field elements like `sqrt(-1)`), as well as
//! lookup tables of pre-computed points. //! lookup tables of pre-computed points.
#![allow(dead_code)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(missing_docs)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
use field_64bit::FieldElement64; use field_64bit::FieldElement64;
@ -23,58 +19,37 @@ use edwards::ExtendedPoint;
use edwards::AffineNielsPoint; use edwards::AffineNielsPoint;
use edwards::EdwardsBasepointTable; use edwards::EdwardsBasepointTable;
pub const p: FieldElement64 = FieldElement64([2251799813685229, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247]); /// Edwards `d` value, equal to `-121665/121666 mod p`.
pub(crate) const EDWARDS_D: FieldElement64 = FieldElement64([929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575]);
pub const d: FieldElement64 = FieldElement64([929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575]); /// Edwards `2*d` value, equal to `2*(-121665/121666) mod p`.
pub(crate) const EDWARDS_D2: FieldElement64 = FieldElement64([1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903]);
pub const d2: FieldElement64 = FieldElement64([1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903]); /// `= sqrt(a*d - 1)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
pub(crate) const SQRT_AD_MINUS_ONE: FieldElement64 = FieldElement64([
pub const d4: FieldElement64 = FieldElement64([1468021120295602, 1865462880516853, 2144638232625316, 1379996857856750, 1267578991991807]);
pub const a_minus_d: FieldElement64 = FieldElement64([1321844580190025, 1785434093556034, 589740348686294, 217950738957124, 809005158844672]);
pub const sqrt_ad_minus_one: FieldElement64 = FieldElement64([
2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748 2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748
]); ]);
pub const invsqrt_a_minus_d: FieldElement64 = FieldElement64([ /// `= 1/sqrt(a-d)`, where `a = -1 (mod p)`, `d` are the Edwards curve parameters.
pub(crate) const INVSQRT_A_MINUS_D: FieldElement64 = FieldElement64([
278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447 278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447
]); ]);
pub const inv_a_minus_d: FieldElement64 = FieldElement64([
2251799813563563, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247
]);
/// Precomputed value of one of the square roots of -1 (mod p) /// Precomputed value of one of the square roots of -1 (mod p)
pub const SQRT_M1: FieldElement64 = FieldElement64([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]); pub(crate) const SQRT_M1: FieldElement64 = FieldElement64([1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133]);
/// Precomputed value of the other square root of -1 (mod p),
/// i.e., `MSQRT_M1 = -SQRT_M1`.
pub const MSQRT_M1: FieldElement64 = FieldElement64([533094393274173, 2016890930128738, 18285341111199, 134597186663265, 1486323764102114]);
/// Precomputed value of 1/2 (mod p).
pub const HALF: FieldElement64 = FieldElement64([2251799813685239, 2251799813685247, 2251799813685247, 2251799813685247, 1125899906842623]);
/// In Montgomery form y² = x³+Ax²+x, Curve25519 has A=486662. /// In Montgomery form y² = x³+Ax²+x, Curve25519 has A=486662.
pub const A: FieldElement64 = FieldElement64([486662, 0, 0, 0, 0]); pub(crate) const MONTGOMERY_A: FieldElement64 = FieldElement64([486662, 0, 0, 0, 0]);
/// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.) /// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.)
pub const APLUS2_OVER_FOUR: FieldElement64 = FieldElement64([121666, 0, 0, 0, 0]); pub(crate) const APLUS2_OVER_FOUR: FieldElement64 = FieldElement64([121666, 0, 0, 0, 0]);
/// `SQRT_MINUS_A` is sqrt(-486662)
// XXX I think that this was used in Adam's code for his elligator
// implementation, but that should maybe be using sqrt(-486664)
// instead...? - hdevalence
pub const SQRT_MINUS_A: FieldElement64 = FieldElement64([557817479725543, 1643290402203250, 16226468853936, 1304118542701054, 1985241807451647]);
/// `SQRT_MINUS_APLUS2` is sqrt(-486664) /// `SQRT_MINUS_APLUS2` is sqrt(-486664)
pub const SQRT_MINUS_APLUS2: FieldElement64 = FieldElement64([1693982333959686, 608509411481997, 2235573344831311, 947681270984193, 266558006233600]); pub(crate) const SQRT_MINUS_APLUS2: FieldElement64 = FieldElement64([1693982333959686, 608509411481997, 2235573344831311, 947681270984193, 266558006233600]);
/// `SQRT_MINUS_HALF` is sqrt(-1/2) /// The Ed25519 basepoint has y = 4/5. This is called `_POINT` to
pub const SQRT_MINUS_HALF: FieldElement64 = FieldElement64([266547196637087, 2134345371906993, 1135042577398223, 67298593331632, 743161882051057]); /// distinguish it from `_TABLE`, which should be used for scalar
/// multiplication (it's much faster).
/// Basepoint has y = 4/5. This is called `_POINT` to distinguish it from `_TABLE`, which should
/// be used for scalar multiplication (it's much faster).
pub const ED25519_BASEPOINT_POINT: ExtendedPoint = ExtendedPoint{ pub const ED25519_BASEPOINT_POINT: ExtendedPoint = ExtendedPoint{
X: FieldElement64([1738742601995546, 1146398526822698, 2070867633025821, 562264141797630, 587772402128613]), X: FieldElement64([1738742601995546, 1146398526822698, 2070867633025821, 562264141797630, 587772402128613]),
Y: FieldElement64([1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198]), Y: FieldElement64([1801439850948184, 1351079888211148, 450359962737049, 900719925474099, 1801439850948198]),
@ -147,7 +122,8 @@ pub const EIGHT_TORSION: [ExtendedPoint; 8] = [
} }
]; ];
pub const bi: [AffineNielsPoint; 8] = [ /// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B]`.
pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: [AffineNielsPoint; 8] = [
AffineNielsPoint { AffineNielsPoint {
y_plus_x: FieldElement64([1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563]), y_plus_x: FieldElement64([1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563]),
y_minus_x: FieldElement64([62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585]), y_minus_x: FieldElement64([62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585]),

View file

@ -135,8 +135,8 @@ impl CompressedEdwardsY {
let Y = FieldElement::from_bytes(self.as_bytes()); let Y = FieldElement::from_bytes(self.as_bytes());
let Z = FieldElement::one(); let Z = FieldElement::one();
let YY = Y.square(); let YY = Y.square();
let u = &YY - &Z; // u = y²-1 let u = &YY - &Z; // u = y²-1
let v = &(&YY * &constants::d) + &Z; // v = dy²+1 let v = &(&YY * &constants::EDWARDS_D) + &Z; // v = dy²+1
let (is_nonzero_square, mut X) = FieldElement::sqrt_ratio(&u, &v); let (is_nonzero_square, mut X) = FieldElement::sqrt_ratio(&u, &v);
if is_nonzero_square != 1u8 { return None; } if is_nonzero_square != 1u8 { return None; }
@ -342,7 +342,7 @@ impl ValidityCheck for ProjectivePoint {
let ZZ = self.Z.square(); let ZZ = self.Z.square();
let ZZZZ = ZZ.square(); let ZZZZ = ZZ.square();
let lhs = &(&YY - &XX) * &ZZ; let lhs = &(&YY - &XX) * &ZZ;
let rhs = &ZZZZ + &(&constants::d * &(&XX * &YY)); let rhs = &ZZZZ + &(&constants::EDWARDS_D * &(&XX * &YY));
lhs == rhs lhs == rhs
} }
@ -518,7 +518,7 @@ impl ExtendedPoint {
Y_plus_X: &self.Y + &self.X, Y_plus_X: &self.Y + &self.X,
Y_minus_X: &self.Y - &self.X, Y_minus_X: &self.Y - &self.X,
Z: self.Z, Z: self.Z,
T2d: &self.T * &constants::d2, T2d: &self.T * &constants::EDWARDS_D2,
} }
} }
@ -541,7 +541,7 @@ impl ExtendedPoint {
let recip = self.Z.invert(); let recip = self.Z.invert();
let x = &self.X * &recip; let x = &self.X * &recip;
let y = &self.Y * &recip; let y = &self.Y * &recip;
let xy2d = &(&x * &y) * &constants::d2; let xy2d = &(&x * &y) * &constants::EDWARDS_D2;
AffineNielsPoint{ AffineNielsPoint{
y_plus_x: &y + &x, y_plus_x: &y + &x,
y_minus_x: &y - &x, y_minus_x: &y - &x,
@ -1233,6 +1233,7 @@ pub mod vartime {
} }
let odd_multiples_of_A = OddMultiples::create(A); let odd_multiples_of_A = OddMultiples::create(A);
let odd_multiples_of_B = &constants::AFFINE_ODD_MULTIPLES_OF_BASEPOINT;
let mut r = ProjectivePoint::identity(); let mut r = ProjectivePoint::identity();
loop { loop {
@ -1245,9 +1246,9 @@ pub mod vartime {
} }
if b_naf[i] > 0 { if b_naf[i] > 0 {
t = &t.to_extended() + &constants::bi[( b_naf[i]/2) as usize]; t = &t.to_extended() + &odd_multiples_of_B[( b_naf[i]/2) as usize];
} else if b_naf[i] < 0 { } else if b_naf[i] < 0 {
t = &t.to_extended() - &constants::bi[(-b_naf[i]/2) as usize]; t = &t.to_extended() - &odd_multiples_of_B[(-b_naf[i]/2) as usize];
} }
r = t.to_projective(); r = t.to_projective();
@ -1431,7 +1432,7 @@ mod test {
#[test] #[test]
fn basepoint_mult_by_basepoint_order() { fn basepoint_mult_by_basepoint_order() {
let B = &constants::ED25519_BASEPOINT_TABLE; let B = &constants::ED25519_BASEPOINT_TABLE;
let should_be_id = B * &constants::l; let should_be_id = B * &constants::BASEPOINT_ORDER;
assert!(should_be_id.is_identity()); assert!(should_be_id.is_identity());
} }

View file

@ -38,9 +38,6 @@
#[cfg(all(test, feature = "bench"))] #[cfg(all(test, feature = "bench"))]
extern crate test; extern crate test;
#[cfg(test)]
extern crate sha2;
#[macro_use] #[macro_use]
extern crate arrayref; extern crate arrayref;

View file

@ -146,8 +146,9 @@ impl CompressedMontgomeryU {
/// actually a square and `0` if otherwise, along with a `FieldElement`: the /// actually a square and `0` if otherwise, along with a `FieldElement`: the
/// Montgomery `v` corresponding to this `u`. /// Montgomery `v` corresponding to this `u`.
pub fn to_montgomery_v(u: &FieldElement) -> (u8, FieldElement) { pub fn to_montgomery_v(u: &FieldElement) -> (u8, FieldElement) {
let A = &constants::MONTGOMERY_A;
let one: FieldElement = FieldElement::one(); let one: FieldElement = FieldElement::one();
let v_squared: FieldElement = u * &(&u.square() + &(&(&constants::A * u) + &one)); let v_squared: FieldElement = u * &(&u.square() + &(&(A * u) + &one));
let (okay, v_inv) = v_squared.invsqrt(); let (okay, v_inv) = v_squared.invsqrt();
let v = &v_inv * &v_squared; let v = &v_inv * &v_squared;

View file

@ -462,7 +462,7 @@ impl CompressedRistretto {
let yden = &one + &ss; // 1 - a*s^2 let yden = &one + &ss; // 1 - a*s^2
let ynum = &one - &ss; // 1 + a*s^2 let ynum = &one - &ss; // 1 + a*s^2
let yden_sqr = yden.square(); let yden_sqr = yden.square();
let xden_sqr = &(&(-&constants::d) * &ynum.square()) - &yden_sqr; let xden_sqr = &(&(-&constants::EDWARDS_D) * &ynum.square()) - &yden_sqr;
let (ok, invsqrt) = (&xden_sqr * &yden_sqr).invsqrt(); let (ok, invsqrt) = (&xden_sqr * &yden_sqr).invsqrt();
@ -639,7 +639,7 @@ impl RistrettoPoint {
let iX = &X * &constants::SQRT_M1; let iX = &X * &constants::SQRT_M1;
let iY = &Y * &constants::SQRT_M1; let iY = &Y * &constants::SQRT_M1;
let ristretto_magic = &constants::invsqrt_a_minus_d; let ristretto_magic = &constants::INVSQRT_A_MINUS_D;
let enchanted_denominator = &i1 * ristretto_magic; let enchanted_denominator = &i1 * ristretto_magic;
let rotate = (T * &z_inv).is_negative(); let rotate = (T * &z_inv).is_negative();
@ -673,7 +673,7 @@ impl RistrettoPoint {
/// This method is not public because it's just used for hashing /// This method is not public because it's just used for hashing
/// to a point -- proper elligator support is deferred for now. /// to a point -- proper elligator support is deferred for now.
pub fn elligator_ristretto_flavour(r_0: &FieldElement) -> RistrettoPoint { pub fn elligator_ristretto_flavour(r_0: &FieldElement) -> RistrettoPoint {
let (i, d) = (&constants::SQRT_M1, &constants::d); let (i, d) = (&constants::SQRT_M1, &constants::EDWARDS_D);
let one = FieldElement::one(); let one = FieldElement::one();
let r = i * &r_0.square(); let r = i * &r_0.square();
@ -706,7 +706,7 @@ impl RistrettoPoint {
let s_sq = s.square(); let s_sq = s.square();
let P = CompletedPoint{ let P = CompletedPoint{
X: &(&s + &s) * &D, X: &(&s + &s) * &D,
Z: &T * &constants::sqrt_ad_minus_one, Z: &T * &constants::SQRT_AD_MINUS_ONE,
Y: &FieldElement::one() - &s_sq, Y: &FieldElement::one() - &s_sq,
T: &FieldElement::one() + &s_sq, T: &FieldElement::one() + &s_sq,
}; };
@ -1061,7 +1061,7 @@ mod test {
#[test] #[test]
fn decompress_negative_s_fails() { fn decompress_negative_s_fails() {
// constants::d is neg, so decompression should fail as |d| != d. // constants::d is neg, so decompression should fail as |d| != d.
let bad_compressed = CompressedRistretto(constants::d.to_bytes()); let bad_compressed = CompressedRistretto(constants::EDWARDS_D.to_bytes());
assert!(bad_compressed.decompress().is_none()); assert!(bad_compressed.decompress().is_none());
} }

View file

@ -136,7 +136,7 @@ impl<'a, 'b> Add<&'b Scalar> for &'a Scalar {
impl<'b> SubAssign<&'b Scalar> for Scalar { impl<'b> SubAssign<&'b Scalar> for Scalar {
fn sub_assign(&mut self, _rhs: &'b Scalar) { fn sub_assign(&mut self, _rhs: &'b Scalar) {
// (l-1)*_rhs + self = self - _rhs // (l-1)*_rhs + self = self - _rhs
*self = Scalar::multiply_add(&constants::l_minus_1, _rhs, self); *self = Scalar::multiply_add(&constants::BASEPOINT_ORDER_MINUS_1, _rhs, self);
} }
} }
@ -144,14 +144,14 @@ impl<'a, 'b> Sub<&'b Scalar> for &'a Scalar {
type Output = Scalar; type Output = Scalar;
fn sub(self, _rhs: &'b Scalar) -> Scalar { fn sub(self, _rhs: &'b Scalar) -> Scalar {
// (l-1)*_rhs + self = self - _rhs // (l-1)*_rhs + self = self - _rhs
Scalar::multiply_add(&constants::l_minus_1, _rhs, self) Scalar::multiply_add(&constants::BASEPOINT_ORDER_MINUS_1, _rhs, self)
} }
} }
impl<'a> Neg for &'a Scalar { impl<'a> Neg for &'a Scalar {
type Output = Scalar; type Output = Scalar;
fn neg(self) -> Scalar { fn neg(self) -> Scalar {
self * &constants::l_minus_1 self * &constants::BASEPOINT_ORDER_MINUS_1
} }
} }
@ -900,7 +900,7 @@ mod test {
#[test] #[test]
fn impl_sub() { fn impl_sub() {
let should_be_one = &constants::l - &constants::l_minus_1; let should_be_one = &constants::BASEPOINT_ORDER - &constants::BASEPOINT_ORDER_MINUS_1;
assert_eq!(should_be_one, Scalar::one()); assert_eq!(should_be_one, Scalar::one());
} }