33//! By default these are all constant-time and use the `subtle` crate.
44
55use super :: BoxedUint ;
6- use crate :: Limb ;
7- use core:: cmp;
8- use subtle:: { Choice , ConstantTimeEq } ;
6+ use crate :: { CtChoice , Limb } ;
7+ use core:: cmp:: { self , Ordering } ;
8+ use subtle:: {
9+ Choice , ConditionallySelectable , ConstantTimeEq , ConstantTimeGreater , ConstantTimeLess ,
10+ } ;
911
1012impl ConstantTimeEq for BoxedUint {
1113 #[ inline]
@@ -23,17 +25,55 @@ impl ConstantTimeEq for BoxedUint {
2325 }
2426}
2527
28+ impl ConstantTimeGreater for BoxedUint {
29+ #[ inline]
30+ fn ct_gt ( & self , other : & Self ) -> Choice {
31+ let ( _, borrow) = other. sbb ( self , Limb :: ZERO ) ;
32+ CtChoice :: from_mask ( borrow. 0 ) . into ( )
33+ }
34+ }
35+
36+ impl ConstantTimeLess for BoxedUint {
37+ #[ inline]
38+ fn ct_lt ( & self , other : & Self ) -> Choice {
39+ let ( _, borrow) = self . sbb ( other, Limb :: ZERO ) ;
40+ CtChoice :: from_mask ( borrow. 0 ) . into ( )
41+ }
42+ }
43+
2644impl Eq for BoxedUint { }
2745impl PartialEq for BoxedUint {
2846 fn eq ( & self , other : & Self ) -> bool {
2947 self . ct_eq ( other) . into ( )
3048 }
3149}
3250
51+ impl Ord for BoxedUint {
52+ fn cmp ( & self , other : & Self ) -> Ordering {
53+ let mut ret = Ordering :: Equal ;
54+ ret. conditional_assign ( & Ordering :: Greater , self . ct_gt ( other) ) ;
55+ ret. conditional_assign ( & Ordering :: Less , self . ct_lt ( other) ) ;
56+
57+ #[ cfg( debug_assertions) ]
58+ if ret == Ordering :: Equal {
59+ debug_assert_eq ! ( self , other) ;
60+ }
61+
62+ ret
63+ }
64+ }
65+
66+ impl PartialOrd for BoxedUint {
67+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
68+ Some ( self . cmp ( other) )
69+ }
70+ }
71+
3372#[ cfg( test) ]
3473mod tests {
3574 use super :: BoxedUint ;
36- use subtle:: ConstantTimeEq ;
75+ use core:: cmp:: Ordering ;
76+ use subtle:: { ConstantTimeEq , ConstantTimeGreater , ConstantTimeLess } ;
3777
3878 #[ test]
3979 fn ct_eq ( ) {
@@ -45,4 +85,61 @@ mod tests {
4585 assert ! ( !bool :: from( b. ct_eq( & a) ) ) ;
4686 assert ! ( bool :: from( b. ct_eq( & b) ) ) ;
4787 }
88+
89+ #[ test]
90+ fn ct_gt ( ) {
91+ let a = BoxedUint :: zero ( ) ;
92+ let b = BoxedUint :: one ( ) ;
93+ let c = BoxedUint :: max ( 64 ) . unwrap ( ) ;
94+
95+ assert ! ( bool :: from( b. ct_gt( & a) ) ) ;
96+ assert ! ( bool :: from( c. ct_gt( & a) ) ) ;
97+ assert ! ( bool :: from( c. ct_gt( & b) ) ) ;
98+
99+ assert ! ( !bool :: from( a. ct_gt( & a) ) ) ;
100+ assert ! ( !bool :: from( b. ct_gt( & b) ) ) ;
101+ assert ! ( !bool :: from( c. ct_gt( & c) ) ) ;
102+
103+ assert ! ( !bool :: from( a. ct_gt( & b) ) ) ;
104+ assert ! ( !bool :: from( a. ct_gt( & c) ) ) ;
105+ assert ! ( !bool :: from( b. ct_gt( & c) ) ) ;
106+ }
107+
108+ #[ test]
109+ fn ct_lt ( ) {
110+ let a = BoxedUint :: zero ( ) ;
111+ let b = BoxedUint :: one ( ) ;
112+ let c = BoxedUint :: max ( 64 ) . unwrap ( ) ;
113+
114+ assert ! ( bool :: from( a. ct_lt( & b) ) ) ;
115+ assert ! ( bool :: from( a. ct_lt( & c) ) ) ;
116+ assert ! ( bool :: from( b. ct_lt( & c) ) ) ;
117+
118+ assert ! ( !bool :: from( a. ct_lt( & a) ) ) ;
119+ assert ! ( !bool :: from( b. ct_lt( & b) ) ) ;
120+ assert ! ( !bool :: from( c. ct_lt( & c) ) ) ;
121+
122+ assert ! ( !bool :: from( b. ct_lt( & a) ) ) ;
123+ assert ! ( !bool :: from( c. ct_lt( & a) ) ) ;
124+ assert ! ( !bool :: from( c. ct_lt( & b) ) ) ;
125+ }
126+
127+ #[ test]
128+ fn cmp ( ) {
129+ let a = BoxedUint :: zero ( ) ;
130+ let b = BoxedUint :: one ( ) ;
131+ let c = BoxedUint :: max ( 64 ) . unwrap ( ) ;
132+
133+ assert_eq ! ( a. cmp( & b) , Ordering :: Less ) ;
134+ assert_eq ! ( a. cmp( & c) , Ordering :: Less ) ;
135+ assert_eq ! ( b. cmp( & c) , Ordering :: Less ) ;
136+
137+ assert_eq ! ( a. cmp( & a) , Ordering :: Equal ) ;
138+ assert_eq ! ( b. cmp( & b) , Ordering :: Equal ) ;
139+ assert_eq ! ( c. cmp( & c) , Ordering :: Equal ) ;
140+
141+ assert_eq ! ( b. cmp( & a) , Ordering :: Greater ) ;
142+ assert_eq ! ( c. cmp( & a) , Ordering :: Greater ) ;
143+ assert_eq ! ( c. cmp( & b) , Ordering :: Greater ) ;
144+ }
48145}
0 commit comments