Change externally-exposed API to implement ConditionallySelectable

This commit is contained in:
Henry de Valence 2018-11-02 14:16:51 -07:00
parent 2e8f3c8f41
commit b0a190bd63
3 changed files with 56 additions and 46 deletions

View file

@ -92,17 +92,17 @@
// affine and projective cakes and eat both of them too. // affine and projective cakes and eat both of them too.
#![allow(non_snake_case)] #![allow(non_snake_case)]
use core::borrow::Borrow;
use core::fmt::Debug; use core::fmt::Debug;
use core::iter::Iterator; 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::{AddAssign, SubAssign};
use core::ops::{Mul, MulAssign}; use core::ops::{Mul, MulAssign};
use core::iter::Sum;
use core::borrow::Borrow;
use subtle::ConditionallyAssignable;
use subtle::ConditionallyNegatable;
use subtle::Choice; use subtle::Choice;
use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
use constants; use constants;
@ -328,10 +328,12 @@ impl CompressedEdwardsY {
impl Identity for EdwardsPoint { impl Identity for EdwardsPoint {
fn identity() -> EdwardsPoint { fn identity() -> EdwardsPoint {
EdwardsPoint{ X: FieldElement::zero(), EdwardsPoint {
Y: FieldElement::one(), X: FieldElement::zero(),
Z: FieldElement::one(), Y: FieldElement::one(),
T: FieldElement::zero() } Z: FieldElement::one(),
T: FieldElement::zero(),
}
} }
} }
@ -358,12 +360,14 @@ impl ValidityCheck for EdwardsPoint {
// Constant-time assignment // Constant-time assignment
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl ConditionallyAssignable for EdwardsPoint { impl ConditionallySelectable for EdwardsPoint {
fn conditional_assign(&mut self, other: &EdwardsPoint, choice: Choice) { fn conditional_select(a: &EdwardsPoint, b: &EdwardsPoint, choice: Choice) -> EdwardsPoint {
self.X.conditional_assign(&other.X, choice); EdwardsPoint {
self.Y.conditional_assign(&other.Y, choice); X: FieldElement::conditional_select(&a.X, &b.X, choice),
self.Z.conditional_assign(&other.Z, choice); Y: FieldElement::conditional_select(&a.Y, &b.Y, choice),
self.T.conditional_assign(&other.T, 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 { impl ConstantTimeEq for EdwardsPoint {
fn ct_eq(&self, other: &EdwardsPoint) -> Choice { 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())
} }
} }

View file

@ -157,28 +157,29 @@
//! [ristretto_main]: //! [ristretto_main]:
//! https://ristretto.group/ //! https://ristretto.group/
use core::borrow::Borrow;
use core::fmt::Debug; 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::{AddAssign, SubAssign};
use core::ops::{Mul, MulAssign}; 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::generic_array::typenum::U64;
use digest::Digest;
use constants; use constants;
use field::FieldElement; use field::FieldElement;
use subtle::Choice;
use subtle::ConditionallyAssignable; use subtle::ConditionallyAssignable;
use subtle::ConditionallyNegatable; use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
use subtle::Choice;
use edwards::EdwardsPoint;
use edwards::EdwardsBasepointTable; use edwards::EdwardsBasepointTable;
use edwards::EdwardsPoint;
#[allow(unused_imports)] #[allow(unused_imports)]
use prelude::*; use prelude::*;
@ -961,11 +962,11 @@ impl RistrettoBasepointTable {
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Constant-time conditional assignment // Constant-time conditional selection
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl ConditionallyAssignable for RistrettoPoint { impl ConditionallySelectable for RistrettoPoint {
/// Conditionally assign `other` to `self`, if `choice == Choice(1)`. /// Conditionally select between `self` and `other`.
/// ///
/// # Example /// # Example
/// ///
@ -973,7 +974,7 @@ impl ConditionallyAssignable for RistrettoPoint {
/// # extern crate subtle; /// # extern crate subtle;
/// # extern crate curve25519_dalek; /// # extern crate curve25519_dalek;
/// # /// #
/// use subtle::ConditionallyAssignable; /// use subtle::ConditionallySelectable;
/// use subtle::Choice; /// use subtle::Choice;
/// # /// #
/// # use curve25519_dalek::traits::Identity; /// # use curve25519_dalek::traits::Identity;
@ -986,17 +987,18 @@ impl ConditionallyAssignable for RistrettoPoint {
/// ///
/// let mut P = A; /// let mut P = A;
/// ///
/// P.conditional_assign(&B, Choice::from(0)); /// P = RistrettoPoint::conditional_select(&A, &B, Choice::from(0));
/// assert_eq!(P, A); /// assert_eq!(P, A);
/// P.conditional_assign(&B, Choice::from(1)); /// P = RistrettoPoint::conditional_select(&A, &B, Choice::from(1));
/// assert_eq!(P, B); /// assert_eq!(P, B);
/// # } /// # }
/// ``` /// ```
fn conditional_assign(&mut self, other: &RistrettoPoint, choice: Choice) { fn conditional_select(
self.0.X.conditional_assign(&other.0.X, choice); a: &RistrettoPoint,
self.0.Y.conditional_assign(&other.0.Y, choice); b: &RistrettoPoint,
self.0.Z.conditional_assign(&other.0.Z, choice); choice: Choice,
self.0.T.conditional_assign(&other.0.T, choice); ) -> RistrettoPoint {
RistrettoPoint(EdwardsPoint::conditional_select(&a.0, &b.0, choice))
} }
} }

View file

@ -138,26 +138,26 @@
//! The resulting `Scalar` has exactly the specified bit pattern, //! The resulting `Scalar` has exactly the specified bit pattern,
//! **except for the highest bit, which will be set to 0**. //! **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::fmt::Debug;
use core::iter::{Product, Sum};
use core::ops::Index;
use core::ops::Neg; use core::ops::Neg;
use core::ops::{Add, AddAssign}; use core::ops::{Add, AddAssign};
use core::ops::{Sub, SubAssign};
use core::ops::{Mul, MulAssign}; use core::ops::{Mul, MulAssign};
use core::ops::{Index}; use core::ops::{Sub, SubAssign};
use core::cmp::{Eq, PartialEq};
use core::iter::{Product, Sum};
use core::borrow::Borrow;
#[allow(unused_imports)] #[allow(unused_imports)]
use prelude::*; use prelude::*;
use rand::{Rng, CryptoRng}; use rand::{CryptoRng, Rng};
use digest::Digest;
use digest::generic_array::typenum::U64; use digest::generic_array::typenum::U64;
use digest::Digest;
use subtle::Choice; use subtle::Choice;
use subtle::ConditionallyAssignable; use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
use backend; use backend;
@ -343,11 +343,13 @@ impl<'a> Neg for Scalar {
} }
} }
impl ConditionallyAssignable for Scalar { impl ConditionallySelectable for Scalar {
fn conditional_assign(&mut self, other: &Scalar, choice: Choice) { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
let mut bytes = [0u8; 32];
for i in 0..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 }
} }
} }