mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-04 20:24:10 +00:00
Merge pull request #205 from dalek-cryptography/fix-subtle-traits
Change to subtle::ConditionallySelectable
This commit is contained in:
commit
5d0bdf2f21
12 changed files with 235 additions and 108 deletions
|
|
@ -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 }
|
||||
|
||||
|
|
@ -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 }
|
||||
|
||||
|
|
@ -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 = []
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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::ConditionallyAssignable;
|
||||
use subtle::Choice;
|
||||
use subtle::ConditionallySelectable;
|
||||
|
||||
/// A `FieldElement32` represents an element of the field
|
||||
/// \\( \mathbb Z / (2\^{255} - 19)\\).
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@
|
|||
//! limbs with \\(128\\)-bit products.
|
||||
|
||||
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::ConditionallyAssignable;
|
||||
use subtle::Choice;
|
||||
use subtle::ConditionallySelectable;
|
||||
|
||||
/// A `FieldElement64` represents an element of the field
|
||||
/// \\( \mathbb Z / (2\^{255} - 19)\\).
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -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(),
|
||||
|
|
@ -268,8 +268,17 @@ 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);
|
||||
|
|
@ -277,9 +286,16 @@ impl ConditionallyAssignable for ProjectiveNielsPoint {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -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(),
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -897,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::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
use core::cmp::{Eq, PartialEq};
|
||||
|
||||
use subtle::ConditionallyAssignable;
|
||||
use subtle::ConditionallySelectable;
|
||||
use subtle::ConditionallyNegatable;
|
||||
use subtle::Choice;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
//!
|
||||
//! Scalar multiplication on `MontgomeryPoint`s is provided by the `*`
|
||||
//! operator, which implements the Montgomery ladder.
|
||||
//!
|
||||
//!
|
||||
//! # Edwards Conversion
|
||||
//!
|
||||
//! The \\(2\\)-to-\\(1\\) map from the Edwards model to the Montgomery
|
||||
|
|
@ -51,16 +51,15 @@
|
|||
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::ConditionallyAssignable;
|
||||
use subtle::ConditionallySwappable;
|
||||
use subtle::ConstantTimeEq;
|
||||
use subtle::Choice;
|
||||
use subtle::ConditionallySelectable;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
|
||||
/// Curve25519 or its twist.
|
||||
|
|
@ -141,7 +140,7 @@ impl MontgomeryPoint {
|
|||
/// \\( \mathbb P(\mathbb F\_p) \\), which we identify with the Kummer
|
||||
/// line of the Montgomery curve.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct ProjectivePoint{
|
||||
struct ProjectivePoint {
|
||||
pub U: FieldElement,
|
||||
pub W: FieldElement,
|
||||
}
|
||||
|
|
@ -161,10 +160,16 @@ impl Default for ProjectivePoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl ConditionallyAssignable for ProjectivePoint {
|
||||
fn conditional_assign(&mut self, that: &ProjectivePoint, choice: Choice) {
|
||||
self.U.conditional_assign(&that.U, choice);
|
||||
self.W.conditional_assign(&that.W, choice);
|
||||
impl ConditionallySelectable for ProjectivePoint {
|
||||
fn conditional_select(
|
||||
a: &ProjectivePoint,
|
||||
b: &ProjectivePoint,
|
||||
choice: Choice,
|
||||
) -> ProjectivePoint {
|
||||
ProjectivePoint {
|
||||
U: FieldElement::conditional_select(&a.U, &b.U, choice),
|
||||
W: FieldElement::conditional_select(&a.W, &b.W, choice),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +201,7 @@ impl ProjectivePoint {
|
|||
/// (U\_Q : W\_Q) \gets u(P + Q).
|
||||
/// $$
|
||||
fn differential_add_and_double(
|
||||
P: &mut ProjectivePoint,
|
||||
P: &mut ProjectivePoint,
|
||||
Q: &mut ProjectivePoint,
|
||||
affine_PmQ: &FieldElement,
|
||||
) {
|
||||
|
|
@ -249,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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,28 +157,28 @@
|
|||
//! [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::ConditionallyAssignable;
|
||||
use subtle::Choice;
|
||||
use subtle::ConditionallySelectable;
|
||||
use subtle::ConditionallyNegatable;
|
||||
use subtle::ConstantTimeEq;
|
||||
use subtle::Choice;
|
||||
|
||||
use edwards::EdwardsPoint;
|
||||
use edwards::EdwardsBasepointTable;
|
||||
use edwards::EdwardsPoint;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use prelude::*;
|
||||
|
|
@ -949,11 +949,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
|
||||
///
|
||||
|
|
@ -961,7 +961,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;
|
||||
|
|
@ -974,17 +974,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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -981,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]);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue