Add a conditional negation function.

This commit is contained in:
Henry de Valence 2017-02-20 14:20:43 -08:00
parent 57884ecefa
commit 5f4de0074d
2 changed files with 25 additions and 0 deletions

View file

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

View file

@ -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<T>(x: &mut T, choice: u8)
where T: CTAssignable, for<'a> &'a T: Neg<Output=T>
{
// 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