Use inherent constants for ZERO, ONE, and MINUS_ONE (#470)

For the field element types `FieldElement` and `Scalar`, use inherent
constants instead of (non-const) functions to return these constant
values.

It's likely the original functions predate support for inherent
constants, but now that they're available, they're a better fit for
these sort of constant values.
This commit is contained in:
Tony Arcieri 2022-12-11 23:04:42 -07:00 committed by GitHub
parent acd78987f9
commit 6f237a0810
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 143 additions and 202 deletions

View file

@ -226,9 +226,9 @@ use crate::traits::Identity;
impl Identity for ProjectivePoint {
fn identity() -> ProjectivePoint {
ProjectivePoint {
X: FieldElement::zero(),
Y: FieldElement::one(),
Z: FieldElement::one(),
X: FieldElement::ZERO,
Y: FieldElement::ONE,
Z: FieldElement::ONE,
}
}
}
@ -236,10 +236,10 @@ impl Identity for ProjectivePoint {
impl Identity for ProjectiveNielsPoint {
fn identity() -> ProjectiveNielsPoint {
ProjectiveNielsPoint {
Y_plus_X: FieldElement::one(),
Y_minus_X: FieldElement::one(),
Z: FieldElement::one(),
T2d: FieldElement::zero(),
Y_plus_X: FieldElement::ONE,
Y_minus_X: FieldElement::ONE,
Z: FieldElement::ONE,
T2d: FieldElement::ZERO,
}
}
}
@ -253,9 +253,9 @@ impl Default for ProjectiveNielsPoint {
impl Identity for AffineNielsPoint {
fn identity() -> AffineNielsPoint {
AffineNielsPoint {
y_plus_x: FieldElement::one(),
y_minus_x: FieldElement::one(),
xy2d: FieldElement::zero(),
y_plus_x: FieldElement::ONE,
y_minus_x: FieldElement::ONE,
xy2d: FieldElement::ZERO,
}
}
}

View file

@ -177,30 +177,19 @@ impl ConditionallySelectable for FieldElement2625 {
}
impl FieldElement2625 {
pub const ZERO: FieldElement2625 = FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
pub const ONE: FieldElement2625 = FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
pub const MINUS_ONE: FieldElement2625 = FieldElement2625([
0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff,
0x3ffffff, 0x1ffffff,
]);
/// Invert the sign of this field element
pub fn negate(&mut self) {
let neg = self.neg();
self.0 = neg.0;
}
/// Construct zero.
pub fn zero() -> FieldElement2625 {
FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement2625 {
FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement2625 {
FieldElement2625([
0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff,
0x3ffffff, 0x1ffffff,
])
}
/// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, k: u32) -> FieldElement2625 {
debug_assert!(k > 0);

View file

@ -156,26 +156,15 @@ impl ConditionallySelectable for FieldElement51 {
}
impl FieldElement51 {
/// Construct zero.
pub fn zero() -> FieldElement51 {
FieldElement51([0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement51 {
FieldElement51([1, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement51 {
FieldElement51([
2251799813685228,
2251799813685247,
2251799813685247,
2251799813685247,
2251799813685247,
])
}
pub const ZERO: FieldElement51 = FieldElement51([0, 0, 0, 0, 0]);
pub const ONE: FieldElement51 = FieldElement51([1, 0, 0, 0, 0]);
pub const MINUS_ONE: FieldElement51 = FieldElement51([
2251799813685228,
2251799813685247,
2251799813685247,
2251799813685247,
2251799813685247,
]);
/// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon).
#[inline(always)]

View file

@ -19,7 +19,7 @@ use crate::backend::serial::curve_models::AffineNielsPoint;
use crate::edwards::{EdwardsBasepointTable, EdwardsPoint};
use crate::window::{LookupTable, NafLookupTable8};
/// The value of minus one, equal to `-&FieldElement::one()`
/// The value of minus one, equal to `-&FieldElement::ONE`
pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625([
67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863,
33554431,

View file

@ -282,6 +282,13 @@ impl ConditionallySelectable for FieldElement2625 {
}
impl FieldElement2625 {
pub const ZERO: FieldElement2625 = FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
pub const ONE: FieldElement2625 = FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
pub const MINUS_ONE: FieldElement2625 = FieldElement2625([
0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff,
0x3ffffff, 0x1ffffff,
]);
/// Invert the sign of this field element
pub fn negate(&mut self) {
// Compute -b as ((2^4 * p) - b) to avoid underflow.
@ -300,24 +307,6 @@ impl FieldElement2625 {
self.0 = neg.0;
}
/// Construct zero.
pub fn zero() -> FieldElement2625 {
FieldElement2625([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement2625 {
FieldElement2625([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement2625 {
FieldElement2625([
0x3ffffec, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff, 0x3ffffff, 0x1ffffff,
0x3ffffff, 0x1ffffff,
])
}
/// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, k: u32) -> FieldElement2625 {
debug_assert!(k > 0);

View file

@ -53,10 +53,7 @@ fn m(x: u32, y: u32) -> u64 {
}
impl Scalar29 {
/// Return the zero scalar.
pub fn zero() -> Scalar29 {
Scalar29([0, 0, 0, 0, 0, 0, 0, 0, 0])
}
pub const ZERO: Scalar29 = Scalar29([0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// Unpack a 32 byte / 256 bit scalar into 9 29-bit limbs.
#[rustfmt::skip] // keep alignment of s[*] calculations
@ -70,7 +67,7 @@ impl Scalar29 {
let mask = (1u32 << 29) - 1;
let top_mask = (1u32 << 24) - 1;
let mut s = Scalar29::zero();
let mut s = Scalar29::ZERO;
s[0] = words[0] & mask;
s[1] = ((words[0] >> 29) | (words[1] << 3)) & mask;
@ -96,8 +93,8 @@ impl Scalar29 {
}
let mask = (1u32 << 29) - 1;
let mut lo = Scalar29::zero();
let mut hi = Scalar29::zero();
let mut lo = Scalar29::ZERO;
let mut hi = Scalar29::ZERO;
lo[0] = words[ 0] & mask;
lo[1] = ((words[ 0] >> 29) | (words[ 1] << 3)) & mask;
@ -168,7 +165,7 @@ impl Scalar29 {
/// Compute `a + b` (mod l).
pub fn add(a: &Scalar29, b: &Scalar29) -> Scalar29 {
let mut sum = Scalar29::zero();
let mut sum = Scalar29::ZERO;
let mask = (1u32 << 29) - 1;
// a + b
@ -184,7 +181,7 @@ impl Scalar29 {
/// Compute `a - b` (mod l).
pub fn sub(a: &Scalar29, b: &Scalar29) -> Scalar29 {
let mut difference = Scalar29::zero();
let mut difference = Scalar29::ZERO;
let mask = (1u32 << 29) - 1;
// a - b
@ -512,7 +509,7 @@ mod test {
#[test]
fn add() {
let res = Scalar29::add(&A, &B);
let zero = Scalar29::zero();
let zero = Scalar29::ZERO;
for i in 0..9 {
assert!(res[i] == zero[i]);
}

View file

@ -17,7 +17,7 @@ use crate::backend::serial::curve_models::AffineNielsPoint;
use crate::edwards::{EdwardsBasepointTable, EdwardsPoint};
use crate::window::{LookupTable, NafLookupTable8};
/// The value of minus one, equal to `-&FieldElement::one()`
/// The value of minus one, equal to `-&FieldElement::ONE`
pub(crate) const MINUS_ONE: FieldElement51 = FieldElement51([
2251799813685228,
2251799813685247,

View file

@ -253,6 +253,16 @@ impl ConditionallySelectable for FieldElement51 {
}
impl FieldElement51 {
pub const ZERO: FieldElement51 = FieldElement51([0, 0, 0, 0, 0]);
pub const ONE: FieldElement51 = FieldElement51([1, 0, 0, 0, 0]);
pub const MINUS_ONE: FieldElement51 = FieldElement51([
2251799813685228,
2251799813685247,
2251799813685247,
2251799813685247,
2251799813685247,
]);
/// Invert the sign of this field element
pub fn negate(&mut self) {
// See commentary in the Sub impl
@ -266,27 +276,6 @@ impl FieldElement51 {
self.0 = neg.0;
}
/// Construct zero.
pub fn zero() -> FieldElement51 {
FieldElement51([0, 0, 0, 0, 0])
}
/// Construct one.
pub fn one() -> FieldElement51 {
FieldElement51([1, 0, 0, 0, 0])
}
/// Construct -1.
pub fn minus_one() -> FieldElement51 {
FieldElement51([
2251799813685228,
2251799813685247,
2251799813685247,
2251799813685247,
2251799813685247,
])
}
/// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon).
#[inline(always)]
fn reduce(mut limbs: [u64; 5]) -> FieldElement51 {

View file

@ -55,10 +55,7 @@ fn m(x: u64, y: u64) -> u128 {
}
impl Scalar52 {
/// Return the zero scalar
pub fn zero() -> Scalar52 {
Scalar52([0, 0, 0, 0, 0])
}
pub const ZERO: Scalar52 = Scalar52([0, 0, 0, 0, 0]);
/// Unpack a 32 byte / 256 bit scalar into 5 52-bit limbs.
#[rustfmt::skip] // keep alignment of s[*] calculations
@ -72,7 +69,7 @@ impl Scalar52 {
let mask = (1u64 << 52) - 1;
let top_mask = (1u64 << 48) - 1;
let mut s = Scalar52::zero();
let mut s = Scalar52::ZERO;
s[0] = words[0] & mask;
s[1] = ((words[0] >> 52) | (words[1] << 12)) & mask;
@ -94,8 +91,8 @@ impl Scalar52 {
}
let mask = (1u64 << 52) - 1;
let mut lo = Scalar52::zero();
let mut hi = Scalar52::zero();
let mut lo = Scalar52::ZERO;
let mut hi = Scalar52::ZERO;
lo[0] = words[0] & mask;
lo[1] = ((words[0] >> 52) | (words[ 1] << 12)) & mask;
@ -158,7 +155,7 @@ impl Scalar52 {
/// Compute `a + b` (mod l)
pub fn add(a: &Scalar52, b: &Scalar52) -> Scalar52 {
let mut sum = Scalar52::zero();
let mut sum = Scalar52::ZERO;
let mask = (1u64 << 52) - 1;
// a + b
@ -174,7 +171,7 @@ impl Scalar52 {
/// Compute `a - b` (mod l)
pub fn sub(a: &Scalar52, b: &Scalar52) -> Scalar52 {
let mut difference = Scalar52::zero();
let mut difference = Scalar52::ZERO;
let mask = (1u64 << 52) - 1;
// a - b
@ -472,7 +469,7 @@ mod test {
#[test]
fn add() {
let res = Scalar52::add(&A, &B);
let zero = Scalar52::zero();
let zero = Scalar52::ZERO;
for i in 0..5 {
assert!(res[i] == zero[i]);
}

View file

@ -134,7 +134,7 @@ impl ExtendedPoint {
// =======================
// S5 S6 S8 S9
let zero = FieldElement2625x4::zero();
let zero = FieldElement2625x4::ZERO;
let S_1 = tmp1.shuffle(Shuffle::AAAA);
let S_2 = tmp1.shuffle(Shuffle::BBBB);

View file

@ -180,11 +180,13 @@ impl ConditionallySelectable for FieldElement2625x4 {
}
impl FieldElement2625x4 {
pub const ZERO: FieldElement2625x4 = FieldElement2625x4([u32x8::splat(0); 5]);
/// Split this vector into an array of four (serial) field
/// elements.
#[rustfmt::skip] // keep alignment of extracted lanes
pub fn split(&self) -> [FieldElement51; 4] {
let mut out = [FieldElement51::zero(); 4];
let mut out = [FieldElement51::ZERO; 4];
for i in 0..5 {
let a_2i = self.0[i].extract(0) as u64; //
let b_2i = self.0[i].extract(1) as u64; //
@ -322,11 +324,6 @@ impl FieldElement2625x4 {
])
}
/// Construct a vector of zeros.
pub fn zero() -> FieldElement2625x4 {
FieldElement2625x4([u32x8::splat(0); 5])
}
/// Convenience wrapper around `new(x,x,x,x)`.
pub fn splat(x: &FieldElement51) -> FieldElement2625x4 {
FieldElement2625x4::new(x, x, x, x)
@ -888,7 +885,7 @@ mod test {
#[test]
fn scale_by_curve_constants() {
let mut x = FieldElement2625x4::splat(&FieldElement51::one());
let mut x = FieldElement2625x4::splat(&FieldElement51::ONE);
x = x * (121666, 121666, 2 * 121666, 2 * 121665);

View file

@ -97,7 +97,7 @@ impl ExtendedPoint {
// =======================
// S5 S6 S8 S9
let zero = F51x4Unreduced::zero();
let zero = F51x4Unreduced::ZERO;
let S1_S1_S1_S1 = tmp1.shuffle(Shuffle::AAAA);
let S2_S2_S2_S2 = tmp1.shuffle(Shuffle::BBBB);

View file

@ -101,9 +101,7 @@ fn blend_lanes(x: u64x4, y: u64x4, control: Lanes) -> u64x4 {
}
impl F51x4Unreduced {
pub fn zero() -> F51x4Unreduced {
F51x4Unreduced([u64x4::splat(0); 5])
}
pub const ZERO: F51x4Unreduced = F51x4Unreduced([u64x4::splat(0); 5]);
pub fn new(
x0: &FieldElement51,

View file

@ -132,7 +132,7 @@ mod test {
/// Test that SQRT_M1 is the positive square root of -1
#[test]
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;
assert_eq!(minus_one, sqrt_m1_sq);
assert_eq!(constants::SQRT_M1.is_negative().unwrap_u8(), 0);
@ -140,7 +140,7 @@ mod test {
#[test]
fn test_sqrt_constants_sign() {
let minus_one = FieldElement::minus_one();
let minus_one = FieldElement::MINUS_ONE;
let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt();
assert_eq!(was_nonzero_square.unwrap_u8(), 1u8);
let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1;
@ -175,7 +175,7 @@ mod test {
#[test]
fn test_sqrt_ad_minus_one() {
let a = FieldElement::minus_one();
let a = FieldElement::MINUS_ONE;
let ad_minus_one = &(&a * &constants::EDWARDS_D) + &a;
let should_be_ad_minus_one = constants::SQRT_AD_MINUS_ONE.square();
assert_eq!(should_be_ad_minus_one, ad_minus_one);

View file

@ -191,7 +191,7 @@ impl CompressedEdwardsY {
#[rustfmt::skip] // keep alignment of explanatory comments
pub fn decompress(&self) -> Option<EdwardsPoint> {
let Y = FieldElement::from_bytes(self.as_bytes());
let Z = FieldElement::one();
let Z = FieldElement::ONE;
let YY = Y.square();
let u = &YY - &Z; // u = y²-1
let v = &(&YY * &constants::EDWARDS_D) + &Z; // v = dy²+1
@ -370,10 +370,10 @@ impl CompressedEdwardsY {
impl Identity for EdwardsPoint {
fn identity() -> EdwardsPoint {
EdwardsPoint {
X: FieldElement::zero(),
Y: FieldElement::one(),
Z: FieldElement::one(),
T: FieldElement::zero(),
X: FieldElement::ZERO,
Y: FieldElement::ONE,
Z: FieldElement::ONE,
T: FieldElement::ZERO,
}
}
}
@ -400,8 +400,8 @@ impl Zeroize for EdwardsPoint {
/// Reset this `CompressedEdwardsPoint` to the identity element.
fn zeroize(&mut self) {
self.X.zeroize();
self.Y = FieldElement::one();
self.Z = FieldElement::one();
self.Y = FieldElement::ONE;
self.Z = FieldElement::ONE;
self.T.zeroize();
}
}
@ -1210,7 +1210,7 @@ mod test {
/// Test that computing 1*basepoint gives the correct basepoint.
#[test]
fn basepoint_mult_one_vs_basepoint() {
let bp = &constants::ED25519_BASEPOINT_TABLE * &Scalar::one();
let bp = &constants::ED25519_BASEPOINT_TABLE * &Scalar::ONE;
let compressed = bp.compress();
assert_eq!(compressed, constants::ED25519_BASEPOINT_COMPRESSED);
}
@ -1258,10 +1258,10 @@ mod test {
two_bytes[0] = 2;
let id1 = EdwardsPoint::identity();
let id2 = EdwardsPoint {
X: FieldElement::zero(),
X: FieldElement::ZERO,
Y: FieldElement::from_bytes(&two_bytes),
Z: FieldElement::from_bytes(&two_bytes),
T: FieldElement::zero(),
T: FieldElement::ZERO,
};
assert_eq!(id1.ct_eq(&id2).unwrap_u8(), 1u8);
}

View file

@ -173,10 +173,10 @@ impl FieldElement {
// Section 3.2
let n = inputs.len();
let mut scratch = vec![FieldElement::one(); n];
let mut scratch = vec![FieldElement::ONE; n];
// Keep an accumulator of all of the previous products
let mut acc = FieldElement::one();
let mut acc = FieldElement::ONE;
// Pass through the input vector, recording the previous
// products in the scratch space
@ -310,7 +310,7 @@ impl FieldElement {
/// - `(Choice(0), +sqrt(i/self)) ` if `self` is a nonzero nonsquare;
///
pub fn invsqrt(&self) -> (Choice, FieldElement) {
FieldElement::sqrt_ratio_i(&FieldElement::one(), self)
FieldElement::sqrt_ratio_i(&FieldElement::ONE, self)
}
}
@ -376,7 +376,7 @@ mod test {
let ainv = FieldElement::from_bytes(&AINV_BYTES);
let should_be_inverse = a.invert();
assert_eq!(ainv, should_be_inverse);
assert_eq!(FieldElement::one(), &a * &should_be_inverse);
assert_eq!(FieldElement::ONE, &a * &should_be_inverse);
}
#[test]
@ -398,8 +398,8 @@ mod test {
#[test]
fn sqrt_ratio_behavior() {
let zero = FieldElement::zero();
let one = FieldElement::one();
let zero = FieldElement::ZERO;
let one = FieldElement::ONE;
let i = constants::SQRT_M1;
let two = &one + &one; // 2 is nonsquare mod p.
let four = &two + &two; // 4 is square mod p.
@ -468,8 +468,8 @@ mod test {
#[test]
fn conditional_negate() {
let one = FieldElement::one();
let minus_one = FieldElement::minus_one();
let one = FieldElement::ONE;
let minus_one = FieldElement::MINUS_ONE;
let mut x = one;
x.conditional_negate(Choice::from(1));
assert_eq!(x, minus_one);

View file

@ -159,11 +159,11 @@ impl MontgomeryPoint {
let u = FieldElement::from_bytes(&self.0);
if u == FieldElement::minus_one() {
if u == FieldElement::MINUS_ONE {
return None;
}
let one = FieldElement::one();
let one = FieldElement::ONE;
let y = &(&u - &one) * &(&u + &one).invert();
@ -182,7 +182,7 @@ impl MontgomeryPoint {
// draft gets into a more polished/accepted state.
#[allow(unused)]
pub(crate) fn elligator_encode(r_0: &FieldElement) -> MontgomeryPoint {
let one = FieldElement::one();
let one = FieldElement::ONE;
let d_1 = &one + &r_0.square2(); /* 2r^2 */
let d = &MONTGOMERY_A_NEG * &(d_1.invert()); /* A/(1+2r^2) */
@ -195,7 +195,7 @@ pub(crate) fn elligator_encode(r_0: &FieldElement) -> MontgomeryPoint {
let (eps_is_sq, _eps) = FieldElement::sqrt_ratio_i(&eps, &one);
let zero = FieldElement::zero();
let zero = FieldElement::ZERO;
let Atemp = FieldElement::conditional_select(&MONTGOMERY_A, &zero, eps_is_sq); /* 0, or A if nonsquare*/
let mut u = &d + &Atemp; /* d, or d+A if nonsquare */
u.conditional_negate(!eps_is_sq); /* d, or -d-A if nonsquare */
@ -215,8 +215,8 @@ struct ProjectivePoint {
impl Identity for ProjectivePoint {
fn identity() -> ProjectivePoint {
ProjectivePoint {
U: FieldElement::one(),
W: FieldElement::zero(),
U: FieldElement::ONE,
W: FieldElement::ZERO,
}
}
}
@ -332,7 +332,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a MontgomeryPoint {
let mut x0 = ProjectivePoint::identity();
let mut x1 = ProjectivePoint {
U: affine_u,
W: FieldElement::one(),
W: FieldElement::ONE,
};
// Go through the bits from most to least significant, using a sliding window of 2
@ -442,7 +442,7 @@ mod test {
/// Check that Montgomery -> Edwards fails for points on the twist.
#[test]
fn montgomery_to_edwards_rejects_twist() {
let one = FieldElement::one();
let one = FieldElement::ONE;
// u = 2 corresponds to a point on the twist.
let two = MontgomeryPoint((&one + &one).as_bytes());

View file

@ -281,7 +281,7 @@ impl CompressedRistretto {
}
// Step 2. Compute (X:Y:Z:T).
let one = FieldElement::one();
let one = FieldElement::ONE;
let ss = s.square();
let u1 = &one - &ss; // 1 + as²
let u2 = &one + &ss; // 1 - as² where a=-1
@ -639,7 +639,7 @@ impl RistrettoPoint {
let d_minus_one_sq = &constants::EDWARDS_D_MINUS_ONE_SQUARED;
let mut c = constants::MINUS_ONE;
let one = FieldElement::one();
let one = FieldElement::ONE;
let r = i * &r_0.square();
let N_s = &(&r + &one) * one_minus_d_sq;
@ -663,8 +663,8 @@ impl RistrettoPoint {
CompletedPoint {
X: &(&s + &s) * &D,
Z: &N_t * &constants::SQRT_AD_MINUS_ONE,
Y: &FieldElement::one() - &s_sq,
T: &FieldElement::one() + &s_sq,
Y: &FieldElement::ONE - &s_sq,
T: &FieldElement::ONE + &s_sq,
}
.as_extended(),
)

View file

@ -36,7 +36,7 @@
//! ```
//! use curve25519_dalek::scalar::Scalar;
//!
//! let one_as_bytes: [u8; 32] = Scalar::one().to_bytes();
//! let one_as_bytes: [u8; 32] = Scalar::ONE.to_bytes();
//! let a: Option<Scalar> = Scalar::from_canonical_bytes(one_as_bytes);
//!
//! assert!(a.is_some());
@ -76,7 +76,7 @@
//! ];
//! let a: Scalar = Scalar::from_bytes_mod_order(l_plus_two_bytes);
//!
//! let two: Scalar = Scalar::one() + Scalar::one();
//! let two: Scalar = Scalar::ONE + Scalar::ONE;
//!
//! assert!(a == two);
//! ```
@ -129,7 +129,7 @@
//! ];
//! let a: Scalar = Scalar::from_bits(l_plus_two_bytes);
//!
//! let two: Scalar = Scalar::one() + Scalar::one();
//! let two: Scalar = Scalar::ONE + Scalar::ONE;
//!
//! assert!(a != two); // the scalar is not reduced (mod l)…
//! assert!(! a.is_canonical()); // …and therefore is not canonical.
@ -388,7 +388,7 @@ impl<'a> Neg for &'a Scalar {
fn neg(self) -> Scalar {
let self_R = UnpackedScalar::mul_internal(&self.unpack(), &constants::R);
let self_mod_l = UnpackedScalar::montgomery_reduce(&self_R);
UnpackedScalar::sub(&UnpackedScalar::zero(), &self_mod_l).pack()
UnpackedScalar::sub(&UnpackedScalar::ZERO, &self_mod_l).pack()
}
}
@ -475,7 +475,7 @@ where
where
I: Iterator<Item = T>,
{
iter.fold(Scalar::one(), |acc, item| acc * item.borrow())
iter.fold(Scalar::ONE, |acc, item| acc * item.borrow())
}
}
@ -487,13 +487,13 @@ where
where
I: Iterator<Item = T>,
{
iter.fold(Scalar::zero(), |acc, item| acc + item.borrow())
iter.fold(Scalar::ZERO, |acc, item| acc + item.borrow())
}
}
impl Default for Scalar {
fn default() -> Scalar {
Scalar::zero()
Scalar::ZERO
}
}
@ -569,6 +569,17 @@ impl Zeroize for Scalar {
}
impl Scalar {
/// The scalar \\( 0 \\).
pub const ZERO: Self = Self { bytes: [0u8; 32] };
/// The scalar \\( 1 \\).
pub const ONE: Self = Self {
bytes: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
],
};
#[cfg(any(test, feature = "rand_core"))]
/// Return a `Scalar` chosen uniformly at random using a user-provided RNG.
///
@ -679,7 +690,7 @@ impl Scalar {
/// ```
/// use curve25519_dalek::scalar::Scalar;
///
/// let s: Scalar = Scalar::zero();
/// let s: Scalar = Scalar::ZERO;
///
/// assert!(s.to_bytes() == [0u8; 32]);
/// ```
@ -694,7 +705,7 @@ impl Scalar {
/// ```
/// use curve25519_dalek::scalar::Scalar;
///
/// let s: Scalar = Scalar::zero();
/// let s: Scalar = Scalar::ZERO;
///
/// assert!(s.as_bytes() == &[0u8; 32]);
/// ```
@ -702,21 +713,6 @@ impl Scalar {
&self.bytes
}
/// Construct the scalar \\( 0 \\).
pub fn zero() -> Self {
Scalar { bytes: [0u8; 32] }
}
/// Construct the scalar \\( 1 \\).
pub fn one() -> Self {
Scalar {
bytes: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
}
}
/// Given a nonzero `Scalar`, compute its multiplicative inverse.
///
/// # Warning
@ -752,7 +748,7 @@ impl Scalar {
/// let inv_X: Scalar = X.invert();
/// assert!(XINV == inv_X);
/// let should_be_one: Scalar = &inv_X * &X;
/// assert!(should_be_one == Scalar::one());
/// assert!(should_be_one == Scalar::ONE);
/// ```
pub fn invert(&self) -> Scalar {
self.unpack().invert().pack()
@ -806,7 +802,7 @@ impl Scalar {
use zeroize::Zeroizing;
let n = inputs.len();
let one: UnpackedScalar = Scalar::one().unpack().as_montgomery();
let one: UnpackedScalar = Scalar::ONE.unpack().as_montgomery();
// Place scratch storage in a Zeroizing wrapper to wipe it when
// we pass out of scope.
@ -814,7 +810,7 @@ impl Scalar {
let mut scratch = Zeroizing::new(scratch_vec);
// Keep an accumulator of all of the previous products
let mut acc = Scalar::one().unpack().as_montgomery();
let mut acc = Scalar::ONE.unpack().as_montgomery();
// Pass through the input vector, recording the previous
// products in the scratch space
@ -829,7 +825,7 @@ impl Scalar {
}
// acc is nonzero iff all inputs are nonzero
debug_assert!(acc.pack() != Scalar::zero());
debug_assert!(acc.pack() != Scalar::ZERO);
// Compute the inverse of all products
acc = acc.montgomery_invert().from_montgomery();
@ -1395,7 +1391,7 @@ mod test {
let naf = x.non_adjacent_form(w);
// Reconstruct the scalar from the computed NAF
let mut y = Scalar::zero();
let mut y = Scalar::ZERO;
for i in (0..256).rev() {
y += y;
let digit = if naf[i] < 0 {
@ -1436,7 +1432,7 @@ mod test {
#[test]
fn scalar_mul_by_one() {
let test_scalar = X * Scalar::one();
let test_scalar = X * Scalar::ONE;
for i in 0..32 {
assert!(test_scalar[i] == X[i]);
}
@ -1446,12 +1442,12 @@ mod test {
fn add_reduces() {
// Check that the addition works
assert_eq!(
(LARGEST_ED25519_S + Scalar::one()).reduce(),
(LARGEST_ED25519_S + Scalar::ONE).reduce(),
CANONICAL_LARGEST_ED25519_S_PLUS_ONE
);
// Check that the addition reduces
assert_eq!(
LARGEST_ED25519_S + Scalar::one(),
LARGEST_ED25519_S + Scalar::ONE,
CANONICAL_LARGEST_ED25519_S_PLUS_ONE
);
}
@ -1460,12 +1456,12 @@ mod test {
fn sub_reduces() {
// Check that the subtraction works
assert_eq!(
(LARGEST_ED25519_S - Scalar::one()).reduce(),
(LARGEST_ED25519_S - Scalar::ONE).reduce(),
CANONICAL_LARGEST_ED25519_S_MINUS_ONE
);
// Check that the subtraction reduces
assert_eq!(
LARGEST_ED25519_S - Scalar::one(),
LARGEST_ED25519_S - Scalar::ONE,
CANONICAL_LARGEST_ED25519_S_MINUS_ONE
);
}
@ -1509,8 +1505,8 @@ mod test {
assert_eq!(neg_a, neg_b);
let minus_a_3 = Scalar::zero() - a - a - a;
let minus_b_3 = Scalar::zero() - b - b - b;
let minus_a_3 = Scalar::ZERO - a - a - a;
let minus_b_3 = Scalar::ZERO - b - b - b;
assert_eq!(minus_a_3, minus_b_3);
assert_eq!(minus_a_3, -a_3);
@ -1520,7 +1516,7 @@ mod test {
#[test]
fn impl_add() {
let two = Scalar::from(2u64);
let one = Scalar::one();
let one = Scalar::ONE;
let should_be_two = one + one;
assert_eq!(should_be_two, two);
}
@ -1542,7 +1538,7 @@ mod test {
assert_eq!(should_be_X_times_Y, X_TIMES_Y);
// Test that product works for the empty iterator
let one = Scalar::one();
let one = Scalar::ONE;
let empty_vector = vec![];
let should_be_one: Scalar = empty_vector.iter().product();
assert_eq!(should_be_one, one);
@ -1568,12 +1564,12 @@ mod test {
fn impl_sum() {
// Test that sum works for non-empty iterators
let two = Scalar::from(2u64);
let one_vector = vec![Scalar::one(), Scalar::one()];
let one_vector = vec![Scalar::ONE, Scalar::ONE];
let should_be_two: Scalar = one_vector.iter().sum();
assert_eq!(should_be_two, two);
// Test that sum works for the empty iterator
let zero = Scalar::zero();
let zero = Scalar::ZERO;
let empty_vector = vec![];
let should_be_zero: Scalar = empty_vector.iter().sum();
assert_eq!(should_be_zero, zero);
@ -1637,7 +1633,7 @@ mod test {
let inv_X = X.invert();
assert_eq!(inv_X, XINV);
let should_be_one = inv_X * X;
assert_eq!(should_be_one, Scalar::one());
assert_eq!(should_be_one, Scalar::ONE);
}
// Negating a scalar twice should result in the original scalar.
@ -1736,8 +1732,8 @@ mod test {
#[test]
#[should_panic]
fn batch_invert_with_a_zero_input_panics() {
let mut xs = vec![Scalar::one(); 16];
xs[3] = Scalar::zero();
let mut xs = vec![Scalar::ONE; 16];
xs[3] = Scalar::ZERO;
// This should panic in debug mode.
Scalar::batch_invert(&mut xs);
}
@ -1745,7 +1741,7 @@ mod test {
#[test]
#[cfg(feature = "alloc")]
fn batch_invert_empty() {
assert_eq!(Scalar::one(), Scalar::batch_invert(&mut []));
assert_eq!(Scalar::ONE, Scalar::batch_invert(&mut []));
}
#[test]
@ -1767,7 +1763,7 @@ mod test {
assert_eq!(ret, expected);
for (a, b) in v1.iter().zip(v2.iter()) {
assert_eq!(a * b, Scalar::one());
assert_eq!(a * b, Scalar::ONE);
}
}
@ -1776,8 +1772,8 @@ mod test {
let digits = scalar.as_radix_2w(w);
let radix = Scalar::from((1 << w) as u64);
let mut term = Scalar::one();
let mut recovered_scalar = Scalar::zero();
let mut term = Scalar::ONE;
let mut recovered_scalar = Scalar::ZERO;
for digit in &digits[0..digits_count] {
let digit = *digit;
if digit != 0 {
@ -1839,7 +1835,7 @@ mod test {
// Tests consistency of From<{integer}> impls for Scalar
#[test]
fn test_scalar_from_int() {
let s1 = Scalar::one();
let s1 = Scalar::ONE;
// For `x` in `u8`, `u16`, `u32`, `u64`, and `u128`, check that
// `Scalar::from(x + 1) == Scalar::from(x) + Scalar::from(1)`