@@ -160,10 +160,8 @@ use digest::generic_array::typenum::U64;
160
160
#[ cfg( feature = "digest" ) ]
161
161
use digest:: Digest ;
162
162
163
- use subtle:: Choice ;
164
- use subtle:: ConditionallySelectable ;
165
- use subtle:: ConstantTimeEq ;
166
- use subtle:: CtOption ;
163
+ use subtle:: { Choice , CtOption } ;
164
+ use subtle:: { ConditionallySelectable , ConstantTimeEq , ConstantTimeGreater } ;
167
165
168
166
use zeroize:: Zeroize ;
169
167
@@ -258,9 +256,9 @@ impl Scalar {
258
256
/// if `bytes` is a canonical byte representation;
259
257
/// - `None` if `bytes` is not a canonical byte representation.
260
258
pub fn from_canonical_bytes ( bytes : [ u8 ; 32 ] ) -> CtOption < Scalar > {
261
- let high_bit_unset = ( bytes [ 31 ] >> 7 ) . ct_eq ( & 0 ) ;
262
- let candidate = Scalar :: from_bits ( bytes ) ;
263
- CtOption :: new ( candidate, high_bit_unset & candidate. is_canonical ( ) )
259
+ let candidate = Scalar { bytes } ;
260
+
261
+ CtOption :: new ( candidate, candidate. is_canonical ( ) )
264
262
}
265
263
266
264
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer.
@@ -1138,7 +1136,15 @@ impl Scalar {
1138
1136
/// # }
1139
1137
/// ```
1140
1138
pub fn is_canonical ( & self ) -> Choice {
1141
- self . ct_eq ( & self . reduce ( ) )
1139
+ let mut over = Choice :: from ( 0 ) ;
1140
+ let mut under = Choice :: from ( 0 ) ;
1141
+ for ( this, l) in self . unpack ( ) . 0 . iter ( ) . zip ( & constants:: L . 0 ) . rev ( ) {
1142
+ let gt = this. ct_gt ( l) ;
1143
+ let eq = this. ct_eq ( l) ;
1144
+ under |= ( !gt & !eq) & !over;
1145
+ over |= gt;
1146
+ }
1147
+ under
1142
1148
}
1143
1149
}
1144
1150
0 commit comments