Fix all clippy warnings replay (#441)

Also fixes CI not running on all branches

Co-authored-by: Anthony Ramine <nox@nox.paris>
This commit is contained in:
pinkforest(she/her) 2022-12-04 19:40:51 +11:00 committed by GitHub
parent 03b8668b29
commit e01bb1bdc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 383 additions and 283 deletions

View file

@ -2,9 +2,9 @@ name: Rust
on:
push:
branches: [ '*' ]
branches: [ '**' ]
pull_request:
branches: [ '*' ]
branches: [ '**' ]
env:
CARGO_TERM_COLOR: always
@ -69,6 +69,31 @@ jobs:
- uses: dtolnay/rust-toolchain@nightly
- run: cargo test --features "nightly"
clippy:
name: Check that clippy is happy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
with:
components: clippy
- env:
RUSTFLAGS: "-C target_feature=+avx2"
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings
- env:
RUSTFLAGS: "-C target_feature=+avx512ifma"
run: cargo clippy --target x86_64-unknown-linux-gnu --features simd_backend -- -D warnings
rustfmt:
name: Check formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
msrv:
name: Current MSRV is 1.56.1
runs-on: ubuntu-latest

View file

@ -92,10 +92,6 @@ mod multiscalar_benches {
.collect()
}
fn construct(n: usize) -> (Vec<Scalar>, Vec<EdwardsPoint>) {
(construct_scalars(n), construct_points(n))
}
fn consttime_multiscalar_mul<M: Measurement>(c: &mut BenchmarkGroup<M>) {
for multiscalar_size in &MULTISCALAR_SIZES {
c.bench_with_input(
@ -147,7 +143,7 @@ mod multiscalar_benches {
c.bench_with_input(
BenchmarkId::new(
"Variable-time fixed-base multiscalar multiplication",
&multiscalar_size,
multiscalar_size,
),
&multiscalar_size,
move |b, &&total_size| {

View file

@ -332,7 +332,7 @@ impl ProjectivePoint {
/// \\( \mathbb P\^3 \\) model.
///
/// This costs \\(3 \mathrm M + 1 \mathrm S\\).
pub fn to_extended(&self) -> EdwardsPoint {
pub fn as_extended(&self) -> EdwardsPoint {
EdwardsPoint {
X: &self.X * &self.Z,
Y: &self.Y * &self.Z,
@ -347,7 +347,7 @@ impl CompletedPoint {
/// \\) model to the \\( \mathbb P\^2 \\) model.
///
/// This costs \\(3 \mathrm M \\).
pub fn to_projective(&self) -> ProjectivePoint {
pub fn as_projective(&self) -> ProjectivePoint {
ProjectivePoint {
X: &self.X * &self.T,
Y: &self.Y * &self.Z,
@ -359,7 +359,7 @@ impl CompletedPoint {
/// \\) model to the \\( \mathbb P\^3 \\) model.
///
/// This costs \\(4 \mathrm M \\).
pub fn to_extended(&self) -> EdwardsPoint {
pub fn as_extended(&self) -> EdwardsPoint {
EdwardsPoint {
X: &self.X * &self.T,
Y: &self.Y * &self.Z,

View file

@ -233,10 +233,10 @@ impl FieldElement2625 {
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
pub fn to_bytes(&self) -> [u8; 32] {
pub fn as_bytes(&self) -> [u8; 32] {
let mut bytes = [0u8; 32];
fiat_25519_to_bytes(&mut bytes, &self.0);
return bytes;
bytes
}
/// Compute `self^2`.

View file

@ -209,10 +209,10 @@ impl FieldElement51 {
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
pub fn to_bytes(&self) -> [u8; 32] {
pub fn as_bytes(&self) -> [u8; 32] {
let mut bytes = [0u8; 32];
fiat_25519_to_bytes(&mut bytes, &self.0);
return bytes;
bytes
}
/// Given `k > 0`, return `self^(2^k)`.

View file

@ -12,6 +12,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use crate::edwards::EdwardsPoint;
use crate::scalar::Scalar;
@ -94,11 +95,11 @@ impl VartimeMultiscalarMul for Pippenger {
// Collect optimized scalars and points in buffers for repeated access
// (scanning the whole set per digit position).
let scalars = scalars.map(|s| s.borrow().to_radix_2w(w));
let scalars = scalars.map(|s| s.borrow().as_radix_2w(w));
let points = points
.into_iter()
.map(|p| p.map(|P| P.to_projective_niels()));
.map(|p| p.map(|P| P.as_projective_niels()));
let scalars_points = scalars
.zip(points)
@ -113,8 +114,8 @@ impl VartimeMultiscalarMul for Pippenger {
let mut columns = (0..digits_count).rev().map(|digit_index| {
// Clear the buckets when processing another digit.
for i in 0..buckets_count {
buckets[i] = EdwardsPoint::identity();
for bucket in &mut buckets {
*bucket = EdwardsPoint::identity();
}
// Iterate over pairs of (point, scalar)
@ -124,12 +125,16 @@ impl VartimeMultiscalarMul for Pippenger {
for (digits, pt) in scalars_points.iter() {
// Widen digit so that we don't run into edge cases when w=8.
let digit = digits[digit_index] as i16;
if digit > 0 {
let b = (digit - 1) as usize;
buckets[b] = (&buckets[b] + pt).to_extended();
} else if digit < 0 {
let b = (-digit - 1) as usize;
buckets[b] = (&buckets[b] - pt).to_extended();
match digit.cmp(&0) {
Ordering::Greater => {
let b = (digit - 1) as usize;
buckets[b] = (&buckets[b] + pt).as_extended();
}
Ordering::Less => {
let b = (-digit - 1) as usize;
buckets[b] = (&buckets[b] - pt).as_extended();
}
Ordering::Equal => {}
}
}
@ -193,7 +198,7 @@ mod test {
assert_eq!(subject.compress(), control.compress());
n = n / 2;
n /= 2;
}
}
}

View file

@ -12,6 +12,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use crate::backend::serial::curve_models::{
AffineNielsPoint, CompletedPoint, ProjectiveNielsPoint, ProjectivePoint,
@ -87,25 +88,34 @@ impl VartimePrecomputedMultiscalarMul for VartimePrecomputedStraus {
for i in 0..dp {
let t_ij = dynamic_nafs[i][j];
if t_ij > 0 {
R = &R.to_extended() + &dynamic_lookup_tables[i].select(t_ij as usize);
} else if t_ij < 0 {
R = &R.to_extended() - &dynamic_lookup_tables[i].select(-t_ij as usize);
match t_ij.cmp(&0) {
Ordering::Greater => {
R = &R.as_extended() + &dynamic_lookup_tables[i].select(t_ij as usize)
}
Ordering::Less => {
R = &R.as_extended() - &dynamic_lookup_tables[i].select(-t_ij as usize)
}
Ordering::Equal => {}
}
}
#[allow(clippy::needless_range_loop)]
for i in 0..sp {
let t_ij = static_nafs[i][j];
if t_ij > 0 {
R = &R.to_extended() + &self.static_lookup_tables[i].select(t_ij as usize);
} else if t_ij < 0 {
R = &R.to_extended() - &self.static_lookup_tables[i].select(-t_ij as usize);
match t_ij.cmp(&0) {
Ordering::Greater => {
R = &R.as_extended() + &self.static_lookup_tables[i].select(t_ij as usize)
}
Ordering::Less => {
R = &R.as_extended() - &self.static_lookup_tables[i].select(-t_ij as usize)
}
Ordering::Equal => {}
}
}
S = R.to_projective();
S = R.as_projective();
}
Some(S.to_extended())
Some(S.as_extended())
}
}

View file

@ -14,6 +14,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use crate::edwards::EdwardsPoint;
use crate::scalar::Scalar;
@ -123,7 +124,7 @@ impl MultiscalarMul for Straus {
// Zeroizing wrapper.
let scalar_digits_vec: Vec<_> = scalars
.into_iter()
.map(|s| s.borrow().to_radix_16())
.map(|s| s.borrow().as_radix_16())
.collect();
let scalar_digits = Zeroizing::new(scalar_digits_vec);
@ -135,7 +136,7 @@ impl MultiscalarMul for Straus {
// R_i = s_{i,j} * P_i
let R_i = lookup_table_i.select(s_i[j]);
// Q = Q + R_i
Q = (&Q + &R_i).to_extended();
Q = (&Q + &R_i).as_extended();
}
}
@ -183,16 +184,18 @@ impl VartimeMultiscalarMul for Straus {
let mut t: CompletedPoint = r.double();
for (naf, lookup_table) in nafs.iter().zip(lookup_tables.iter()) {
if naf[i] > 0 {
t = &t.to_extended() + &lookup_table.select(naf[i] as usize);
} else if naf[i] < 0 {
t = &t.to_extended() - &lookup_table.select(-naf[i] as usize);
match naf[i].cmp(&0) {
Ordering::Greater => {
t = &t.as_extended() + &lookup_table.select(naf[i] as usize)
}
Ordering::Less => t = &t.as_extended() - &lookup_table.select(-naf[i] as usize),
Ordering::Equal => {}
}
}
r = t.to_projective();
r = t.as_projective();
}
Some(r.to_extended())
Some(r.as_extended())
}
}

View file

@ -16,7 +16,7 @@ pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
// s = s_0 + s_1*16^1 + ... + s_63*16^63,
//
// with `-8 ≤ s_i < 8` for `0 ≤ i < 63` and `-8 ≤ s_63 ≤ 8`.
let scalar_digits = scalar.to_radix_16();
let scalar_digits = scalar.as_radix_16();
// Compute s*P as
//
// s*P = P*(s_0 + s_1*16^1 + s_2*16^2 + ... + s_63*16^63)
@ -31,17 +31,17 @@ pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
let mut tmp1 = &tmp3 + &lookup_table.select(scalar_digits[63]);
// Now tmp1 = s_63*P in P1xP1 coords
for i in (0..63).rev() {
tmp2 = tmp1.to_projective(); // tmp2 = (prev) in P2 coords
tmp2 = tmp1.as_projective(); // tmp2 = (prev) in P2 coords
tmp1 = tmp2.double(); // tmp1 = 2*(prev) in P1xP1 coords
tmp2 = tmp1.to_projective(); // tmp2 = 2*(prev) in P2 coords
tmp2 = tmp1.as_projective(); // tmp2 = 2*(prev) in P2 coords
tmp1 = tmp2.double(); // tmp1 = 4*(prev) in P1xP1 coords
tmp2 = tmp1.to_projective(); // tmp2 = 4*(prev) in P2 coords
tmp2 = tmp1.as_projective(); // tmp2 = 4*(prev) in P2 coords
tmp1 = tmp2.double(); // tmp1 = 8*(prev) in P1xP1 coords
tmp2 = tmp1.to_projective(); // tmp2 = 8*(prev) in P2 coords
tmp2 = tmp1.as_projective(); // tmp2 = 8*(prev) in P2 coords
tmp1 = tmp2.double(); // tmp1 = 16*(prev) in P1xP1 coords
tmp3 = tmp1.to_extended(); // tmp3 = 16*(prev) in P3 coords
tmp3 = tmp1.as_extended(); // tmp3 = 16*(prev) in P3 coords
tmp1 = &tmp3 + &lookup_table.select(scalar_digits[i]);
// Now tmp1 = s_i*P + 16*(prev) in P1xP1 coords
}
tmp1.to_extended()
tmp1.as_extended()
}

View file

@ -10,6 +10,8 @@
// - Henry de Valence <hdevalence@hdevalence.ca>
#![allow(non_snake_case)]
use core::cmp::Ordering;
use crate::backend::serial::curve_models::{ProjectiveNielsPoint, ProjectivePoint};
use crate::constants;
use crate::edwards::EdwardsPoint;
@ -38,19 +40,19 @@ pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
loop {
let mut t = r.double();
if a_naf[i] > 0 {
t = &t.to_extended() + &table_A.select(a_naf[i] as usize);
} else if a_naf[i] < 0 {
t = &t.to_extended() - &table_A.select(-a_naf[i] as usize);
match a_naf[i].cmp(&0) {
Ordering::Greater => t = &t.as_extended() + &table_A.select(a_naf[i] as usize),
Ordering::Less => t = &t.as_extended() - &table_A.select(-a_naf[i] as usize),
Ordering::Equal => {}
}
if b_naf[i] > 0 {
t = &t.to_extended() + &table_B.select(b_naf[i] as usize);
} else if b_naf[i] < 0 {
t = &t.to_extended() - &table_B.select(-b_naf[i] as usize);
match b_naf[i].cmp(&0) {
Ordering::Greater => t = &t.as_extended() + &table_B.select(b_naf[i] as usize),
Ordering::Less => t = &t.as_extended() - &table_B.select(-b_naf[i] as usize),
Ordering::Equal => {}
}
r = t.to_projective();
r = t.as_projective();
if i == 0 {
break;
@ -58,5 +60,5 @@ pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
i -= 1;
}
r.to_extended()
r.as_extended()
}

View file

@ -3891,6 +3891,7 @@ pub const ED25519_BASEPOINT_TABLE_INNER_DOC_HIDDEN: EdwardsBasepointTable =
]);
/// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B, ..., 127B]`.
#[allow(dead_code)]
pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: NafLookupTable8<AffineNielsPoint> =
NafLookupTable8([
AffineNielsPoint {

View file

@ -432,7 +432,8 @@ impl FieldElement2625 {
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
pub fn to_bytes(&self) -> [u8; 32] {
#[allow(clippy::identity_op)]
pub fn as_bytes(&self) -> [u8; 32] {
let inp = &self.0;
// Reduce the value represented by `in` to the range [0,2*p)
let mut h: [u32; 10] = FieldElement2625::reduce([
@ -481,29 +482,29 @@ impl FieldElement2625 {
// Now carry the result to compute r + 19q...
h[1] += h[0] >> 26;
h[0] = h[0] & LOW_26_BITS;
h[0] &= LOW_26_BITS;
h[2] += h[1] >> 25;
h[1] = h[1] & LOW_25_BITS;
h[1] &= LOW_25_BITS;
h[3] += h[2] >> 26;
h[2] = h[2] & LOW_26_BITS;
h[2] &= LOW_26_BITS;
h[4] += h[3] >> 25;
h[3] = h[3] & LOW_25_BITS;
h[3] &= LOW_25_BITS;
h[5] += h[4] >> 26;
h[4] = h[4] & LOW_26_BITS;
h[4] &= LOW_26_BITS;
h[6] += h[5] >> 25;
h[5] = h[5] & LOW_25_BITS;
h[5] &= LOW_25_BITS;
h[7] += h[6] >> 26;
h[6] = h[6] & LOW_26_BITS;
h[6] &= LOW_26_BITS;
h[8] += h[7] >> 25;
h[7] = h[7] & LOW_25_BITS;
h[7] &= LOW_25_BITS;
h[9] += h[8] >> 26;
h[8] = h[8] & LOW_26_BITS;
h[8] &= LOW_26_BITS;
// ... but instead of carrying the value
// (h[9] >> 25) = q*2^255 into another limb,
// discard it, subtracting the value from h.
debug_assert!((h[9] >> 25) == 0 || (h[9] >> 25) == 1);
h[9] = h[9] & LOW_25_BITS;
h[9] &= LOW_25_BITS;
let mut s = [0u8; 32];
s[0] = (h[0] >> 0) as u8;
@ -597,8 +598,8 @@ impl FieldElement2625 {
/// Compute `2*self^2`.
pub fn square2(&self) -> FieldElement2625 {
let mut coeffs = self.square_inner();
for i in 0..self.0.len() {
coeffs[i] += coeffs[i];
for coeff in &mut coeffs {
*coeff += *coeff;
}
FieldElement2625::reduce(coeffs)
}

View file

@ -126,7 +126,8 @@ impl Scalar29 {
/// Pack the limbs of this `Scalar29` into 32 bytes.
#[rustfmt::skip] // keep alignment of s[*] calculations
pub fn to_bytes(&self) -> [u8; 32] {
#[allow(clippy::identity_op)]
pub fn as_bytes(&self) -> [u8; 32] {
let mut s = [0u8; 32];
s[ 0] = (self.0[0] >> 0) as u8;
@ -375,11 +376,12 @@ impl Scalar29 {
/// Puts a Scalar29 in to Montgomery form, i.e. computes `a*R (mod l)`
#[inline(never)]
pub fn to_montgomery(&self) -> Scalar29 {
pub fn as_montgomery(&self) -> Scalar29 {
Scalar29::montgomery_mul(self, &constants::RR)
}
/// Takes a Scalar29 out of Montgomery form, i.e. computes `a/R (mod l)`
#[allow(clippy::wrong_self_convention)]
pub fn from_montgomery(&self) -> Scalar29 {
let mut limbs = [0u64; 17];
for i in 0..9 {

View file

@ -6282,6 +6282,7 @@ pub const ED25519_BASEPOINT_TABLE_INNER_DOC_HIDDEN: EdwardsBasepointTable =
]);
/// Odd multiples of the basepoint `[B, 3B, 5B, 7B, 9B, 11B, 13B, 15B, ..., 127B]`.
#[allow(dead_code)]
pub(crate) const AFFINE_ODD_MULTIPLES_OF_BASEPOINT: NafLookupTable8<AffineNielsPoint> =
NafLookupTable8([
AffineNielsPoint {

View file

@ -200,7 +200,7 @@ impl<'a, 'b> Mul<&'b FieldElement51> for &'a FieldElement51 {
// out[0] + carry * 19 < 2^51 + 19 * 2^59.33 < 2^63.58
//
// and there is no overflow.
out[0] = out[0] + carry * 19;
out[0] += carry * 19;
// Now out[1] < 2^51 + 2^(64 -51) = 2^51 + 2^13 < 2^(51 + epsilon).
out[1] += out[0] >> 51;
@ -367,7 +367,7 @@ impl FieldElement51 {
/// Serialize this `FieldElement51` to a 32-byte array. The
/// encoding is canonical.
#[rustfmt::skip] // keep alignment of s[*] calculations
pub fn to_bytes(&self) -> [u8; 32] {
pub fn as_bytes(&self) -> [u8; 32] {
// Let h = limbs[0] + limbs[1]*2^51 + ... + limbs[4]*2^204.
//
// Write h = pq + r with 0 <= r < p.
@ -398,17 +398,17 @@ impl FieldElement51 {
// Now carry the result to compute r + 19q ...
let low_51_bit_mask = (1u64 << 51) - 1;
limbs[1] += limbs[0] >> 51;
limbs[0] = limbs[0] & low_51_bit_mask;
limbs[2] += limbs[1] >> 51;
limbs[1] = limbs[1] & low_51_bit_mask;
limbs[3] += limbs[2] >> 51;
limbs[2] = limbs[2] & low_51_bit_mask;
limbs[4] += limbs[3] >> 51;
limbs[3] = limbs[3] & low_51_bit_mask;
limbs[1] += limbs[0] >> 51;
limbs[0] &= low_51_bit_mask;
limbs[2] += limbs[1] >> 51;
limbs[1] &= low_51_bit_mask;
limbs[3] += limbs[2] >> 51;
limbs[2] &= low_51_bit_mask;
limbs[4] += limbs[3] >> 51;
limbs[3] &= low_51_bit_mask;
// ... but instead of carrying (limbs[4] >> 51) = 2^255q
// into another limb, discard it, subtracting the value
limbs[4] = limbs[4] & low_51_bit_mask;
limbs[4] &= low_51_bit_mask;
// Now arrange the bits of the limbs.
let mut s = [0u8;32];
@ -543,7 +543,7 @@ impl FieldElement51 {
// a[0] + carry * 19 < 2^51 + 19 * 2^59.33 < 2^63.58
//
// and there is no overflow.
a[0] = a[0] + carry * 19;
a[0] += carry * 19;
// Now a[1] < 2^51 + 2^(64 -51) = 2^51 + 2^13 < 2^(51 + epsilon).
a[1] += a[0] >> 51;
@ -551,7 +551,7 @@ impl FieldElement51 {
// Now all a[i] < 2^(51 + epsilon) and a = self^(2^k).
k = k - 1;
k -= 1;
if k == 0 {
break;
}

View file

@ -116,7 +116,8 @@ impl Scalar52 {
/// Pack the limbs of this `Scalar52` into 32 bytes
#[rustfmt::skip] // keep alignment of s[*] calculations
pub fn to_bytes(&self) -> [u8; 32] {
#[allow(clippy::identity_op)]
pub fn as_bytes(&self) -> [u8; 32] {
let mut s = [0u8; 32];
s[ 0] = (self.0[ 0] >> 0) as u8;
@ -304,11 +305,12 @@ impl Scalar52 {
/// Puts a Scalar52 in to Montgomery form, i.e. computes `a*R (mod l)`
#[inline(never)]
pub fn to_montgomery(&self) -> Scalar52 {
pub fn as_montgomery(&self) -> Scalar52 {
Scalar52::montgomery_mul(self, &constants::RR)
}
/// Takes a Scalar52 out of Montgomery form, i.e. computes `a/R (mod l)`
#[allow(clippy::wrong_self_convention)]
#[inline(never)]
pub fn from_montgomery(&self) -> Scalar52 {
let mut limbs = [0u128; 9];

View file

@ -338,7 +338,7 @@ mod test {
macro_rules! print_var {
($x:ident) => {
println!("{} = {:?}", stringify!($x), $x.to_bytes());
println!("{} = {:?}", stringify!($x), $x.as_bytes());
};
}
@ -450,7 +450,7 @@ mod test {
macro_rules! print_var {
($x:ident) => {
println!("{} = {:?}", stringify!($x), $x.to_bytes());
println!("{} = {:?}", stringify!($x), $x.as_bytes());
};
}

View file

@ -95,7 +95,7 @@ fn repack_pair(x: u32x8, y: u32x8) -> u32x8 {
// x' = (a0, b0, 0, 0, c0, d0, 0, 0)
// y' = ( 0, 0, a1, b1, 0, 0, c1, d1)
return _mm256_blend_epi32(x_shuffled, y_shuffled, 0b11001100).into_bits();
_mm256_blend_epi32(x_shuffled, y_shuffled, 0b11001100).into_bits()
}
}
@ -105,6 +105,7 @@ fn repack_pair(x: u32x8, y: u32x8) -> u32x8 {
/// It's used to specify blend operations without
/// having to know details about the data layout of the
/// `FieldElement2625x4`.
#[allow(clippy::upper_case_acronyms)]
#[derive(Copy, Clone, Debug)]
pub enum Lanes {
C,
@ -122,6 +123,7 @@ pub enum Lanes {
/// The enum variants are named by what they do to a vector \\(
/// (A,B,C,D) \\); for instance, `Shuffle::BADC` turns \\( (A, B, C,
/// D) \\) into \\( (B, A, D, C) \\).
#[allow(clippy::upper_case_acronyms)]
#[derive(Copy, Clone, Debug)]
pub enum Shuffle {
AAAA,
@ -344,6 +346,7 @@ impl FieldElement2625x4 {
) -> FieldElement2625x4 {
let mut buf = [u32x8::splat(0); 5];
let low_26_bits = (1 << 26) - 1;
#[allow(clippy::needless_range_loop)]
for i in 0..5 {
let a_2i = (x0.0[i] & low_26_bits) as u32;
let a_2i_1 = (x0.0[i] >> 26) as u32;
@ -502,7 +505,7 @@ impl FieldElement2625x4 {
};
// Add the final carryin.
v[0] = v[0] + c9_19;
v[0] += c9_19;
// Each output coefficient has exactly one carryin, which is
// bounded by 2^11.25, so they are bounded as
@ -531,12 +534,12 @@ impl FieldElement2625x4 {
debug_assert!(i < 9);
if i % 2 == 0 {
// Even limbs have 26 bits
z[i + 1] = z[i + 1] + (z[i] >> 26);
z[i] = z[i] & LOW_26_BITS;
z[i + 1] += z[i] >> 26;
z[i] &= LOW_26_BITS;
} else {
// Odd limbs have 25 bits
z[i + 1] = z[i + 1] + (z[i] >> 25);
z[i] = z[i] & LOW_25_BITS;
z[i + 1] += z[i] >> 25;
z[i] &= LOW_25_BITS;
}
};
@ -559,7 +562,7 @@ impl FieldElement2625x4 {
// Instead, we split the carry in two, with c = c_0 + c_1*2^26.
let c = z[9] >> 25;
z[9] = z[9] & LOW_25_BITS;
z[9] &= LOW_25_BITS;
let mut c0: u64x4 = c & LOW_26_BITS; // c0 < 2^26;
let mut c1: u64x4 = c >> 26; // c1 < 2^(39-26) = 2^13;
@ -570,8 +573,8 @@ impl FieldElement2625x4 {
c1 = _mm256_mul_epu32(c1.into_bits(), x19.into_bits()).into_bits(); // c1 < 2^17.25
}
z[0] = z[0] + c0; // z0 < 2^26 + 2^30.25 < 2^30.33
z[1] = z[1] + c1; // z1 < 2^25 + 2^17.25 < 2^25.0067
z[0] += c0; // z0 < 2^26 + 2^30.25 < 2^30.33
z[1] += c1; // z1 < 2^25 + 2^17.25 < 2^25.0067
carry(&mut z, 0); // z0 < 2^26, z1 < 2^25.0067 + 2^4.33 = 2^25.007
// The output coefficients are bounded with

View file

@ -38,6 +38,7 @@ pub struct F51x4Unreduced(pub(crate) [u64x4; 5]);
#[derive(Copy, Clone, Debug)]
pub struct F51x4Reduced(pub(crate) [u64x4; 5]);
#[allow(clippy::upper_case_acronyms)]
#[derive(Copy, Clone)]
pub enum Shuffle {
AAAA,
@ -72,6 +73,7 @@ fn shuffle_lanes(x: u64x4, control: Shuffle) -> u64x4 {
}
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Copy, Clone)]
pub enum Lanes {
D,

View file

@ -34,6 +34,10 @@ pub(crate) use self::ifma::{
constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint,
};
#[cfg(any(target_feature = "avx2", target_feature = "avx512ifma", all(docsrs, target_arch = "x86_64")))]
#[cfg(any(
target_feature = "avx2",
target_feature = "avx512ifma",
all(docsrs, target_arch = "x86_64")
))]
#[allow(missing_docs)]
pub mod scalar_mul;

View file

@ -10,6 +10,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use crate::backend::vector::{CachedPoint, ExtendedPoint};
use crate::edwards::EdwardsPoint;
@ -51,7 +52,7 @@ impl VartimeMultiscalarMul for Pippenger {
// Collect optimized scalars and points in a buffer for repeated access
// (scanning the whole collection per each digit position).
let scalars = scalars.into_iter().map(|s| s.borrow().to_radix_2w(w));
let scalars = scalars.into_iter().map(|s| s.borrow().as_radix_2w(w));
let points = points
.into_iter()
@ -70,8 +71,8 @@ impl VartimeMultiscalarMul for Pippenger {
let mut columns = (0..digits_count).rev().map(|digit_index| {
// Clear the buckets when processing another digit.
for i in 0..buckets_count {
buckets[i] = ExtendedPoint::identity();
for bucket in &mut buckets {
*bucket = ExtendedPoint::identity();
}
// Iterate over pairs of (point, scalar)
@ -81,12 +82,16 @@ impl VartimeMultiscalarMul for Pippenger {
for (digits, pt) in scalars_points.iter() {
// Widen digit so that we don't run into edge cases when w=8.
let digit = digits[digit_index] as i16;
if digit > 0 {
let b = (digit - 1) as usize;
buckets[b] = &buckets[b] + pt;
} else if digit < 0 {
let b = (-digit - 1) as usize;
buckets[b] = &buckets[b] - pt;
match digit.cmp(&0) {
Ordering::Greater => {
let b = (digit - 1) as usize;
buckets[b] = &buckets[b] + pt;
}
Ordering::Less => {
let b = (-digit - 1) as usize;
buckets[b] = &buckets[b] - pt;
}
Ordering::Equal => {}
}
}

View file

@ -12,6 +12,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use crate::backend::vector::{CachedPoint, ExtendedPoint};
use crate::edwards::EdwardsPoint;
@ -84,19 +85,28 @@ impl VartimePrecomputedMultiscalarMul for VartimePrecomputedStraus {
for i in 0..dp {
let t_ij = dynamic_nafs[i][j];
if t_ij > 0 {
R = &R + &dynamic_lookup_tables[i].select(t_ij as usize);
} else if t_ij < 0 {
R = &R - &dynamic_lookup_tables[i].select(-t_ij as usize);
match t_ij.cmp(&0) {
Ordering::Greater => {
R = &R + &dynamic_lookup_tables[i].select(t_ij as usize);
}
Ordering::Less => {
R = &R - &dynamic_lookup_tables[i].select(-t_ij as usize);
}
Ordering::Equal => {}
}
}
#[allow(clippy::needless_range_loop)]
for i in 0..sp {
let t_ij = static_nafs[i][j];
if t_ij > 0 {
R = &R + &self.static_lookup_tables[i].select(t_ij as usize);
} else if t_ij < 0 {
R = &R - &self.static_lookup_tables[i].select(-t_ij as usize);
match t_ij.cmp(&0) {
Ordering::Greater => {
R = &R + &self.static_lookup_tables[i].select(t_ij as usize);
}
Ordering::Less => {
R = &R - &self.static_lookup_tables[i].select(-t_ij as usize);
}
Ordering::Equal => {}
}
}
}

View file

@ -12,6 +12,7 @@
#![allow(non_snake_case)]
use core::borrow::Borrow;
use core::cmp::Ordering;
use zeroize::Zeroizing;
@ -53,7 +54,7 @@ impl MultiscalarMul for Straus {
let scalar_digits_vec: Vec<_> = scalars
.into_iter()
.map(|s| s.borrow().to_radix_16())
.map(|s| s.borrow().as_radix_16())
.collect();
// Pass ownership to a `Zeroizing` wrapper
let scalar_digits = Zeroizing::new(scalar_digits_vec);
@ -95,10 +96,14 @@ impl VartimeMultiscalarMul for Straus {
Q = Q.double();
for (naf, lookup_table) in nafs.iter().zip(lookup_tables.iter()) {
if naf[i] > 0 {
Q = &Q + &lookup_table.select(naf[i] as usize);
} else if naf[i] < 0 {
Q = &Q - &lookup_table.select(-naf[i] as usize);
match naf[i].cmp(&0) {
Ordering::Greater => {
Q = &Q + &lookup_table.select(naf[i] as usize);
}
Ordering::Less => {
Q = &Q - &lookup_table.select(-naf[i] as usize);
}
Ordering::Equal => {}
}
}
}

View file

@ -15,7 +15,7 @@ pub fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
// s = s_0 + s_1*16^1 + ... + s_63*16^63,
//
// with `-8 ≤ s_i < 8` for `0 ≤ i < 63` and `-8 ≤ s_63 ≤ 8`.
let scalar_digits = scalar.to_radix_16();
let scalar_digits = scalar.as_radix_16();
// Compute s*P as
//
// s*P = P*(s_0 + s_1*16^1 + s_2*16^2 + ... + s_63*16^63)

View file

@ -11,6 +11,8 @@
#![allow(non_snake_case)]
use core::cmp::Ordering;
use crate::backend::vector::BASEPOINT_ODD_LOOKUP_TABLE;
use crate::backend::vector::{CachedPoint, ExtendedPoint};
use crate::edwards::EdwardsPoint;
@ -40,16 +42,24 @@ pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {
loop {
Q = Q.double();
if a_naf[i] > 0 {
Q = &Q + &table_A.select(a_naf[i] as usize);
} else if a_naf[i] < 0 {
Q = &Q - &table_A.select(-a_naf[i] as usize);
match a_naf[i].cmp(&0) {
Ordering::Greater => {
Q = &Q + &table_A.select(a_naf[i] as usize);
}
Ordering::Less => {
Q = &Q - &table_A.select(-a_naf[i] as usize);
}
Ordering::Equal => {}
}
if b_naf[i] > 0 {
Q = &Q + &table_B.select(b_naf[i] as usize);
} else if b_naf[i] < 0 {
Q = &Q - &table_B.select(-b_naf[i] as usize);
match b_naf[i].cmp(&0) {
Ordering::Greater => {
Q = &Q + &table_B.select(b_naf[i] as usize);
}
Ordering::Less => {
Q = &Q - &table_B.select(-b_naf[i] as usize);
}
Ordering::Equal => {}
}
if i == 0 {

View file

@ -413,7 +413,7 @@ impl Zeroize for EdwardsPoint {
impl ValidityCheck for EdwardsPoint {
fn is_valid(&self) -> bool {
let point_on_curve = self.to_projective().is_valid();
let point_on_curve = self.as_projective().is_valid();
let on_segre_image = (&self.X * &self.Y) == (&self.Z * &self.T);
point_on_curve && on_segre_image
@ -466,7 +466,7 @@ impl Eq for EdwardsPoint {}
impl EdwardsPoint {
/// Convert to a ProjectiveNielsPoint
pub(crate) fn to_projective_niels(&self) -> ProjectiveNielsPoint {
pub(crate) fn as_projective_niels(&self) -> ProjectiveNielsPoint {
ProjectiveNielsPoint {
Y_plus_X: &self.Y + &self.X,
Y_minus_X: &self.Y - &self.X,
@ -479,7 +479,7 @@ impl EdwardsPoint {
/// coordinates to projective coordinates.
///
/// Free.
pub(crate) fn to_projective(&self) -> ProjectivePoint {
pub(crate) fn as_projective(&self) -> ProjectivePoint {
ProjectivePoint {
X: self.X,
Y: self.Y,
@ -489,7 +489,7 @@ impl EdwardsPoint {
/// Dehomogenize to a AffineNielsPoint.
/// Mainly for testing.
pub(crate) fn to_affine_niels(&self) -> AffineNielsPoint {
pub(crate) fn as_affine_niels(&self) -> AffineNielsPoint {
let recip = self.Z.invert();
let x = &self.X * &recip;
let y = &self.Y * &recip;
@ -519,7 +519,7 @@ impl EdwardsPoint {
let U = &self.Z + &self.Y;
let W = &self.Z - &self.Y;
let u = &U * &W.invert();
MontgomeryPoint(u.to_bytes())
MontgomeryPoint(u.as_bytes())
}
/// Compress this point to `CompressedEdwardsY` format.
@ -529,7 +529,7 @@ impl EdwardsPoint {
let y = &self.Y * &recip;
let mut s: [u8; 32];
s = y.to_bytes();
s = y.as_bytes();
s[31] ^= x.is_negative().unwrap_u8() << 7;
CompressedEdwardsY(s)
}
@ -573,7 +573,7 @@ impl EdwardsPoint {
impl EdwardsPoint {
/// Add this point to itself.
pub(crate) fn double(&self) -> EdwardsPoint {
self.to_projective().double().to_extended()
self.as_projective().double().as_extended()
}
}
@ -584,7 +584,7 @@ impl EdwardsPoint {
impl<'a, 'b> Add<&'b EdwardsPoint> for &'a EdwardsPoint {
type Output = EdwardsPoint;
fn add(self, other: &'b EdwardsPoint) -> EdwardsPoint {
(self + &other.to_projective_niels()).to_extended()
(self + &other.as_projective_niels()).as_extended()
}
}
@ -605,7 +605,7 @@ define_add_assign_variants!(LHS = EdwardsPoint, RHS = EdwardsPoint);
impl<'a, 'b> Sub<&'b EdwardsPoint> for &'a EdwardsPoint {
type Output = EdwardsPoint;
fn sub(self, other: &'b EdwardsPoint) -> EdwardsPoint {
(self - &other.to_projective_niels()).to_extended()
(self - &other.as_projective_niels()).as_extended()
}
}
@ -881,7 +881,7 @@ macro_rules! impl_basepoint_table {
fn basepoint(&self) -> $point {
// self.0[0].select(1) = 1*(16^2)^0*B
// but as an `AffineNielsPoint`, so add identity to convert to extended.
(&<$point>::identity() + &self.0[0].select(1)).to_extended()
(&<$point>::identity() + &self.0[0].select(1)).as_extended()
}
/// The computation uses Pippeneger's algorithm, as described for the
@ -923,19 +923,19 @@ macro_rules! impl_basepoint_table {
///
/// The above algorithm is trivially generalised to other powers-of-2 radices.
fn basepoint_mul(&self, scalar: &Scalar) -> $point {
let a = scalar.to_radix_2w($radix);
let a = scalar.as_radix_2w($radix);
let tables = &self.0;
let mut P = <$point>::identity();
for i in (0..$adds).filter(|x| x % 2 == 1) {
P = (&P + &tables[i / 2].select(a[i])).to_extended();
P = (&P + &tables[i / 2].select(a[i])).as_extended();
}
P = P.mul_by_pow_2($radix);
for i in (0..$adds).filter(|x| x % 2 == 0) {
P = (&P + &tables[i / 2].select(a[i])).to_extended();
P = (&P + &tables[i / 2].select(a[i])).as_extended();
}
P
@ -1030,13 +1030,13 @@ impl EdwardsPoint {
pub(crate) fn mul_by_pow_2(&self, k: u32) -> EdwardsPoint {
debug_assert!(k > 0);
let mut r: CompletedPoint;
let mut s = self.to_projective();
let mut s = self.as_projective();
for _ in 0..(k - 1) {
r = s.double();
s = r.to_projective();
s = r.as_projective();
}
// Unroll last iteration so we can go directly to_extended()
s.double().to_extended()
// Unroll last iteration so we can go directly as_extended()
s.double().as_extended()
}
/// Determine if this point is of small order.
@ -1195,7 +1195,7 @@ mod test {
#[test]
fn decompression_sign_handling() {
// Manually set the high bit of the last byte to flip the sign
let mut minus_basepoint_bytes = constants::ED25519_BASEPOINT_COMPRESSED.as_bytes().clone();
let mut minus_basepoint_bytes = *constants::ED25519_BASEPOINT_COMPRESSED.as_bytes();
minus_basepoint_bytes[31] |= 1 << 7;
let minus_basepoint = CompressedEdwardsY(minus_basepoint_bytes)
.decompress()
@ -1228,7 +1228,7 @@ mod test {
#[test]
fn basepoint_plus_basepoint_vs_basepoint2() {
let bp = constants::ED25519_BASEPOINT_POINT;
let bp_added = &bp + &bp;
let bp_added = bp + bp;
assert_eq!(bp_added.compress(), BASE2_CMPRSSD);
}
@ -1237,7 +1237,7 @@ mod test {
#[test]
fn basepoint_plus_basepoint_projective_niels_vs_basepoint2() {
let bp = constants::ED25519_BASEPOINT_POINT;
let bp_added = (&bp + &bp.to_projective_niels()).to_extended();
let bp_added = (&bp + &bp.as_projective_niels()).as_extended();
assert_eq!(bp_added.compress(), BASE2_CMPRSSD);
}
@ -1246,8 +1246,8 @@ mod test {
#[test]
fn basepoint_plus_basepoint_affine_niels_vs_basepoint2() {
let bp = constants::ED25519_BASEPOINT_POINT;
let bp_affine_niels = bp.to_affine_niels();
let bp_added = (&bp + &bp_affine_niels).to_extended();
let bp_affine_niels = bp.as_affine_niels();
let bp_added = (&bp + &bp_affine_niels).as_extended();
assert_eq!(bp_added.compress(), BASE2_CMPRSSD);
}
@ -1272,8 +1272,8 @@ mod test {
fn to_affine_niels_clears_denominators() {
// construct a point as aB so it has denominators (ie. Z != 1)
let aB = &constants::ED25519_BASEPOINT_TABLE * &A_SCALAR;
let aB_affine_niels = aB.to_affine_niels();
let also_aB = (&EdwardsPoint::identity() + &aB_affine_niels).to_extended();
let aB_affine_niels = aB.as_affine_niels();
let also_aB = (&EdwardsPoint::identity() + &aB_affine_niels).as_extended();
assert_eq!(aB.compress(), also_aB.compress());
}
@ -1296,14 +1296,14 @@ mod test {
#[test]
fn test_precomputed_basepoint_mult() {
let aB_1 = &constants::ED25519_BASEPOINT_TABLE * &A_SCALAR;
let aB_2 = &constants::ED25519_BASEPOINT_POINT * &A_SCALAR;
let aB_2 = constants::ED25519_BASEPOINT_POINT * A_SCALAR;
assert_eq!(aB_1.compress(), aB_2.compress());
}
/// Test scalar_mul versus a known scalar multiple from ed25519.py
#[test]
fn scalar_mul_vs_ed25519py() {
let aB = &constants::ED25519_BASEPOINT_POINT * &A_SCALAR;
let aB = constants::ED25519_BASEPOINT_POINT * A_SCALAR;
assert_eq!(aB.compress(), A_TIMES_BASEPOINT);
}
@ -1330,11 +1330,11 @@ mod test {
let P = &constants::ED25519_BASEPOINT_POINT;
let a = A_SCALAR;
let table_radix16 = EdwardsBasepointTableRadix16::create(&P);
let table_radix32 = EdwardsBasepointTableRadix32::create(&P);
let table_radix64 = EdwardsBasepointTableRadix64::create(&P);
let table_radix128 = EdwardsBasepointTableRadix128::create(&P);
let table_radix256 = EdwardsBasepointTableRadix256::create(&P);
let table_radix16 = EdwardsBasepointTableRadix16::create(P);
let table_radix32 = EdwardsBasepointTableRadix32::create(P);
let table_radix64 = EdwardsBasepointTableRadix64::create(P);
let table_radix128 = EdwardsBasepointTableRadix128::create(P);
let table_radix256 = EdwardsBasepointTableRadix256::create(P);
let aP = (&constants::ED25519_BASEPOINT_TABLE * &a).compress();
let aP16 = (&table_radix16 * &a).compress();
@ -1360,11 +1360,11 @@ mod test {
0xFF, 0xFF, 0xFF, 0xFF,
]);
let table_radix16 = EdwardsBasepointTableRadix16::create(&P);
let table_radix32 = EdwardsBasepointTableRadix32::create(&P);
let table_radix64 = EdwardsBasepointTableRadix64::create(&P);
let table_radix128 = EdwardsBasepointTableRadix128::create(&P);
let table_radix256 = EdwardsBasepointTableRadix256::create(&P);
let table_radix16 = EdwardsBasepointTableRadix16::create(P);
let table_radix32 = EdwardsBasepointTableRadix32::create(P);
let table_radix64 = EdwardsBasepointTableRadix64::create(P);
let table_radix128 = EdwardsBasepointTableRadix128::create(P);
let table_radix256 = EdwardsBasepointTableRadix256::create(P);
let aP = (&constants::ED25519_BASEPOINT_TABLE * &a).compress();
let aP16 = (&table_radix16 * &a).compress();
@ -1385,8 +1385,8 @@ mod test {
fn basepoint_projective_extended_round_trip() {
assert_eq!(
constants::ED25519_BASEPOINT_POINT
.to_projective()
.to_extended()
.as_projective()
.as_extended()
.compress(),
constants::ED25519_BASEPOINT_COMPRESSED
);
@ -1406,12 +1406,12 @@ mod test {
let BASE = constants::ED25519_BASEPOINT_POINT;
let s1 = Scalar::from(999u64);
let P1 = &BASE * &s1;
let P1 = BASE * s1;
let s2 = Scalar::from(333u64);
let P2 = &BASE * &s2;
let P2 = BASE * s2;
let vec = vec![P1.clone(), P2.clone()];
let vec = vec![P1, P2];
let sum: EdwardsPoint = vec.iter().sum();
assert_eq!(sum, P1 + P2);
@ -1427,7 +1427,7 @@ mod test {
let mapped = vec.iter().map(|x| x * s);
let sum: EdwardsPoint = mapped.sum();
assert_eq!(sum, &P1 * &s + &P2 * &s);
assert_eq!(sum, P1 * s + P2 * s);
}
/// Test that the conditional assignment trait works for AffineNielsPoints.
@ -1435,7 +1435,7 @@ mod test {
fn conditional_assign_for_affine_niels_point() {
let id = AffineNielsPoint::identity();
let mut p1 = AffineNielsPoint::identity();
let bp = constants::ED25519_BASEPOINT_POINT.to_affine_niels();
let bp = constants::ED25519_BASEPOINT_POINT.as_affine_niels();
p1.conditional_assign(&bp, Choice::from(0));
assert_eq!(p1, id);
@ -1492,8 +1492,8 @@ mod test {
let G: EdwardsPoint = constants::ED25519_BASEPOINT_POINT;
let s: Scalar = A_SCALAR;
let P1 = &G * &s;
let P2 = &s * &G;
let P1 = G * s;
let P2 = s * G;
assert!(P1.compress().to_bytes() == P2.compress().to_bytes());
}

View file

@ -95,7 +95,7 @@ impl ConstantTimeEq for FieldElement {
/// internal representation is not canonical, the field elements
/// are normalized to wire format before comparison.
fn ct_eq(&self, other: &FieldElement) -> Choice {
self.to_bytes().ct_eq(&other.to_bytes())
self.as_bytes().ct_eq(&other.as_bytes())
}
}
@ -108,7 +108,7 @@ impl FieldElement {
///
/// If negative, return `Choice(1)`. Otherwise, return `Choice(0)`.
pub fn is_negative(&self) -> Choice {
let bytes = self.to_bytes();
let bytes = self.as_bytes();
(bytes[0] & 1).into()
}
@ -119,7 +119,7 @@ impl FieldElement {
/// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`.
pub fn is_zero(&self) -> Choice {
let zero = [0u8; 32];
let bytes = self.to_bytes();
let bytes = self.as_bytes();
bytes.ct_eq(&zero)
}
@ -212,6 +212,7 @@ impl FieldElement {
///
/// This function returns zero on input zero.
#[rustfmt::skip] // keep alignment of explanatory comments
#[allow(clippy::let_and_return)]
pub fn invert(&self) -> FieldElement {
// The bits of p-2 = 2^255 -19 -2 are 11010111111...11.
//
@ -225,6 +226,7 @@ impl FieldElement {
/// Raise this field element to the power (p-5)/8 = 2^252 -3.
#[rustfmt::skip] // keep alignment of explanatory comments
#[allow(clippy::let_and_return)]
fn pow_p58(&self) -> FieldElement {
// The bits of (p-5)/8 are 101111.....11.
//
@ -489,10 +491,10 @@ mod test {
// Decode to a field element
let one = FieldElement::from_bytes(&one_encoded_wrongly_bytes);
// .. then check that the encoding is correct
let one_bytes = one.to_bytes();
let one_bytes = one.as_bytes();
assert_eq!(one_bytes[0], 1);
for i in 1..32 {
assert_eq!(one_bytes[i], 0);
for byte in &one_bytes[1..] {
assert_eq!(*byte, 0);
}
}

View file

@ -49,7 +49,10 @@
// affine and projective cakes and eat both of them too.
#![allow(non_snake_case)]
use core::ops::{Mul, MulAssign};
use core::{
hash::{Hash, Hasher},
ops::{Mul, MulAssign},
};
use crate::constants::{APLUS2_OVER_FOUR, MONTGOMERY_A, MONTGOMERY_A_NEG};
use crate::edwards::{CompressedEdwardsY, EdwardsPoint};
@ -66,7 +69,7 @@ use zeroize::Zeroize;
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
/// Curve25519 or its twist.
#[derive(Copy, Clone, Debug, Hash)]
#[derive(Copy, Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MontgomeryPoint(pub [u8; 32]);
@ -80,12 +83,6 @@ impl ConstantTimeEq for MontgomeryPoint {
}
}
impl Default for MontgomeryPoint {
fn default() -> MontgomeryPoint {
MontgomeryPoint([0u8; 32])
}
}
impl PartialEq for MontgomeryPoint {
fn eq(&self, other: &MontgomeryPoint) -> bool {
self.ct_eq(other).unwrap_u8() == 1u8
@ -94,6 +91,17 @@ impl PartialEq for MontgomeryPoint {
impl Eq for MontgomeryPoint {}
// Equal MontgomeryPoints must hash to the same value. So we have to get them into a canonical
// encoding first
impl Hash for MontgomeryPoint {
fn hash<H: Hasher>(&self, state: &mut H) {
// Do a round trip through a `FieldElement`. `as_bytes` is guaranteed to give a canonical
// 32-byte encoding
let canonical_bytes = FieldElement::from_bytes(&self.0).as_bytes();
canonical_bytes.hash(state);
}
}
impl Identity for MontgomeryPoint {
/// Return the group identity element, which has order 4.
fn identity() -> MontgomeryPoint {
@ -109,7 +117,7 @@ impl Zeroize for MontgomeryPoint {
impl MontgomeryPoint {
/// View this `MontgomeryPoint` as an array of bytes.
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
@ -159,7 +167,7 @@ impl MontgomeryPoint {
let y = &(&u - &one) * &(&u + &one).invert();
let mut y_bytes = y.to_bytes();
let mut y_bytes = y.as_bytes();
y_bytes[31] ^= sign << 7;
CompressedEdwardsY(y_bytes).decompress()
@ -192,7 +200,7 @@ pub(crate) fn elligator_encode(r_0: &FieldElement) -> MontgomeryPoint {
let mut u = &d + &Atemp; /* d, or d+A if nonsquare */
u.conditional_negate(!eps_is_sq); /* d, or -d-A if nonsquare */
MontgomeryPoint(u.to_bytes())
MontgomeryPoint(u.as_bytes())
}
/// A `ProjectivePoint` holds a point on the projective line
@ -239,9 +247,9 @@ impl ProjectivePoint {
///
/// * \\( u = U / W \\) if \\( W \neq 0 \\);
/// * \\( 0 \\) if \\( W \eq 0 \\);
pub fn to_affine(&self) -> MontgomeryPoint {
pub fn as_affine(&self) -> MontgomeryPoint {
let u = &self.U * &self.W.invert();
MontgomeryPoint(u.to_bytes())
MontgomeryPoint(u.as_bytes())
}
}
@ -339,7 +347,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a MontgomeryPoint {
}
ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(bits[0] as u8));
x0.to_affine()
x0.as_affine()
}
}
@ -371,7 +379,7 @@ mod test {
#[test]
fn identity_in_different_coordinates() {
let id_projective = ProjectivePoint::identity();
let id_montgomery = id_projective.to_affine();
let id_montgomery = id_projective.as_affine();
assert!(id_montgomery == MontgomeryPoint::identity());
}
@ -427,14 +435,14 @@ mod test {
let one = FieldElement::one();
// u = 2 corresponds to a point on the twist.
let two = MontgomeryPoint((&one + &one).to_bytes());
let two = MontgomeryPoint((&one + &one).as_bytes());
assert!(two.to_edwards(0).is_none());
// u = -1 corresponds to a point on the twist, but should be
// checked explicitly because it's an exceptional point for the
// birational map. For instance, libsignal will accept it.
let minus_one = MontgomeryPoint((-&one).to_bytes());
let minus_one = MontgomeryPoint((-&one).as_bytes());
assert!(minus_one.to_edwards(0).is_none());
}

View file

@ -265,7 +265,7 @@ impl CompressedRistretto {
// original input, since our encoding routine is canonical.
let s = FieldElement::from_bytes(self.as_bytes());
let s_bytes_check = s.to_bytes();
let s_bytes_check = s.as_bytes();
let s_encoding_is_canonical = &s_bytes_check[..].ct_eq(self.as_bytes());
let s_is_negative = s.is_negative();
@ -490,7 +490,7 @@ impl RistrettoPoint {
let s_is_negative = s.is_negative();
s.conditional_negate(s_is_negative);
CompressedRistretto(s.to_bytes())
CompressedRistretto(s.as_bytes())
}
/// Double-and-compress a batch of points. The Ristretto encoding
@ -572,8 +572,8 @@ impl RistrettoPoint {
.iter()
.zip(invs.iter())
.map(|(state, inv): (&BatchCompressState, &FieldElement)| {
let Zinv = &state.eg * &inv;
let Tinv = &state.fh * &inv;
let Zinv = &state.eg * inv;
let Tinv = &state.fh * inv;
let mut magic = constants::INVSQRT_A_MINUS_D;
@ -601,7 +601,7 @@ impl RistrettoPoint {
let s_is_negative = s.is_negative();
s.conditional_negate(s_is_negative);
CompressedRistretto(s.to_bytes())
CompressedRistretto(s.as_bytes())
})
.collect()
}
@ -610,9 +610,9 @@ impl RistrettoPoint {
fn coset4(&self) -> [EdwardsPoint; 4] {
[
self.0,
&self.0 + &constants::EIGHT_TORSION[2],
&self.0 + &constants::EIGHT_TORSION[4],
&self.0 + &constants::EIGHT_TORSION[6],
self.0 + constants::EIGHT_TORSION[2],
self.0 + constants::EIGHT_TORSION[4],
self.0 + constants::EIGHT_TORSION[6],
]
}
@ -634,7 +634,7 @@ impl RistrettoPoint {
let one = FieldElement::one();
let r = i * &r_0.square();
let N_s = &(&r + &one) * &one_minus_d_sq;
let N_s = &(&r + &one) * one_minus_d_sq;
let D = &(&c - &(d * &r)) * &(&r + d);
let (Ns_D_is_sq, mut s) = FieldElement::sqrt_ratio_i(&N_s, &D);
@ -645,7 +645,7 @@ impl RistrettoPoint {
s.conditional_assign(&s_prime, !Ns_D_is_sq);
c.conditional_assign(&r, !Ns_D_is_sq);
let N_t = &(&(&c * &(&r - &one)) * &d_minus_one_sq) - &D;
let N_t = &(&(&c * &(&r - &one)) * d_minus_one_sq) - &D;
let s_sq = s.square();
use crate::backend::serial::curve_models::CompletedPoint;
@ -658,7 +658,7 @@ impl RistrettoPoint {
Y: &FieldElement::one() - &s_sq,
T: &FieldElement::one() + &s_sq,
}
.to_extended(),
.as_extended(),
)
}
@ -734,7 +734,7 @@ impl RistrettoPoint {
// dealing with generic arrays is clumsy, until const generics land
let output = hash.finalize();
let mut output_bytes = [0u8; 64];
output_bytes.copy_from_slice(&output.as_slice());
output_bytes.copy_from_slice(output.as_slice());
RistrettoPoint::from_uniform_bytes(&output_bytes)
}
@ -765,7 +765,7 @@ impl RistrettoPoint {
// Applying Elligator twice and adding the results ensures a
// uniform distribution.
&R_1 + &R_2
R_1 + R_2
}
}
@ -818,7 +818,7 @@ impl<'a, 'b> Add<&'b RistrettoPoint> for &'a RistrettoPoint {
type Output = RistrettoPoint;
fn add(self, other: &'b RistrettoPoint) -> RistrettoPoint {
RistrettoPoint(&self.0 + &other.0)
RistrettoPoint(self.0 + other.0)
}
}
@ -840,7 +840,7 @@ impl<'a, 'b> Sub<&'b RistrettoPoint> for &'a RistrettoPoint {
type Output = RistrettoPoint;
fn sub(self, other: &'b RistrettoPoint) -> RistrettoPoint {
RistrettoPoint(&self.0 - &other.0)
RistrettoPoint(self.0 - other.0)
}
}
@ -1180,8 +1180,8 @@ mod test {
let P = constants::RISTRETTO_BASEPOINT_POINT;
let s = Scalar::from(999u64);
let P1 = &P * &s;
let P2 = &s * &P;
let P1 = P * s;
let P2 = s * P;
assert!(P1.compress().as_bytes() == P2.compress().as_bytes());
}
@ -1193,12 +1193,12 @@ mod test {
let BASE = constants::RISTRETTO_BASEPOINT_POINT;
let s1 = Scalar::from(999u64);
let P1 = &BASE * &s1;
let P1 = BASE * s1;
let s2 = Scalar::from(333u64);
let P2 = &BASE * &s2;
let P2 = BASE * s2;
let vec = vec![P1.clone(), P2.clone()];
let vec = vec![P1, P2];
let sum: RistrettoPoint = vec.iter().sum();
assert_eq!(sum, P1 + P2);
@ -1214,13 +1214,13 @@ mod test {
let mapped = vec.iter().map(|x| x * s);
let sum: RistrettoPoint = mapped.sum();
assert_eq!(sum, &P1 * &s + &P2 * &s);
assert_eq!(sum, P1 * s + P2 * s);
}
#[test]
fn decompress_negative_s_fails() {
// constants::d is neg, so decompression should fail as |d| != d.
let bad_compressed = CompressedRistretto(constants::EDWARDS_D.to_bytes());
let bad_compressed = CompressedRistretto(constants::EDWARDS_D.as_bytes());
assert!(bad_compressed.decompress().is_none());
}
@ -1248,7 +1248,7 @@ mod test {
let bp_compressed_ristretto = constants::RISTRETTO_BASEPOINT_POINT.compress();
let bp_recaf = bp_compressed_ristretto.decompress().unwrap().0;
// Check that bp_recaf differs from bp by a point of order 4
let diff = &constants::RISTRETTO_BASEPOINT_POINT.0 - &bp_recaf;
let diff = &constants::RISTRETTO_BASEPOINT_POINT.0 - bp_recaf;
let diff4 = diff.mul_by_pow_2(2);
assert_eq!(diff4.compress(), CompressedEdwardsY::identity());
}
@ -1324,9 +1324,9 @@ mod test {
]),
];
let mut bp = RistrettoPoint::identity();
for i in 0..16 {
assert_eq!(bp.compress(), compressed[i]);
bp = &bp + &constants::RISTRETTO_BASEPOINT_POINT;
for point in compressed {
assert_eq!(bp.compress(), point);
bp += constants::RISTRETTO_BASEPOINT_POINT;
}
}
@ -1334,8 +1334,8 @@ mod test {
fn four_torsion_basepoint() {
let bp = constants::RISTRETTO_BASEPOINT_POINT;
let bp_coset = bp.coset4();
for i in 0..4 {
assert_eq!(bp, RistrettoPoint(bp_coset[i]));
for point in bp_coset {
assert_eq!(bp, RistrettoPoint(point));
}
}
@ -1345,8 +1345,8 @@ mod test {
let B = &constants::RISTRETTO_BASEPOINT_TABLE;
let P = B * &Scalar::random(&mut rng);
let P_coset = P.coset4();
for i in 0..4 {
assert_eq!(P, RistrettoPoint(P_coset[i]));
for point in P_coset {
assert_eq!(P, RistrettoPoint(point));
}
}

View file

@ -208,6 +208,7 @@ cfg_if! {
/// The `Scalar` struct holds an integer \\(s < 2\^{255} \\) which
/// represents an element of \\(\mathbb Z / \ell\\).
#[allow(clippy::derive_hash_xor_eq)]
#[derive(Copy, Clone, Hash)]
pub struct Scalar {
/// `bytes` is a little-endian byte encoding of an integer representing a scalar modulo the
@ -388,7 +389,7 @@ impl<'a> Neg for &'a Scalar {
}
}
impl<'a> Neg for Scalar {
impl Neg for Scalar {
type Output = Scalar;
fn neg(self) -> Scalar {
-&self
@ -398,6 +399,7 @@ impl<'a> Neg for Scalar {
impl ConditionallySelectable for Scalar {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
let mut bytes = [0u8; 32];
#[allow(clippy::needless_range_loop)]
for i in 0..32 {
bytes[i] = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice);
}
@ -797,7 +799,7 @@ impl Scalar {
use zeroize::Zeroizing;
let n = inputs.len();
let one: UnpackedScalar = Scalar::one().unpack().to_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.
@ -805,7 +807,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().to_montgomery();
let mut acc = Scalar::one().unpack().as_montgomery();
// Pass through the input vector, recording the previous
// products in the scratch space
@ -814,7 +816,7 @@ impl Scalar {
// Avoid unnecessary Montgomery multiplication in second pass by
// keeping inputs in Montgomery form
let tmp = input.unpack().to_montgomery();
let tmp = input.unpack().as_montgomery();
*input = tmp.pack();
acc = UnpackedScalar::montgomery_mul(&acc, &tmp);
}
@ -832,7 +834,7 @@ impl Scalar {
// in place
for (input, scratch) in inputs.iter_mut().rev().zip(scratch.iter().rev()) {
let tmp = UnpackedScalar::montgomery_mul(&acc, &input.unpack());
*input = UnpackedScalar::montgomery_mul(&acc, &scratch).pack();
*input = UnpackedScalar::montgomery_mul(&acc, scratch).pack();
acc = tmp;
}
@ -842,6 +844,7 @@ impl Scalar {
/// Get the bits of the scalar.
pub(crate) fn bits(&self) -> [i8; 256] {
let mut bits = [0i8; 256];
#[allow(clippy::needless_range_loop)]
for i in 0..256 {
// As i runs from 0..256, the bottom 3 bits index the bit,
// while the upper bits index the byte.
@ -942,14 +945,13 @@ impl Scalar {
// Construct a buffer of bits of the scalar, starting at bit `pos`
let u64_idx = pos / 64;
let bit_idx = pos % 64;
let bit_buf: u64;
if bit_idx < 64 - w {
let bit_buf: u64 = if bit_idx < 64 - w {
// This window's bits are contained in a single u64
bit_buf = x_u64[u64_idx] >> bit_idx;
x_u64[u64_idx] >> bit_idx
} else {
// Combine the current u64's bits with the bits from the next u64
bit_buf = (x_u64[u64_idx] >> bit_idx) | (x_u64[1 + u64_idx] << (64 - bit_idx));
}
(x_u64[u64_idx] >> bit_idx) | (x_u64[1 + u64_idx] << (64 - bit_idx))
};
// Add the carry into the current window
let window = carry + (bit_buf & window_mask);
@ -983,12 +985,13 @@ impl Scalar {
/// a = a\_0 + a\_1 16\^1 + \cdots + a_{63} 16\^{63},
/// $$
/// with \\(-8 \leq a_i < 8\\) for \\(0 \leq i < 63\\) and \\(-8 \leq a_{63} \leq 8\\).
pub(crate) fn to_radix_16(&self) -> [i8; 64] {
pub(crate) fn as_radix_16(&self) -> [i8; 64] {
debug_assert!(self[31] <= 127);
let mut output = [0i8; 64];
// Step 1: change radix.
// Convert from radix 256 (bytes) to radix 16 (nibbles)
#[allow(clippy::identity_op)]
#[inline(always)]
fn bot_half(x: u8) -> u8 {
(x >> 0) & 15
@ -1023,12 +1026,12 @@ impl Scalar {
debug_assert!(w <= 8);
let digits_count = match w {
4 => (256 + w - 1) / w as usize,
5 => (256 + w - 1) / w as usize,
6 => (256 + w - 1) / w as usize,
7 => (256 + w - 1) / w as usize,
4 => (256 + w - 1) / w,
5 => (256 + w - 1) / w,
6 => (256 + w - 1) / w,
7 => (256 + w - 1) / w,
// See comment in to_radix_2w on handling the terminal carry.
8 => (256 + w - 1) / w + 1 as usize,
8 => (256 + w - 1) / w + 1_usize,
_ => panic!("invalid radix parameter"),
};
@ -1053,12 +1056,12 @@ impl Scalar {
/// $$
/// with \\(-2\^w/2 \leq a_i < 2\^w/2\\) for \\(0 \leq i < (n-1)\\) and \\(-2\^w/2 \leq a_{n-1} \leq 2\^w/2\\).
///
pub(crate) fn to_radix_2w(&self, w: usize) -> [i8; 64] {
pub(crate) fn as_radix_2w(&self, w: usize) -> [i8; 64] {
debug_assert!(w >= 4);
debug_assert!(w <= 8);
if w == 4 {
return self.to_radix_16();
return self.as_radix_16();
}
// Scalar formatted as four `u64`s with carry bit packed into the highest bit.
@ -1070,7 +1073,8 @@ impl Scalar {
let mut carry = 0u64;
let mut digits = [0i8; 64];
let digits_count = (256 + w - 1) / w as usize;
let digits_count = (256 + w - 1) / w;
#[allow(clippy::needless_range_loop)]
for i in 0..digits_count {
// Construct a buffer of bits of the scalar, starting at `bit_offset`.
let bit_offset = i * w;
@ -1078,22 +1082,20 @@ impl Scalar {
let bit_idx = bit_offset % 64;
// Read the bits from the scalar
let bit_buf: u64;
if bit_idx < 64 - w || u64_idx == 3 {
let bit_buf: u64 = if bit_idx < 64 - w || u64_idx == 3 {
// This window's bits are contained in a single u64,
// or it's the last u64 anyway.
bit_buf = scalar64x4[u64_idx] >> bit_idx;
scalar64x4[u64_idx] >> bit_idx
} else {
// Combine the current u64's bits with the bits from the next u64
bit_buf =
(scalar64x4[u64_idx] >> bit_idx) | (scalar64x4[1 + u64_idx] << (64 - bit_idx));
}
(scalar64x4[u64_idx] >> bit_idx) | (scalar64x4[1 + u64_idx] << (64 - bit_idx))
};
// Read the actual coefficient value from the window
let coef = carry + (bit_buf & window_mask); // coef = [0, 2^r)
// Recenter coefficients from [0,2^w) to [-2^w/2, 2^w/2)
carry = (coef + (radix / 2) as u64) >> w;
carry = (coef + (radix / 2)) >> w;
digits[i] = ((coef as i64) - (carry << w) as i64) as i8;
}
@ -1152,16 +1154,17 @@ impl UnpackedScalar {
/// Pack the limbs of this `UnpackedScalar` into a `Scalar`.
fn pack(&self) -> Scalar {
Scalar {
bytes: self.to_bytes(),
bytes: self.as_bytes(),
}
}
/// Inverts an UnpackedScalar in Montgomery form.
#[rustfmt::skip] // keep alignment of addition chain and squarings
#[allow(clippy::just_underscores_and_digits)]
pub fn montgomery_invert(&self) -> UnpackedScalar {
// Uses the addition chain from
// https://briansmith.org/ecc-inversion-addition-chains-01#curve25519_scalar_inversion
let _1 = self;
let _1 = *self;
let _10 = _1.montgomery_square();
let _100 = _10.montgomery_square();
let _11 = UnpackedScalar::montgomery_mul(&_10, &_1);
@ -1215,7 +1218,7 @@ impl UnpackedScalar {
/// Inverts an UnpackedScalar not in Montgomery form.
pub fn invert(&self) -> UnpackedScalar {
self.to_montgomery().montgomery_invert().from_montgomery()
self.as_montgomery().montgomery_invert().from_montgomery()
}
}
@ -1364,8 +1367,8 @@ mod test {
tmp[0..32].copy_from_slice(&b_bytes[..]);
let also_b = Scalar::from_bytes_mod_order_wide(&tmp);
let expected_c = &a * &b;
let also_expected_c = &also_a * &also_b;
let expected_c = a * b;
let also_expected_c = also_a * also_b;
assert_eq!(c, expected_c);
assert_eq!(c, also_expected_c);
@ -1424,7 +1427,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]);
}
@ -1509,14 +1512,14 @@ mod test {
fn impl_add() {
let two = Scalar::from(2u64);
let one = Scalar::one();
let should_be_two = &one + &one;
let should_be_two = one + one;
assert_eq!(should_be_two, two);
}
#[allow(non_snake_case)]
#[test]
fn impl_mul() {
let should_be_X_times_Y = &X * &Y;
let should_be_X_times_Y = X * Y;
assert_eq!(should_be_X_times_Y, X_TIMES_Y);
}
@ -1584,7 +1587,7 @@ mod test {
#[test]
fn square() {
let expected = &X * &X;
let expected = X * X;
let actual = X.unpack().square().pack();
for i in 0..32 {
assert!(expected[i] == actual[i]);
@ -1624,7 +1627,7 @@ mod test {
fn invert() {
let inv_X = X.invert();
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());
}
@ -1641,7 +1644,7 @@ mod test {
#[test]
fn to_bytes_from_bytes_roundtrips() {
let unpacked = X.unpack();
let bytes = unpacked.to_bytes();
let bytes = unpacked.as_bytes();
let should_be_unpacked = UnpackedScalar::from_bytes(&bytes);
assert_eq!(should_be_unpacked.0, unpacked.0);
@ -1761,7 +1764,7 @@ mod test {
fn test_pippenger_radix_iter(scalar: Scalar, w: usize) {
let digits_count = Scalar::to_radix_2w_size_hint(w);
let digits = scalar.to_radix_2w(w);
let digits = scalar.as_radix_2w(w);
let radix = Scalar::from((1 << w) as u64);
let mut term = Scalar::one();

View file

@ -93,9 +93,9 @@ macro_rules! impl_lookup_table {
impl<'a> From<&'a EdwardsPoint> for $name<ProjectiveNielsPoint> {
fn from(P: &'a EdwardsPoint) -> Self {
let mut points = [P.to_projective_niels(); $size];
let mut points = [P.as_projective_niels(); $size];
for j in $conv_range {
points[j + 1] = (P + &points[j]).to_extended().to_projective_niels();
points[j + 1] = (P + &points[j]).as_extended().as_projective_niels();
}
$name(points)
}
@ -103,10 +103,10 @@ macro_rules! impl_lookup_table {
impl<'a> From<&'a EdwardsPoint> for $name<AffineNielsPoint> {
fn from(P: &'a EdwardsPoint) -> Self {
let mut points = [P.to_affine_niels(); $size];
let mut points = [P.as_affine_niels(); $size];
// XXX batch inversion would be good if perf mattered here
for j in $conv_range {
points[j + 1] = (P + &points[j]).to_extended().to_affine_niels()
points[j + 1] = (P + &points[j]).as_extended().as_affine_niels()
}
$name(points)
}
@ -157,10 +157,10 @@ impl<T: Debug> Debug for NafLookupTable5<T> {
impl<'a> From<&'a EdwardsPoint> for NafLookupTable5<ProjectiveNielsPoint> {
fn from(A: &'a EdwardsPoint) -> Self {
let mut Ai = [A.to_projective_niels(); 8];
let mut Ai = [A.as_projective_niels(); 8];
let A2 = A.double();
for i in 0..7 {
Ai[i + 1] = (&A2 + &Ai[i]).to_extended().to_projective_niels();
Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_projective_niels();
}
// Now Ai = [A, 3A, 5A, 7A, 9A, 11A, 13A, 15A]
NafLookupTable5(Ai)
@ -169,10 +169,10 @@ impl<'a> From<&'a EdwardsPoint> for NafLookupTable5<ProjectiveNielsPoint> {
impl<'a> From<&'a EdwardsPoint> for NafLookupTable5<AffineNielsPoint> {
fn from(A: &'a EdwardsPoint) -> Self {
let mut Ai = [A.to_affine_niels(); 8];
let mut Ai = [A.as_affine_niels(); 8];
let A2 = A.double();
for i in 0..7 {
Ai[i + 1] = (&A2 + &Ai[i]).to_extended().to_affine_niels();
Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_affine_niels();
}
// Now Ai = [A, 3A, 5A, 7A, 9A, 11A, 13A, 15A]
NafLookupTable5(Ai)
@ -194,9 +194,9 @@ impl<T: Copy> NafLookupTable8<T> {
impl<T: Debug> Debug for NafLookupTable8<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "NafLookupTable8([\n")?;
writeln!(f, "NafLookupTable8([")?;
for i in 0..64 {
write!(f, "\t{:?},\n", &self.0[i])?;
writeln!(f, "\t{:?},", &self.0[i])?;
}
write!(f, "])")
}
@ -204,10 +204,10 @@ impl<T: Debug> Debug for NafLookupTable8<T> {
impl<'a> From<&'a EdwardsPoint> for NafLookupTable8<ProjectiveNielsPoint> {
fn from(A: &'a EdwardsPoint) -> Self {
let mut Ai = [A.to_projective_niels(); 64];
let mut Ai = [A.as_projective_niels(); 64];
let A2 = A.double();
for i in 0..63 {
Ai[i + 1] = (&A2 + &Ai[i]).to_extended().to_projective_niels();
Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_projective_niels();
}
// Now Ai = [A, 3A, 5A, 7A, 9A, 11A, 13A, 15A, ..., 127A]
NafLookupTable8(Ai)
@ -216,10 +216,10 @@ impl<'a> From<&'a EdwardsPoint> for NafLookupTable8<ProjectiveNielsPoint> {
impl<'a> From<&'a EdwardsPoint> for NafLookupTable8<AffineNielsPoint> {
fn from(A: &'a EdwardsPoint) -> Self {
let mut Ai = [A.to_affine_niels(); 64];
let mut Ai = [A.as_affine_niels(); 64];
let A2 = A.double();
for i in 0..63 {
Ai[i + 1] = (&A2 + &Ai[i]).to_extended().to_affine_niels();
Ai[i + 1] = (&A2 + &Ai[i]).as_extended().as_affine_niels();
}
// Now Ai = [A, 3A, 5A, 7A, 9A, 11A, 13A, 15A, ..., 127A]
NafLookupTable8(Ai)