From 5f4de0074d6c34f01659a3d652df581c870a011e Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 20 Feb 2017 14:20:43 -0800 Subject: [PATCH 1/3] Add a conditional negation function. --- src/field.rs | 14 ++++++++++++++ src/util.rs | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/field.rs b/src/field.rs index dc21ea3..865d633 100644 --- a/src/field.rs +++ b/src/field.rs @@ -803,6 +803,7 @@ impl FieldElement { mod test { use field::*; use test::Bencher; + use util::conditional_negate; #[bench] fn bench_fieldelement_a_mul_a(b: &mut Bencher) { @@ -932,4 +933,17 @@ mod test { // high bit is set to zero in to_bytes assert!(test_bytes[31] == (B_BYTES[31] & 127u8)); } + + #[test] + fn test_conditional_negate() { + let one = FieldElement([ 1,0,0,0,0,0,0,0,0,0]); + let minus_one = FieldElement([-1,0,0,0,0,0,0,0,0,0]); + let mut x = one; + conditional_negate(&mut x,1u8); + assert_eq!(x, minus_one); + conditional_negate(&mut x,0u8); + assert_eq!(x, minus_one); + conditional_negate(&mut x,1u8); + assert_eq!(x, one); + } } diff --git a/src/util.rs b/src/util.rs index 1391ef8..86d91aa 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,6 +11,8 @@ //! Utility functions and tools for constant-time comparisons. +use core::ops::Neg; + /// Trait for items which can be conditionally assigned in constant time. pub trait CTAssignable { /// If `choice == 1u8`, assign `other` to `self`. @@ -19,6 +21,15 @@ pub trait CTAssignable { fn conditional_assign(&mut self, other: &Self, choice: u8); } +/// Conditionally negate an element if `choice == 1u8`. +pub fn conditional_negate(x: &mut T, choice: u8) + where T: CTAssignable, for<'a> &'a T: Neg +{ + // Need to cast to discard mutability + let x_neg = -(x as &T); + x.conditional_assign(&x_neg, choice); +} + /// Check equality of two bytes in constant time. /// /// # Return From 8a1c13ef49a38d997521c16166f93aae5da2fba2 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 20 Feb 2017 14:39:55 -0800 Subject: [PATCH 2/3] Make a CTNegateable trait with a generic impl for better ergonomics --- src/field.rs | 8 ++++---- src/util.rs | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/field.rs b/src/field.rs index 865d633..e0e4767 100644 --- a/src/field.rs +++ b/src/field.rs @@ -803,7 +803,7 @@ impl FieldElement { mod test { use field::*; use test::Bencher; - use util::conditional_negate; + use util::CTNegateable; #[bench] fn bench_fieldelement_a_mul_a(b: &mut Bencher) { @@ -939,11 +939,11 @@ mod test { let one = FieldElement([ 1,0,0,0,0,0,0,0,0,0]); let minus_one = FieldElement([-1,0,0,0,0,0,0,0,0,0]); let mut x = one; - conditional_negate(&mut x,1u8); + x.conditional_negate(1u8); assert_eq!(x, minus_one); - conditional_negate(&mut x,0u8); + x.conditional_negate(0u8); assert_eq!(x, minus_one); - conditional_negate(&mut x,1u8); + x.conditional_negate(1u8); assert_eq!(x, one); } } diff --git a/src/util.rs b/src/util.rs index 86d91aa..2d08f79 100644 --- a/src/util.rs +++ b/src/util.rs @@ -21,13 +21,24 @@ pub trait CTAssignable { fn conditional_assign(&mut self, other: &Self, choice: u8); } -/// Conditionally negate an element if `choice == 1u8`. -pub fn conditional_negate(x: &mut T, choice: u8) +/// Trait for items which can be conditionally negated in constant time. +/// +/// Note: it is not necessary to implement this trait, as a generic +/// implementation is provided. +pub trait CTNegateable +{ + /// Conditionally negate an element if `choice == 1u8`. + fn conditional_negate(&mut self, choice: u8); +} + +impl CTNegateable for T where T: CTAssignable, for<'a> &'a T: Neg { - // Need to cast to discard mutability - let x_neg = -(x as &T); - x.conditional_assign(&x_neg, choice); + fn conditional_negate(&mut self, choice: u8) { + // Need to cast to eliminate mutability + let self_neg: T = -(self as &T); + self.conditional_assign(&self_neg, choice); + } } /// Check equality of two bytes in constant time. From dc5621f5272553e0e64893f22bb25c358ca5b841 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 20 Feb 2017 15:22:28 -0800 Subject: [PATCH 3/3] Use conditional_negate in select_precomputed_point --- src/curve.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/curve.rs b/src/curve.rs index b36cc0b..b659980 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -87,6 +87,7 @@ use field::FieldElement; use scalar::Scalar; use util::bytes_equal_ct; use util::CTAssignable; +use util::CTNegateable; // ------------------------------------------------------------------------ // Compressed points @@ -734,9 +735,8 @@ fn select_precomputed_point(x: i8, points: &[T; 8]) -> T } // Now t == |x| * P. - let minus_t = -(&t); let neg_mask = (xmask & 1) as u8; - t.conditional_assign(&minus_t, neg_mask); + t.conditional_negate(neg_mask); // Now t == x * P. t