From 97fe2f0bf410b781b0c036981cbc05fb20d3898b Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 20 Nov 2017 15:27:44 -0800 Subject: [PATCH] Try to connect the AVX2 backend to the ExtendedPoint frontend --- build.rs | 1 + src/edwards.rs | 65 ++++++++++++++++++++++++++++---------------------- src/lib.rs | 3 ++- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/build.rs b/build.rs index 4fba073..9604ec7 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ #![cfg_attr(feature = "nightly", feature(i128_type))] +#![cfg_attr(feature = "nightly", feature(cfg_target_feature))] #![allow(unused_variables)] #![allow(non_snake_case)] #![allow(dead_code)] diff --git a/src/edwards.rs b/src/edwards.rs index c831075..45354a0 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -432,38 +432,47 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint { /// For scalar multiplication of a basepoint, /// `EdwardsBasepointTable` is approximately 4x faster. fn mul(self, scalar: &'b Scalar) -> ExtendedPoint { - // Construct a lookup table of [P,2P,3P,4P,5P,6P,7P,8P] - let P = self.to_projective_niels(); - let mut lookup_table: [ProjectiveNielsPoint; 8] = [P; 8]; - for i in 0..7 { - lookup_table[i+1] = (self + &lookup_table[i]) - .to_extended().to_projective_niels(); + // If we built with AVX2, use the AVX2 backend. + #[cfg(all(target_feature = "avx2", feature = "avx2_backend"))] { + use backend::avx2::edwards as edwards_avx2; + let P_avx2 = edwards_avx2::ExtendedPoint::from(*self); + return ExtendedPoint::from(&P_avx2 * scalar); } + // Otherwise, proceed as normal: + #[cfg(not(all(target_feature = "avx2", feature = "avx2_backend")))] { + // Construct a lookup table of [P,2P,3P,4P,5P,6P,7P,8P] + let P = self.to_projective_niels(); + let mut lookup_table: [ProjectiveNielsPoint; 8] = [P; 8]; + for i in 0..7 { + lookup_table[i+1] = (self + &lookup_table[i]) + .to_extended().to_projective_niels(); + } - // Setting s = scalar, compute - // - // 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(); + // Setting s = scalar, compute + // + // 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(); - // Compute s*P as - // - // s*P = P*(s_0 + s_1*16^1 + s_2*16^2 + ... + s_63*16^63) - // s*P = P*s_0 + P*s_1*16^1 + P*s_2*16^2 + ... + P*s_63*16^63 - // s*P = P*s_0 + 16*(P*s_1 + 16*(P*s_2 + 16*( ... + P*s_63)...)) - // - // We sum right-to-left. - let mut Q = ExtendedPoint::identity(); - for i in (0..64).rev() { - // Q = 16*Q - Q = Q.mult_by_pow_2(4); - // R = s_i * Q - let R = select_precomputed_point(scalar_digits[i], &lookup_table); - // Q = Q + R - Q = (&Q + &R).to_extended(); + // Compute s*P as + // + // s*P = P*(s_0 + s_1*16^1 + s_2*16^2 + ... + s_63*16^63) + // s*P = P*s_0 + P*s_1*16^1 + P*s_2*16^2 + ... + P*s_63*16^63 + // s*P = P*s_0 + 16*(P*s_1 + 16*(P*s_2 + 16*( ... + P*s_63)...)) + // + // We sum right-to-left. + let mut Q = ExtendedPoint::identity(); + for i in (0..64).rev() { + // Q = 16*Q + Q = Q.mult_by_pow_2(4); + // R = s_i * Q + let R = select_precomputed_point(scalar_digits[i], &lookup_table); + // Q = Q + R + Q = (&Q + &R).to_extended(); + } + Q } - Q } } diff --git a/src/lib.rs b/src/lib.rs index 2106e88..3fcb3ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,11 +11,12 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "nightly", feature(i128_type))] +#![cfg_attr(feature = "nightly", feature(cfg_target_feature))] #![cfg_attr(feature = "bench", feature(test))] #![cfg_attr(all(feature = "nightly", feature = "std"), feature(zero_one))] #![allow(unused_features)] -//#![deny(missing_docs)] // refuse to compile if documentation is missing +#![deny(missing_docs)] // refuse to compile if documentation is missing //! # curve25519-dalek //!