mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
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:
parent
03b8668b29
commit
e01bb1bdc6
31 changed files with 383 additions and 283 deletions
29
.github/workflows/rust.yml
vendored
29
.github/workflows/rust.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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)`.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
14
src/field.rs
14
src/field.rs
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue