From b0a190bd63eaedfd8384dbb21830c290abe6b797 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Fri, 2 Nov 2018 14:16:51 -0700 Subject: [PATCH] Change externally-exposed API to implement ConditionallySelectable --- src/edwards.rs | 40 +++++++++++++++++++++++----------------- src/ristretto.rs | 38 ++++++++++++++++++++------------------ src/scalar.rs | 24 +++++++++++++----------- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/edwards.rs b/src/edwards.rs index a09ce45..ff5318e 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -70,7 +70,7 @@ //! The Edwards arithmetic is implemented using the “extended twisted //! coordinates” of Hisil, Wong, Carter, and Dawson, and the //! corresponding complete formulas. For more details, -//! see the [`curve_models` submodule][curve_models] +//! see the [`curve_models` submodule][curve_models] //! of the internal documentation. //! //! ## Validity Checking @@ -92,17 +92,17 @@ // affine and projective cakes and eat both of them too. #![allow(non_snake_case)] +use core::borrow::Borrow; use core::fmt::Debug; use core::iter::Iterator; -use core::ops::{Add, Sub, Neg}; +use core::iter::Sum; +use core::ops::{Add, Neg, Sub}; use core::ops::{AddAssign, SubAssign}; use core::ops::{Mul, MulAssign}; -use core::iter::Sum; -use core::borrow::Borrow; -use subtle::ConditionallyAssignable; -use subtle::ConditionallyNegatable; use subtle::Choice; +use subtle::ConditionallyNegatable; +use subtle::ConditionallySelectable; use subtle::ConstantTimeEq; use constants; @@ -328,10 +328,12 @@ impl CompressedEdwardsY { impl Identity for EdwardsPoint { fn identity() -> EdwardsPoint { - EdwardsPoint{ X: FieldElement::zero(), - Y: FieldElement::one(), - Z: FieldElement::one(), - T: FieldElement::zero() } + EdwardsPoint { + X: FieldElement::zero(), + Y: FieldElement::one(), + Z: FieldElement::one(), + T: FieldElement::zero(), + } } } @@ -358,12 +360,14 @@ impl ValidityCheck for EdwardsPoint { // Constant-time assignment // ------------------------------------------------------------------------ -impl ConditionallyAssignable for EdwardsPoint { - fn conditional_assign(&mut self, other: &EdwardsPoint, choice: Choice) { - 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); +impl ConditionallySelectable for EdwardsPoint { + fn conditional_select(a: &EdwardsPoint, b: &EdwardsPoint, choice: Choice) -> EdwardsPoint { + EdwardsPoint { + X: FieldElement::conditional_select(&a.X, &b.X, choice), + Y: FieldElement::conditional_select(&a.Y, &b.Y, choice), + Z: FieldElement::conditional_select(&a.Z, &b.Z, choice), + T: FieldElement::conditional_select(&a.T, &b.T, choice), + } } } @@ -373,7 +377,9 @@ impl ConditionallyAssignable for EdwardsPoint { impl ConstantTimeEq for EdwardsPoint { fn ct_eq(&self, other: &EdwardsPoint) -> Choice { - self.compress().as_bytes().ct_eq(other.compress().as_bytes()) + self.compress() + .as_bytes() + .ct_eq(other.compress().as_bytes()) } } diff --git a/src/ristretto.rs b/src/ristretto.rs index b34dbe8..7657902 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -157,28 +157,29 @@ //! [ristretto_main]: //! https://ristretto.group/ +use core::borrow::Borrow; use core::fmt::Debug; -use core::ops::{Add, Sub, Neg}; +use core::iter::Sum; +use core::ops::{Add, Neg, Sub}; use core::ops::{AddAssign, SubAssign}; use core::ops::{Mul, MulAssign}; -use core::iter::Sum; -use core::borrow::Borrow; -use rand::{Rng, CryptoRng}; +use rand::{CryptoRng, Rng}; -use digest::Digest; use digest::generic_array::typenum::U64; +use digest::Digest; use constants; use field::FieldElement; +use subtle::Choice; use subtle::ConditionallyAssignable; use subtle::ConditionallyNegatable; +use subtle::ConditionallySelectable; use subtle::ConstantTimeEq; -use subtle::Choice; -use edwards::EdwardsPoint; use edwards::EdwardsBasepointTable; +use edwards::EdwardsPoint; #[allow(unused_imports)] use prelude::*; @@ -961,11 +962,11 @@ impl RistrettoBasepointTable { } // ------------------------------------------------------------------------ -// Constant-time conditional assignment +// Constant-time conditional selection // ------------------------------------------------------------------------ -impl ConditionallyAssignable for RistrettoPoint { - /// Conditionally assign `other` to `self`, if `choice == Choice(1)`. +impl ConditionallySelectable for RistrettoPoint { + /// Conditionally select between `self` and `other`. /// /// # Example /// @@ -973,7 +974,7 @@ impl ConditionallyAssignable for RistrettoPoint { /// # extern crate subtle; /// # extern crate curve25519_dalek; /// # - /// use subtle::ConditionallyAssignable; + /// use subtle::ConditionallySelectable; /// use subtle::Choice; /// # /// # use curve25519_dalek::traits::Identity; @@ -986,17 +987,18 @@ impl ConditionallyAssignable for RistrettoPoint { /// /// let mut P = A; /// - /// P.conditional_assign(&B, Choice::from(0)); + /// P = RistrettoPoint::conditional_select(&A, &B, Choice::from(0)); /// assert_eq!(P, A); - /// P.conditional_assign(&B, Choice::from(1)); + /// P = RistrettoPoint::conditional_select(&A, &B, Choice::from(1)); /// assert_eq!(P, B); /// # } /// ``` - fn conditional_assign(&mut self, other: &RistrettoPoint, choice: Choice) { - 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); + fn conditional_select( + a: &RistrettoPoint, + b: &RistrettoPoint, + choice: Choice, + ) -> RistrettoPoint { + RistrettoPoint(EdwardsPoint::conditional_select(&a.0, &b.0, choice)) } } diff --git a/src/scalar.rs b/src/scalar.rs index 06c2f3c..eacd4e3 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -138,26 +138,26 @@ //! The resulting `Scalar` has exactly the specified bit pattern, //! **except for the highest bit, which will be set to 0**. +use core::borrow::Borrow; +use core::cmp::{Eq, PartialEq}; use core::fmt::Debug; +use core::iter::{Product, Sum}; +use core::ops::Index; use core::ops::Neg; use core::ops::{Add, AddAssign}; -use core::ops::{Sub, SubAssign}; use core::ops::{Mul, MulAssign}; -use core::ops::{Index}; -use core::cmp::{Eq, PartialEq}; -use core::iter::{Product, Sum}; -use core::borrow::Borrow; +use core::ops::{Sub, SubAssign}; #[allow(unused_imports)] use prelude::*; -use rand::{Rng, CryptoRng}; +use rand::{CryptoRng, Rng}; -use digest::Digest; use digest::generic_array::typenum::U64; +use digest::Digest; use subtle::Choice; -use subtle::ConditionallyAssignable; +use subtle::ConditionallySelectable; use subtle::ConstantTimeEq; use backend; @@ -343,11 +343,13 @@ impl<'a> Neg for Scalar { } } -impl ConditionallyAssignable for Scalar { - fn conditional_assign(&mut self, other: &Scalar, choice: Choice) { +impl ConditionallySelectable for Scalar { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut bytes = [0u8; 32]; for i in 0..32 { - self.bytes[i].conditional_assign(&other.bytes[i], choice); + bytes[i] = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); } + Scalar { bytes } } }