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 { impl Identity for ProjectivePoint {
fn identity() -> ProjectivePoint { fn identity() -> ProjectivePoint {
ProjectivePoint { ProjectivePoint {
X: FieldElement::zero(), X: FieldElement::ZERO,
Y: FieldElement::one(), Y: FieldElement::ONE,
Z: FieldElement::one(), Z: FieldElement::ONE,
} }
} }
} }
@ -236,10 +236,10 @@ impl Identity for ProjectivePoint {
impl Identity for ProjectiveNielsPoint { impl Identity for ProjectiveNielsPoint {
fn identity() -> ProjectiveNielsPoint { fn identity() -> ProjectiveNielsPoint {
ProjectiveNielsPoint { ProjectiveNielsPoint {
Y_plus_X: FieldElement::one(), Y_plus_X: FieldElement::ONE,
Y_minus_X: FieldElement::one(), Y_minus_X: FieldElement::ONE,
Z: FieldElement::one(), Z: FieldElement::ONE,
T2d: FieldElement::zero(), T2d: FieldElement::ZERO,
} }
} }
} }
@ -253,9 +253,9 @@ impl Default for ProjectiveNielsPoint {
impl Identity for AffineNielsPoint { impl Identity for AffineNielsPoint {
fn identity() -> AffineNielsPoint { fn identity() -> AffineNielsPoint {
AffineNielsPoint { AffineNielsPoint {
y_plus_x: FieldElement::one(), y_plus_x: FieldElement::ONE,
y_minus_x: FieldElement::one(), y_minus_x: FieldElement::ONE,
xy2d: FieldElement::zero(), xy2d: FieldElement::ZERO,
} }
} }
} }

View file

@ -177,30 +177,19 @@ impl ConditionallySelectable for FieldElement2625 {
} }
impl 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 /// Invert the sign of this field element
pub fn negate(&mut self) { pub fn negate(&mut self) {
let neg = self.neg(); let neg = self.neg();
self.0 = neg.0; 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)`. /// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, k: u32) -> FieldElement2625 { pub fn pow2k(&self, k: u32) -> FieldElement2625 {
debug_assert!(k > 0); debug_assert!(k > 0);

View file

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

View file

@ -19,7 +19,7 @@ use crate::backend::serial::curve_models::AffineNielsPoint;
use crate::edwards::{EdwardsBasepointTable, EdwardsPoint}; use crate::edwards::{EdwardsBasepointTable, EdwardsPoint};
use crate::window::{LookupTable, NafLookupTable8}; 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([ pub(crate) const MINUS_ONE: FieldElement2625 = FieldElement2625([
67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 67108844, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863, 33554431, 67108863,
33554431, 33554431,

View file

@ -282,6 +282,13 @@ impl ConditionallySelectable for FieldElement2625 {
} }
impl 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 /// Invert the sign of this field element
pub fn negate(&mut self) { pub fn negate(&mut self) {
// Compute -b as ((2^4 * p) - b) to avoid underflow. // Compute -b as ((2^4 * p) - b) to avoid underflow.
@ -300,24 +307,6 @@ impl FieldElement2625 {
self.0 = neg.0; 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)`. /// Given `k > 0`, return `self^(2^k)`.
pub fn pow2k(&self, k: u32) -> FieldElement2625 { pub fn pow2k(&self, k: u32) -> FieldElement2625 {
debug_assert!(k > 0); debug_assert!(k > 0);

View file

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

View file

@ -253,6 +253,16 @@ impl ConditionallySelectable for FieldElement51 {
} }
impl 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 /// Invert the sign of this field element
pub fn negate(&mut self) { pub fn negate(&mut self) {
// See commentary in the Sub impl // See commentary in the Sub impl
@ -266,27 +276,6 @@ impl FieldElement51 {
self.0 = neg.0; 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). /// Given 64-bit input limbs, reduce to enforce the bound 2^(51 + epsilon).
#[inline(always)] #[inline(always)]
fn reduce(mut limbs: [u64; 5]) -> FieldElement51 { fn reduce(mut limbs: [u64; 5]) -> FieldElement51 {

View file

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

View file

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

View file

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

View file

@ -97,7 +97,7 @@ impl ExtendedPoint {
// ======================= // =======================
// S5 S6 S8 S9 // S5 S6 S8 S9
let zero = F51x4Unreduced::zero(); let zero = F51x4Unreduced::ZERO;
let S1_S1_S1_S1 = tmp1.shuffle(Shuffle::AAAA); let S1_S1_S1_S1 = tmp1.shuffle(Shuffle::AAAA);
let S2_S2_S2_S2 = tmp1.shuffle(Shuffle::BBBB); 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 { impl F51x4Unreduced {
pub fn zero() -> F51x4Unreduced { pub const ZERO: F51x4Unreduced = F51x4Unreduced([u64x4::splat(0); 5]);
F51x4Unreduced([u64x4::splat(0); 5])
}
pub fn new( pub fn new(
x0: &FieldElement51, x0: &FieldElement51,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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