@@ -132,10 +132,8 @@ use digest::generic_array::typenum::U64;
132
132
#[ cfg( feature = "digest" ) ]
133
133
use digest:: Digest ;
134
134
135
- use subtle:: Choice ;
136
- use subtle:: ConditionallySelectable ;
137
- use subtle:: ConstantTimeEq ;
138
- use subtle:: CtOption ;
135
+ use subtle:: { Choice , CtOption } ;
136
+ use subtle:: { ConditionallySelectable , ConstantTimeEq , ConstantTimeGreater } ;
139
137
140
138
#[ cfg( feature = "zeroize" ) ]
141
139
use zeroize:: Zeroize ;
@@ -253,9 +251,8 @@ impl Scalar {
253
251
/// if `bytes` is a canonical byte representation modulo the group order \\( \ell \\);
254
252
/// - `None` if `bytes` is not a canonical byte representation.
255
253
pub fn from_canonical_bytes ( bytes : [ u8 ; 32 ] ) -> CtOption < Scalar > {
256
- let high_bit_unset = ( bytes[ 31 ] >> 7 ) . ct_eq ( & 0 ) ;
257
254
let candidate = Scalar { bytes } ;
258
- CtOption :: new ( candidate, high_bit_unset & candidate. is_canonical ( ) )
255
+ CtOption :: new ( candidate, candidate. is_canonical ( ) )
259
256
}
260
257
261
258
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer. This breaks the invariant
@@ -1125,7 +1122,15 @@ impl Scalar {
1125
1122
/// Check whether this `Scalar` is the canonical representative mod \\(\ell\\). This is not
1126
1123
/// public because any `Scalar` that is publicly observed is reduced, by scalar invariant #2.
1127
1124
fn is_canonical ( & self ) -> Choice {
1128
- self . ct_eq ( & self . reduce ( ) )
1125
+ let mut over = Choice :: from ( 0 ) ;
1126
+ let mut under = Choice :: from ( 0 ) ;
1127
+ for ( this, l) in self . unpack ( ) . 0 . iter ( ) . zip ( & constants:: L . 0 ) . rev ( ) {
1128
+ let gt = this. ct_gt ( l) ;
1129
+ let eq = this. ct_eq ( l) ;
1130
+ under |= ( !gt & !eq) & !over;
1131
+ over |= gt;
1132
+ }
1133
+ under
1129
1134
}
1130
1135
}
1131
1136
0 commit comments