Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve points being used in data structures #220

Closed
wants to merge 12 commits into from
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "curve25519-dalek"
version = "0.21.0"
version = "1.0.0-pre.0"
authors = ["Isis Lovecruft <[email protected]>",
"Henry de Valence <[email protected]>"]
readme = "README.md"
Expand Down Expand Up @@ -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.0.0-pre.0", default-features = false }
serde = { version = "1.0", optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }

Expand All @@ -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.0.0-pre.0", default-features = false }
serde = { version = "1.0", optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }

Expand All @@ -78,3 +78,4 @@ 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 = []

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ make doc-internal
To import `curve25519-dalek`, add the following to the dependencies section of
your project's `Cargo.toml`:
```toml
curve25519-dalek = "0.21"
curve25519-dalek = "1.0.0-pre.0"
```
Then import the crate as:
```rust,no_run
Expand Down
18 changes: 13 additions & 5 deletions src/backend/avx2/edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -76,8 +76,12 @@ impl From<ExtendedPoint> for edwards::EdwardsPoint {
}
}

impl ConditionallyAssignable for ExtendedPoint {
fn conditional_assign(&mut self, other: &ExtendedPoint, choice: Choice) {
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);
}
}
Expand Down Expand Up @@ -209,8 +213,12 @@ impl Identity for CachedPoint {
}
}

impl ConditionallyAssignable for CachedPoint {
fn conditional_assign(&mut self, other: &CachedPoint, choice: Choice) {
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);
}
}
Expand Down
34 changes: 28 additions & 6 deletions src/backend/avx2/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,37 @@ 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([
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]);
}
}

Expand Down
53 changes: 46 additions & 7 deletions src/backend/u32/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
//! of signed limbs.

use core::fmt::Debug;
use core::ops::Neg;
use core::ops::{Add, AddAssign};
use core::ops::{Sub, SubAssign};
use core::ops::{Mul, MulAssign};
use core::ops::Neg;
use core::ops::{Sub, SubAssign};

use subtle::ConditionallyAssignable;
use subtle::Choice;
use subtle::ConditionallySelectable;

/// A `FieldElement32` represents an element of the field
/// \\( \mathbb Z / (2\^{255} - 19)\\).
Expand Down Expand Up @@ -219,11 +219,50 @@ impl<'a> Neg for &'a FieldElement32 {
}
}

impl ConditionallyAssignable for FieldElement32 {
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),
])
}

fn conditional_assign(&mut self, other: &FieldElement32, choice: Choice) {
for i in 0..10 {
self.0[i].conditional_assign(&other.0[i], 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);
}
}

Expand Down
38 changes: 31 additions & 7 deletions src/backend/u64/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
//! limbs with \\(128\\)-bit products.

use core::fmt::Debug;
use core::ops::Neg;
use core::ops::{Add, AddAssign};
use core::ops::{Sub, SubAssign};
use core::ops::{Mul, MulAssign};
use core::ops::Neg;
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)\\).
Expand Down Expand Up @@ -209,11 +209,35 @@ impl<'a> Neg for &'a FieldElement64 {
}
}

impl ConditionallyAssignable for FieldElement64 {
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),
])
}

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) {
for i in 0..5 {
self.0[i].conditional_assign(&other.0[i], 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);
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,13 @@ mod test {
}
}

/// Test that SQRT_M1 is the positive square root of -1
#[test]
/// Test that SQRT_M1 is a square root of -1
fn test_sqrt_minus_one() {
let minus_one = FieldElement::minus_one();
let sqrt_m1_sq = &constants::SQRT_M1 * &constants::SQRT_M1;
assert_eq!(minus_one, sqrt_m1_sq);
assert_eq!(constants::SQRT_M1.is_negative().unwrap_u8(), 0);
}

#[test]
Expand All @@ -143,8 +144,6 @@ mod test {
let (was_nonzero_square, invsqrt_m1) = minus_one.invsqrt();
assert_eq!(was_nonzero_square.unwrap_u8(), 1u8);
let sign_test_sqrt = &invsqrt_m1 * &constants::SQRT_M1;
// XXX it seems we have flipped the sign relative to
// the invsqrt function?
assert_eq!(sign_test_sqrt, minus_one);
}

Expand Down
40 changes: 28 additions & 12 deletions src/curve_models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

// ------------------------------------------------------------------------
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -268,18 +268,34 @@ impl ValidityCheck for ProjectivePoint {
// Constant-time assignment
// ------------------------------------------------------------------------

impl ConditionallyAssignable for ProjectiveNielsPoint {
fn conditional_assign(&mut self, other: &ProjectiveNielsPoint, choice: 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),
}
}

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 ConditionallyAssignable for AffineNielsPoint {
fn conditional_assign(&mut self, other: &AffineNielsPoint, choice: Choice) {
// PreComputedGroupElementCMove()
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),
}
}

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);
Expand All @@ -296,7 +312,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(),
Expand All @@ -311,7 +327,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,
Expand All @@ -323,7 +339,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,
Expand Down
Loading