2
2
3
3
use super :: BoxedUint ;
4
4
use crate :: { ConstantTimeSelect , Limb } ;
5
- use subtle:: { Choice , ConditionallySelectable } ;
5
+ use subtle:: { Choice , ConditionallyNegatable , ConditionallySelectable } ;
6
6
7
7
/// NOTE: can't impl `subtle`'s [`ConditionallySelectable`] trait due to its `Copy` bound
8
8
impl ConstantTimeSelect for BoxedUint {
@@ -37,11 +37,18 @@ impl ConstantTimeSelect for BoxedUint {
37
37
}
38
38
}
39
39
40
+ impl ConditionallyNegatable for BoxedUint {
41
+ #[ inline]
42
+ fn conditional_negate ( & mut self , choice : Choice ) {
43
+ let self_neg = self . wrapping_neg ( ) ;
44
+ self . ct_assign ( & self_neg, choice)
45
+ }
46
+ }
47
+
40
48
#[ cfg( test) ]
41
49
mod tests {
42
- use super :: BoxedUint ;
43
- use crate :: ConstantTimeSelect ;
44
- use subtle:: Choice ;
50
+ use crate :: { BoxedUint , ConstantTimeSelect } ;
51
+ use subtle:: { Choice , ConditionallyNegatable } ;
45
52
46
53
#[ test]
47
54
fn conditional_select ( ) {
@@ -51,4 +58,17 @@ mod tests {
51
58
assert_eq ! ( a, BoxedUint :: ct_select( & a, & b, Choice :: from( 0 ) ) ) ;
52
59
assert_eq ! ( b, BoxedUint :: ct_select( & a, & b, Choice :: from( 1 ) ) ) ;
53
60
}
61
+
62
+ #[ test]
63
+ fn conditional_negate ( ) {
64
+ let mut a = BoxedUint :: from ( 123u64 ) ;
65
+ let control = a. clone ( ) ;
66
+
67
+ a. conditional_negate ( Choice :: from ( 0 ) ) ;
68
+ assert_eq ! ( a, control) ;
69
+
70
+ a. conditional_negate ( Choice :: from ( 1 ) ) ;
71
+ assert_ne ! ( a, control) ;
72
+ assert_eq ! ( a, control. wrapping_neg( ) ) ;
73
+ }
54
74
}
0 commit comments