mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Merge branch 'feature/scalarmult-lhs' into develop
This commit is contained in:
commit
4a646806b8
3 changed files with 137 additions and 2 deletions
92
src/curve.rs
92
src/curve.rs
|
|
@ -84,6 +84,8 @@ use core::ops::{Mul, MulAssign};
|
|||
use core::ops::Index;
|
||||
|
||||
use constants;
|
||||
#[cfg(feature = "yolocrypto")]
|
||||
use decaf::DecafPoint;
|
||||
use field::FieldElement;
|
||||
use scalar::Scalar;
|
||||
use subtle::arrays_equal_ct;
|
||||
|
|
@ -445,6 +447,15 @@ impl CTAssignable for AffineNielsPoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl CTAssignable for ExtendedPoint {
|
||||
fn conditional_assign(&mut self, other: &ExtendedPoint, choice: u8) {
|
||||
self.X.conditional_assign(&other.X, choice);
|
||||
self.Y.conditional_assign(&other.Y, choice);
|
||||
self.Z.conditional_assign(&other.Z, choice);
|
||||
self.T.conditional_assign(&other.T, choice);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constant-time Equality
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -817,6 +828,29 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a ExtendedPoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Mul<&'b ExtendedPoint> for &'a Scalar {
|
||||
type Output = ExtendedPoint;
|
||||
|
||||
/// Scalar multiplication: compute `self * point`.
|
||||
///
|
||||
/// Uses a window of size 4. Note: for scalar multiplication of
|
||||
/// the basepoint, `basepoint_mult` is approximately 4x faster.
|
||||
fn mul(self, point: &'b ExtendedPoint) -> ExtendedPoint {
|
||||
point * &self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "yolocrypto")]
|
||||
impl<'a, 'b> Mul<&'b DecafPoint> for &'a Scalar {
|
||||
type Output = DecafPoint;
|
||||
|
||||
/// Scalar multiplication: compute `self * scalar`.
|
||||
fn mul(self, point: &'b DecafPoint) -> DecafPoint {
|
||||
DecafPoint(self * &point.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Precomputation
|
||||
#[derive(Clone)]
|
||||
pub struct EdwardsBasepointTable(pub [[AffineNielsPoint; 8]; 32]);
|
||||
|
|
@ -870,6 +904,39 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a EdwardsBasepointTable {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Mul<&'a EdwardsBasepointTable> for &'b Scalar {
|
||||
type Output = ExtendedPoint;
|
||||
|
||||
/// Construct an `ExtendedPoint` by via this `Scalar` times
|
||||
/// a the basepoint, `B` included in a precomputed `basepoint_table`.
|
||||
///
|
||||
/// Precondition: this scalar must be reduced.
|
||||
///
|
||||
/// The computation proceeds as follows, as described on page 13
|
||||
/// of the Ed25519 paper. Write this scalar `a` in radix 16 with
|
||||
/// coefficients in [-8,8), i.e.,
|
||||
///
|
||||
/// a = a_0 + a_1*16^1 + ... + a_63*16^63,
|
||||
///
|
||||
/// with -8 ≤ a_i < 8. Then
|
||||
///
|
||||
/// a*B = a_0*B + a_1*16^1*B + ... + a_63*16^63*B.
|
||||
///
|
||||
/// Grouping even and odd coefficients gives
|
||||
///
|
||||
/// a*B = a_0*16^0*B + a_2*16^2*B + ... + a_62*16^62*B
|
||||
/// + a_1*16^1*B + a_3*16^3*B + ... + a_63*16^63*B
|
||||
/// = (a_0*16^0*B + a_2*16^2*B + ... + a_62*16^62*B)
|
||||
/// + 16*(a_1*16^0*B + a_3*16^2*B + ... + a_63*16^62*B).
|
||||
///
|
||||
/// We then use the `select_precomputed_point` function, which
|
||||
/// takes `-8 ≤ x < 8` and `[16^2i * B, ..., 8 * 16^2i * B]`,
|
||||
/// and returns `x * 16^2i * B` in constant time.
|
||||
fn mul(self, basepoint_table: &'a EdwardsBasepointTable) -> ExtendedPoint {
|
||||
basepoint_table * &self
|
||||
}
|
||||
}
|
||||
|
||||
impl EdwardsBasepointTable {
|
||||
/// Create a table of precomputed multiples of `basepoint`.
|
||||
pub fn create(basepoint: &ExtendedPoint) -> EdwardsBasepointTable {
|
||||
|
|
@ -1150,6 +1217,8 @@ pub mod vartime {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[cfg(feature = "yolocrypto")]
|
||||
use decaf::DecafPoint;
|
||||
use field::FieldElement;
|
||||
use scalar::Scalar;
|
||||
use subtle::CTAssignable;
|
||||
|
|
@ -1459,6 +1528,29 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scalarmult_extended_point_works_both_ways() {
|
||||
let G: ExtendedPoint = constants::ED25519_BASEPOINT;
|
||||
let s: Scalar = A_SCALAR;
|
||||
|
||||
let P1 = &G * &s;
|
||||
let P2 = &s * &G;
|
||||
|
||||
assert!(P1.compress_edwards().to_bytes() == P2.compress_edwards().to_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "yolocrypto")]
|
||||
fn scalarmult_decafpoint_works_both_ways() {
|
||||
let P: DecafPoint = DecafPoint(constants::ED25519_BASEPOINT);
|
||||
let s: Scalar = A_SCALAR;
|
||||
|
||||
let P1 = &P * &s;
|
||||
let P2 = &s * &P;
|
||||
|
||||
assert!(P1.compress().as_bytes() == P2.compress().as_bytes());
|
||||
}
|
||||
|
||||
mod vartime {
|
||||
use super::super::*;
|
||||
use super::{A_SCALAR, B_SCALAR, A_TIMES_BASEPOINT, DOUBLE_SCALAR_MULT_RESULT};
|
||||
|
|
|
|||
40
src/decaf.rs
40
src/decaf.rs
|
|
@ -271,6 +271,14 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a DecafBasepointTable {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Mul<&'a DecafBasepointTable> for &'b Scalar {
|
||||
type Output = DecafPoint;
|
||||
|
||||
fn mul(self, basepoint_table: &'a DecafBasepointTable) -> DecafPoint {
|
||||
DecafPoint(self * &basepoint_table.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl DecafBasepointTable {
|
||||
/// Create a precomputed table of multiples of the given `basepoint`.
|
||||
pub fn create(basepoint: &DecafPoint) -> DecafBasepointTable {
|
||||
|
|
@ -283,6 +291,38 @@ impl DecafBasepointTable {
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constant-time conditional assignment
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
impl CTAssignable for DecafPoint {
|
||||
/// Conditionally assign `other` to `self`, if `choice == 1u8`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use curve25519_dalek::curve::Identity;
|
||||
/// # use curve25519_dalek::decaf::DecafPoint;
|
||||
/// # use curve25519_dalek::subtle::CTAssignable;
|
||||
/// # use curve25519_dalek::constants;
|
||||
/// let A = DecafPoint::identity();
|
||||
/// let B = constants::DECAF_ED25519_BASEPOINT;
|
||||
///
|
||||
/// let mut P = A;
|
||||
///
|
||||
/// P.conditional_assign(&B, 0u8);
|
||||
/// assert!(P == A);
|
||||
/// P.conditional_assign(&B, 1u8);
|
||||
/// assert!(P == B);
|
||||
/// ```
|
||||
fn conditional_assign(&mut self, other: &DecafPoint, choice: u8) {
|
||||
self.0.X.conditional_assign(&other.0.X, choice);
|
||||
self.0.Y.conditional_assign(&other.0.Y, choice);
|
||||
self.0.Z.conditional_assign(&other.0.Z, choice);
|
||||
self.0.T.conditional_assign(&other.0.T, choice);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Debug traits
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -775,10 +775,11 @@ mod test {
|
|||
assert_eq!(should_be_one, Scalar::one());
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[test]
|
||||
fn impl_mul() {
|
||||
let should_be_X_TIMES_Y = &X * &Y;
|
||||
assert_eq!(should_be_X_TIMES_Y, X_TIMES_Y);
|
||||
let should_be_X_times_Y = &X * &Y;
|
||||
assert_eq!(should_be_X_times_Y, X_TIMES_Y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -809,6 +810,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[test]
|
||||
fn invert() {
|
||||
let inv_X = X.invert();
|
||||
|
|
@ -817,6 +819,7 @@ mod test {
|
|||
}
|
||||
|
||||
// Negating a scalar twice should result in the original scalar.
|
||||
#[allow(non_snake_case)]
|
||||
#[test]
|
||||
fn neg_twice_is_identity() {
|
||||
let negative_X = -&X;
|
||||
|
|
|
|||
Loading…
Reference in a new issue