test subtle 2.0

This commit is contained in:
Henry de Valence 2018-11-05 11:16:24 -08:00
parent 53fcd1060d
commit a116fd9679
12 changed files with 105 additions and 24 deletions

View file

@ -45,7 +45,7 @@ rand = { version = "0.5", default-features = false }
byteorder = { version = "^1.2.3", default-features = false, features = ["i128"] }
digest = { version = "0.8", default-features = false }
clear_on_drop = "=0.2.3"
subtle = { version = "1", default-features = false }
subtle = { version = "2", default-features = false }
serde = { version = "1.0", optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }
@ -54,7 +54,7 @@ rand = { version = "0.5", default-features = false }
byteorder = { version = "^1.2.3", default-features = false, features = ["i128"] }
digest = { version = "0.8", default-features = false }
clear_on_drop = "=0.2.3"
subtle = { version = "1", default-features = false }
subtle = { version = "2", default-features = false }
serde = { version = "1.0", optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }
@ -78,3 +78,6 @@ avx2_backend = ["nightly", "u64_backend", "packed_simd"]
# into the build script. Then, the build.rs emits the stage2_build
# feature before the main-stage compilation.
stage2_build = []
[patch.crates-io]
subtle = { git = "https://github.com/dalek-cryptography/subtle", branch = "fix-subtle-traits" }

View file

@ -80,6 +80,10 @@ impl ConditionallySelectable for ExtendedPoint {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
ExtendedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice))
}
fn conditional_assign(&mut self, other: &Self, choice: Choice) {
self.0.conditional_assign(&other.0, choice);
}
}
impl Default for ExtendedPoint {
@ -213,6 +217,10 @@ impl ConditionallySelectable for CachedPoint {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
CachedPoint(FieldElement32x4::conditional_select(&a.0, &b.0, choice))
}
fn conditional_assign(&mut self, other: &Self, choice: Choice) {
self.0.conditional_assign(&other.0, choice);
}
}
impl<'a> Neg for &'a CachedPoint {

View file

@ -155,13 +155,27 @@ impl ConditionallySelectable for FieldElement32x4 {
let mask = (-(choice.unwrap_u8() as i32)) as u32;
let mask_vec = u32x8::splat(mask);
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])),
a.0[0] ^ (mask_vec & (a.0[0] ^ b.0[0])),
a.0[1] ^ (mask_vec & (a.0[1] ^ b.0[1])),
a.0[2] ^ (mask_vec & (a.0[2] ^ b.0[2])),
a.0[3] ^ (mask_vec & (a.0[3] ^ b.0[3])),
a.0[4] ^ (mask_vec & (a.0[4] ^ b.0[4])),
])
}
fn conditional_assign(
&mut self,
other: &FieldElement32x4,
choice: Choice,
) {
let mask = (-(choice.unwrap_u8() as i32)) as u32;
let mask_vec = u32x8::splat(mask);
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]);
}
}
impl FieldElement32x4 {

View file

@ -16,13 +16,13 @@
//! of signed limbs.
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::ConditionallySelectable;
use subtle::Choice;
use subtle::ConditionallySelectable;
/// A `FieldElement32` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
@ -238,6 +238,32 @@ impl ConditionallySelectable for FieldElement32 {
u32::conditional_select(&a.0[9], &b.0[9], choice),
])
}
fn conditional_assign(&mut self, other: &FieldElement32, choice: Choice) {
self.0[0].conditional_assign(&other.0[0], choice);
self.0[1].conditional_assign(&other.0[1], choice);
self.0[2].conditional_assign(&other.0[2], choice);
self.0[3].conditional_assign(&other.0[3], choice);
self.0[4].conditional_assign(&other.0[4], choice);
self.0[5].conditional_assign(&other.0[5], choice);
self.0[6].conditional_assign(&other.0[6], choice);
self.0[7].conditional_assign(&other.0[7], choice);
self.0[8].conditional_assign(&other.0[8], choice);
self.0[9].conditional_assign(&other.0[9], choice);
}
fn conditional_swap(a: &mut FieldElement32, b: &mut FieldElement32, choice: Choice) {
u32::conditional_swap(&mut a.0[0], &mut b.0[0], choice);
u32::conditional_swap(&mut a.0[1], &mut b.0[1], choice);
u32::conditional_swap(&mut a.0[2], &mut b.0[2], choice);
u32::conditional_swap(&mut a.0[3], &mut b.0[3], choice);
u32::conditional_swap(&mut a.0[4], &mut b.0[4], choice);
u32::conditional_swap(&mut a.0[5], &mut b.0[5], choice);
u32::conditional_swap(&mut a.0[6], &mut b.0[6], choice);
u32::conditional_swap(&mut a.0[7], &mut b.0[7], choice);
u32::conditional_swap(&mut a.0[8], &mut b.0[8], choice);
u32::conditional_swap(&mut a.0[9], &mut b.0[9], choice);
}
}
impl FieldElement32 {

View file

@ -223,6 +223,22 @@ impl ConditionallySelectable for FieldElement64 {
u64::conditional_select(&a.0[4], &b.0[4], choice),
])
}
fn conditional_swap(a: &mut FieldElement64, b: &mut FieldElement64, choice: Choice) {
u64::conditional_swap(&mut a.0[0], &mut b.0[0], choice);
u64::conditional_swap(&mut a.0[1], &mut b.0[1], choice);
u64::conditional_swap(&mut a.0[2], &mut b.0[2], choice);
u64::conditional_swap(&mut a.0[3], &mut b.0[3], choice);
u64::conditional_swap(&mut a.0[4], &mut b.0[4], choice);
}
fn conditional_assign(&mut self, other: &FieldElement64, choice: Choice) {
self.0[0].conditional_assign(&other.0[0], choice);
self.0[1].conditional_assign(&other.0[1], choice);
self.0[2].conditional_assign(&other.0[2], choice);
self.0[3].conditional_assign(&other.0[3], choice);
self.0[4].conditional_assign(&other.0[4], choice);
}
}
impl FieldElement64 {

View file

@ -277,6 +277,13 @@ impl ConditionallySelectable for ProjectiveNielsPoint {
T2d: FieldElement::conditional_select(&a.T2d, &b.T2d, choice),
}
}
fn conditional_assign(&mut self, other: &Self, 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 AffineNielsPoint {
@ -287,6 +294,12 @@ impl ConditionallySelectable for AffineNielsPoint {
xy2d: FieldElement::conditional_select(&a.xy2d, &b.xy2d, choice),
}
}
fn conditional_assign(&mut self, other: &Self, 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.xy2d.conditional_assign(&other.xy2d, choice);
}
}
// ------------------------------------------------------------------------

View file

@ -903,7 +903,7 @@ impl Debug for EdwardsBasepointTable {
mod test {
use field::FieldElement;
use scalar::Scalar;
use subtle::ConditionallyAssignable;
use subtle::ConditionallySelectable;
use constants;
use super::*;

View file

@ -24,7 +24,7 @@
use core::cmp::{Eq, PartialEq};
use subtle::ConditionallyAssignable;
use subtle::ConditionallySelectable;
use subtle::ConditionallyNegatable;
use subtle::Choice;
use subtle::ConstantTimeEq;

View file

@ -51,15 +51,14 @@
use core::ops::{Mul, MulAssign};
use constants::APLUS2_OVER_FOUR;
use edwards::{CompressedEdwardsY, EdwardsPoint};
use field::FieldElement;
use edwards::{EdwardsPoint, CompressedEdwardsY};
use scalar::Scalar;
use traits::Identity;
use subtle::Choice;
use subtle::ConditionallySelectable;
use subtle::ConditionallySwappable;
use subtle::ConstantTimeEq;
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
@ -255,19 +254,22 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a MontgomeryPoint {
// Algorithm 8 of Costello-Smith 2017
let affine_u = FieldElement::from_bytes(&self.0);
let mut x0 = ProjectivePoint::identity();
let mut x1 = ProjectivePoint{ U: affine_u, W: FieldElement::one() };
let mut x1 = ProjectivePoint {
U: affine_u,
W: FieldElement::one(),
};
let bits: [i8; 256] = scalar.bits();
for i in (0..255).rev() {
let choice: u8 = (bits[i+1] ^ bits[i]) as u8;
let choice: u8 = (bits[i + 1] ^ bits[i]) as u8;
debug_assert!(choice == 0 || choice == 1);
x0.conditional_swap(&mut x1, choice.into());
ProjectivePoint::conditional_swap(&mut x0, &mut x1, choice.into());
differential_add_and_double(&mut x0, &mut x1, &affine_u);
}
x0.conditional_swap(&mut x1, Choice::from(bits[0] as u8));
ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(bits[0] as u8));
x0.to_affine()
}

View file

@ -173,9 +173,8 @@ use constants;
use field::FieldElement;
use subtle::Choice;
use subtle::ConditionallyAssignable;
use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
use subtle::ConditionallyNegatable;
use subtle::ConstantTimeEq;
use edwards::EdwardsBasepointTable;

View file

@ -983,7 +983,7 @@ impl Scalar {
/// # extern crate curve25519_dalek;
/// # extern crate subtle;
/// # use curve25519_dalek::scalar::Scalar;
/// # use subtle::ConditionallyAssignable;
/// # use subtle::ConditionallySelectable;
/// # fn main() {
/// // 2^255 - 1, since `from_bits` clears the high bit
/// let _2_255_minus_1 = Scalar::from_bits([0xff;32]);

View file

@ -15,7 +15,7 @@
use core::fmt::Debug;
use subtle::ConditionallyNegatable;
use subtle::ConditionallyAssignable;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
use subtle::Choice;
@ -59,7 +59,7 @@ unsafe impl<T> ZeroSafe for LookupTable<T> {}
impl<T> LookupTable<T>
where
T: Identity + ConditionallyAssignable + ConditionallyNegatable,
T: Identity + ConditionallySelectable + ConditionallyNegatable,
{
/// Given \\(-8 \leq x \leq 8\\), return \\(xP\\) in constant time.
pub fn select(&self, x: i8) -> T {