pub trait ConditionallySelectable: Copy {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self;
fn conditional_assign(&mut self, other: &Self, choice: Choice) { ... }
fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) { ... }
}
A type which can be conditionally selected in constant time. This trait also provides generic implementations of conditional assignment and conditional swaps.
1. conditional_selectfn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self
Select a
or b
according to choice
. Returns:
- a if choice == Choice(0);
- b if choice == Choice(1).
This function should execute in constant time.
use subtle::ConditionallySelectable;
let x: u8 = 13;
let y: u8 = 42;
let z = u8::conditional_select(&x, &y, 0.into());
assert_eq!(z, x);
let z = u8::conditional_select(&x, &y, 1.into());
assert_eq!(z, y);
2. conditional_assign
fn conditional_assign(&mut self, other: &Self, choice: Choice)
Conditionally assign other
to self
, according to choice
.
This function should execute in constant time.
use subtle::ConditionallySelectable;
let mut x: u8 = 13;
let mut y: u8 = 42;
x.conditional_assign(&y, 0.into());
assert_eq!(x, 13);
x.conditional_assign(&y, 1.into());
assert_eq!(x, 42);
3. conditional_swap
fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice)
Conditionally swap self
and other
if choice == 1
; otherwise, reassign both unto themselves.
This function should execute in constant time.
use subtle::ConditionallySelectable;
let mut x: u8 = 13;
let mut y: u8 = 42;
u8::conditional_swap(&mut x, &mut y, 0.into());
assert_eq!(x, 13);
assert_eq!(y, 42);
u8::conditional_swap(&mut x, &mut y, 1.into());
assert_eq!(x, 42);
assert_eq!(y, 13);
二、Trait subtle::ConditionallyNegatable
pub trait ConditionallyNegatable {
fn conditional_negate(&mut self, choice: Choice);
}
A type which can be conditionally negated in constant time.
fn conditional_negate(&mut self, choice: Choice)
Negate self if choice == Choice(1); otherwise, leave it unchanged. This function should execute in constant time.
fn conditional_negate() {
let one = FieldElement::one();
let minus_one = FieldElement::minus_one();
let mut x = one;
x.conditional_negate(Choice::from(1));
assert_eq!(x, minus_one);
x.conditional_negate(Choice::from(0));
assert_eq!(x, minus_one);
x.conditional_negate(Choice::from(1));
assert_eq!(x, one);
}
三、Trait subtle::ConstantTimeEq
pub trait ConstantTimeEq {
fn ct_eq(&self, other: &Self) -> Choice;
}
An Eq-like trait that produces a Choice instead of a bool.
fn ct_eq(&self, other: &Self) -> Choice
Determine if two items are equal. The ct_eq function should execute in constant time. Returns:
- Choice(1u8) if self == other;
- Choice(0u8) if self != other.
use subtle::ConstantTimeEq;
let x: u8 = 5;
let y: u8 = 13;
assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
assert_eq!(x.ct_eq(&x).unwrap_u8(), 1);
impl ConstantTimeEq for [T] fn ct_eq(&self, _rhs: &[T]) -> Choice
Check whether two slices of ConstantTimeEq types are equal. This function short-circuits if the lengths of the input slices are different. Otherwise, it should execute in time independent of the slice contents. Since arrays coerce to slices, this function works with fixed-size arrays:
let a: [u8; 8] = [0,1,2,3,4,5,6,7];
let b: [u8; 8] = [0,1,2,3,0,1,2,3];
let a_eq_a = a.ct_eq(&a);
let a_eq_b = a.ct_eq(&b);
assert_eq!(a_eq_a.unwrap_u8(), 1);
assert_eq!(a_eq_b.unwrap_u8(), 0);
四、Struct subtle::CtOption
pub struct CtOption {
value: T,
is_some: Choice,
}
The CtOption
type represents an optional value similar to the Option
type but is intended for use in constant time APIs. a Choice
that determines whether the optional value should be Some
or not
. If is_some
is false, the value will still be stored but its value is never exposed.
参考资料: [1] https://docs.rs/subtle/2.0.0/subtle/trait.ConditionallySelectable.html [2] https://doc.dalek.rs/subtle/trait.ConditionallyNegatable.html [3] https://doc.dalek.rs/subtle/trait.ConstantTimeEq.html