From 53fcd1060d79e7ebcb0eae0eddaed9ff0cb44a36 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Fri, 2 Nov 2018 14:17:43 -0700 Subject: [PATCH] Change internal API to use ConditionallySelectable --- src/backend/avx2/edwards.rs | 14 ++++++------- src/backend/avx2/field.rs | 20 ++++++++++++------ src/backend/u32/field.rs | 25 ++++++++++++++++------ src/backend/u64/field.rs | 26 +++++++++++++++-------- src/curve_models/mod.rs | 41 ++++++++++++++++++++----------------- src/montgomery.rs | 24 ++++++++++++++-------- 6 files changed, 94 insertions(+), 56 deletions(-) diff --git a/src/backend/avx2/edwards.rs b/src/backend/avx2/edwards.rs index 1510bda..cf9e881 100644 --- a/src/backend/avx2/edwards.rs +++ b/src/backend/avx2/edwards.rs @@ -38,7 +38,7 @@ use core::convert::From; use core::ops::{Add, Neg, Sub}; use subtle::Choice; -use subtle::ConditionallyAssignable; +use subtle::ConditionallySelectable; use edwards; use scalar_mul::window::{LookupTable, NafLookupTable5, NafLookupTable8}; @@ -76,9 +76,9 @@ impl From for edwards::EdwardsPoint { } } -impl ConditionallyAssignable for ExtendedPoint { - fn conditional_assign(&mut self, other: &ExtendedPoint, choice: Choice) { - self.0.conditional_assign(&other.0, choice); +impl ConditionallySelectable for ExtendedPoint { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + ExtendedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice)) } } @@ -209,9 +209,9 @@ impl Identity for CachedPoint { } } -impl ConditionallyAssignable for CachedPoint { - fn conditional_assign(&mut self, other: &CachedPoint, choice: Choice) { - self.0.conditional_assign(&other.0, choice); +impl ConditionallySelectable for CachedPoint { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + CachedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice)) } } diff --git a/src/backend/avx2/field.rs b/src/backend/avx2/field.rs index 6f4e1fd..a37ed50 100644 --- a/src/backend/avx2/field.rs +++ b/src/backend/avx2/field.rs @@ -144,15 +144,23 @@ pub enum Shuffle { pub struct FieldElement32x4(pub(crate) [u32x8; 5]); use subtle::Choice; -use subtle::ConditionallyAssignable; +use subtle::ConditionallySelectable; -impl ConditionallyAssignable for FieldElement32x4 { - fn conditional_assign(&mut self, other: &FieldElement32x4, choice: Choice) { +impl ConditionallySelectable for FieldElement32x4 { + fn conditional_select( + a: &FieldElement32x4, + b: &FieldElement32x4, + choice: Choice, + ) -> FieldElement32x4 { let mask = (-(choice.unwrap_u8() as i32)) as u32; let mask_vec = u32x8::splat(mask); - for i in 0..5 { - self.0[i] = self.0[i] ^ (mask_vec & (self.0[i] ^ other.0[i])); - } + FieldElement32x4([ + self.0[0] ^ (mask_vec & (self.0[0] ^ other.0[0])), + self.0[1] ^ (mask_vec & (self.0[1] ^ other.0[1])), + self.0[2] ^ (mask_vec & (self.0[2] ^ other.0[2])), + self.0[3] ^ (mask_vec & (self.0[3] ^ other.0[3])), + self.0[4] ^ (mask_vec & (self.0[4] ^ other.0[4])), + ]) } } diff --git a/src/backend/u32/field.rs b/src/backend/u32/field.rs index 9de460a..2a9f5bb 100644 --- a/src/backend/u32/field.rs +++ b/src/backend/u32/field.rs @@ -21,7 +21,7 @@ use core::ops::{Sub, SubAssign}; use core::ops::{Mul, MulAssign}; use core::ops::Neg; -use subtle::ConditionallyAssignable; +use subtle::ConditionallySelectable; use subtle::Choice; /// A `FieldElement32` represents an element of the field @@ -219,11 +219,24 @@ impl<'a> Neg for &'a FieldElement32 { } } -impl ConditionallyAssignable for FieldElement32 { - fn conditional_assign(&mut self, other: &FieldElement32, choice: Choice) { - for i in 0..10 { - self.0[i].conditional_assign(&other.0[i], choice); - } +impl ConditionallySelectable for FieldElement32 { + fn conditional_select( + a: &FieldElement32, + b: &FieldElement32, + choice: Choice, + ) -> FieldElement32 { + FieldElement32([ + u32::conditional_select(&a.0[0], &b.0[0], choice), + u32::conditional_select(&a.0[1], &b.0[1], choice), + u32::conditional_select(&a.0[2], &b.0[2], choice), + u32::conditional_select(&a.0[3], &b.0[3], choice), + u32::conditional_select(&a.0[4], &b.0[4], choice), + u32::conditional_select(&a.0[5], &b.0[5], choice), + u32::conditional_select(&a.0[6], &b.0[6], choice), + u32::conditional_select(&a.0[7], &b.0[7], choice), + u32::conditional_select(&a.0[8], &b.0[8], choice), + u32::conditional_select(&a.0[9], &b.0[9], choice), + ]) } } diff --git a/src/backend/u64/field.rs b/src/backend/u64/field.rs index 25a013e..9276af4 100644 --- a/src/backend/u64/field.rs +++ b/src/backend/u64/field.rs @@ -12,13 +12,13 @@ //! limbs with \\(128\\)-bit products. use core::fmt::Debug; -use core::ops::{Add, AddAssign}; -use core::ops::{Sub, SubAssign}; -use core::ops::{Mul, MulAssign}; use core::ops::Neg; +use core::ops::{Add, AddAssign}; +use core::ops::{Mul, MulAssign}; +use core::ops::{Sub, SubAssign}; -use subtle::ConditionallyAssignable; use subtle::Choice; +use subtle::ConditionallySelectable; /// A `FieldElement64` represents an element of the field /// \\( \mathbb Z / (2\^{255} - 19)\\). @@ -209,11 +209,19 @@ impl<'a> Neg for &'a FieldElement64 { } } -impl ConditionallyAssignable for FieldElement64 { - fn conditional_assign(&mut self, other: &FieldElement64, choice: Choice) { - for i in 0..5 { - self.0[i].conditional_assign(&other.0[i], choice); - } +impl ConditionallySelectable for FieldElement64 { + fn conditional_select( + a: &FieldElement64, + b: &FieldElement64, + choice: Choice, + ) -> FieldElement64 { + FieldElement64([ + u64::conditional_select(&a.0[0], &b.0[0], choice), + u64::conditional_select(&a.0[1], &b.0[1], choice), + u64::conditional_select(&a.0[2], &b.0[2], choice), + u64::conditional_select(&a.0[3], &b.0[3], choice), + u64::conditional_select(&a.0[4], &b.0[4], choice), + ]) } } diff --git a/src/curve_models/mod.rs b/src/curve_models/mod.rs index 3f68132..7c472c9 100644 --- a/src/curve_models/mod.rs +++ b/src/curve_models/mod.rs @@ -124,15 +124,15 @@ #![allow(non_snake_case)] use core::fmt::Debug; -use core::ops::{Add, Sub, Neg}; +use core::ops::{Add, Neg, Sub}; -use subtle::ConditionallyAssignable; use subtle::Choice; +use subtle::ConditionallySelectable; use constants; -use field::FieldElement; use edwards::EdwardsPoint; +use field::FieldElement; use traits::ValidityCheck; // ------------------------------------------------------------------------ @@ -204,7 +204,7 @@ use traits::Identity; impl Identity for ProjectivePoint { fn identity() -> ProjectivePoint { - ProjectivePoint{ + ProjectivePoint { X: FieldElement::zero(), Y: FieldElement::one(), Z: FieldElement::one(), @@ -268,21 +268,24 @@ impl ValidityCheck for ProjectivePoint { // Constant-time assignment // ------------------------------------------------------------------------ -impl ConditionallyAssignable for ProjectiveNielsPoint { - fn conditional_assign(&mut self, other: &ProjectiveNielsPoint, choice: Choice) { - self.Y_plus_X.conditional_assign(&other.Y_plus_X, choice); - self.Y_minus_X.conditional_assign(&other.Y_minus_X, choice); - self.Z.conditional_assign(&other.Z, choice); - self.T2d.conditional_assign(&other.T2d, choice); +impl ConditionallySelectable for ProjectiveNielsPoint { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + ProjectiveNielsPoint { + Y_plus_X: FieldElement::conditional_select(&a.Y_plus_X, &b.Y_plus_X, choice), + Y_minus_X: FieldElement::conditional_select(&a.Y_minus_X, &b.Y_minus_X, choice), + Z: FieldElement::conditional_select(&a.Z, &b.Z, choice), + T2d: FieldElement::conditional_select(&a.T2d, &b.T2d, choice), + } } } -impl ConditionallyAssignable for AffineNielsPoint { - fn conditional_assign(&mut self, other: &AffineNielsPoint, choice: Choice) { - // PreComputedGroupElementCMove() - self.y_plus_x.conditional_assign(&other.y_plus_x, choice); - self.y_minus_x.conditional_assign(&other.y_minus_x, choice); - self.xy2d.conditional_assign(&other.xy2d, choice); +impl ConditionallySelectable for AffineNielsPoint { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + AffineNielsPoint { + y_plus_x: FieldElement::conditional_select(&a.y_plus_x, &b.y_plus_x, choice), + y_minus_x: FieldElement::conditional_select(&a.y_minus_x, &b.y_minus_x, choice), + xy2d: FieldElement::conditional_select(&a.xy2d, &b.xy2d, choice), + } } } @@ -296,7 +299,7 @@ impl ProjectivePoint { /// /// This costs \\(3 \mathrm M + 1 \mathrm S\\). pub fn to_extended(&self) -> EdwardsPoint { - EdwardsPoint{ + EdwardsPoint { X: &self.X * &self.Z, Y: &self.Y * &self.Z, Z: self.Z.square(), @@ -311,7 +314,7 @@ impl CompletedPoint { /// /// This costs \\(3 \mathrm M \\). pub fn to_projective(&self) -> ProjectivePoint { - ProjectivePoint{ + ProjectivePoint { X: &self.X * &self.T, Y: &self.Y * &self.Z, Z: &self.Z * &self.T, @@ -323,7 +326,7 @@ impl CompletedPoint { /// /// This costs \\(4 \mathrm M \\). pub fn to_extended(&self) -> EdwardsPoint { - EdwardsPoint{ + EdwardsPoint { X: &self.X * &self.T, Y: &self.Y * &self.Z, Z: &self.Z * &self.T, diff --git a/src/montgomery.rs b/src/montgomery.rs index fe7423b..76ef4e2 100644 --- a/src/montgomery.rs +++ b/src/montgomery.rs @@ -29,7 +29,7 @@ //! //! Scalar multiplication on `MontgomeryPoint`s is provided by the `*` //! operator, which implements the Montgomery ladder. -//! +//! //! # Edwards Conversion //! //! The \\(2\\)-to-\\(1\\) map from the Edwards model to the Montgomery @@ -57,10 +57,10 @@ use scalar::Scalar; use traits::Identity; -use subtle::ConditionallyAssignable; +use subtle::Choice; +use subtle::ConditionallySelectable; use subtle::ConditionallySwappable; use subtle::ConstantTimeEq; -use subtle::Choice; /// Holds the \\(u\\)-coordinate of a point on the Montgomery form of /// Curve25519 or its twist. @@ -141,7 +141,7 @@ impl MontgomeryPoint { /// \\( \mathbb P(\mathbb F\_p) \\), which we identify with the Kummer /// line of the Montgomery curve. #[derive(Copy, Clone, Debug)] -struct ProjectivePoint{ +struct ProjectivePoint { pub U: FieldElement, pub W: FieldElement, } @@ -161,10 +161,16 @@ impl Default for ProjectivePoint { } } -impl ConditionallyAssignable for ProjectivePoint { - fn conditional_assign(&mut self, that: &ProjectivePoint, choice: Choice) { - self.U.conditional_assign(&that.U, choice); - self.W.conditional_assign(&that.W, choice); +impl ConditionallySelectable for ProjectivePoint { + fn conditional_select( + a: &ProjectivePoint, + b: &ProjectivePoint, + choice: Choice, + ) -> ProjectivePoint { + ProjectivePoint { + U: FieldElement::conditional_select(&a.U, &b.U, choice), + W: FieldElement::conditional_select(&a.W, &b.W, choice), + } } } @@ -196,7 +202,7 @@ impl ProjectivePoint { /// (U\_Q : W\_Q) \gets u(P + Q). /// $$ fn differential_add_and_double( - P: &mut ProjectivePoint, + P: &mut ProjectivePoint, Q: &mut ProjectivePoint, affine_PmQ: &FieldElement, ) {