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

@ -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())
}
}

View file

@ -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))
}
}

View file

@ -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 }
}
}