@@ -145,6 +145,13 @@ use subtle::ConditionallySelectable;
145
145
use subtle:: ConstantTimeEq ;
146
146
use subtle:: CtOption ;
147
147
148
+ #[ cfg( feature = "group" ) ]
149
+ use elliptic_curve:: {
150
+ bigint:: { ArrayEncoding , Encoding , U256 , U512 } ,
151
+ ops:: { Reduce , Invert } ,
152
+ scalar:: { FromUintUnchecked , IsHigh } ,
153
+ } ;
154
+
148
155
#[ cfg( feature = "zeroize" ) ]
149
156
use zeroize:: Zeroize ;
150
157
@@ -266,6 +273,15 @@ impl Scalar {
266
273
CtOption :: new ( candidate, high_bit_unset & candidate. is_canonical ( ) )
267
274
}
268
275
276
+ /// Converts from an integer representation in little endian into
277
+ /// its (congruent) `Scalar` representation.
278
+ /// Incorrectly using this can lead to mathematically invalid results,
279
+ /// which can lead to potential security vulnerabilities.
280
+ /// Use only if you know the input is congruent to a scalar.
281
+ pub const fn from_canonical_bytes_unchecked ( bytes : [ u8 ; 32 ] ) -> Scalar {
282
+ Scalar { bytes }
283
+ }
284
+
269
285
/// Construct a `Scalar` from the low 255 bits of a 256-bit integer. This breaks the invariant
270
286
/// that scalars are always reduced. Scalar-scalar arithmetic, i.e., addition, subtraction,
271
287
/// multiplication, **does not work** on scalars produced from this function. You may only use
@@ -1343,6 +1359,56 @@ impl FromUniformBytes<64> for Scalar {
1343
1359
}
1344
1360
}
1345
1361
1362
+ #[ cfg( feature = "group" ) ]
1363
+ impl Reduce < U256 > for Scalar {
1364
+ type Bytes = [ u8 ; 32 ] ;
1365
+
1366
+ fn reduce ( n : U256 ) -> Self {
1367
+ Scalar :: from_bytes_mod_order ( n. to_le_bytes ( ) )
1368
+ }
1369
+
1370
+ fn reduce_bytes ( bytes : & Self :: Bytes ) -> Self {
1371
+ Scalar :: from_bytes_mod_order ( * bytes)
1372
+ }
1373
+ }
1374
+
1375
+ #[ cfg( feature = "group" ) ]
1376
+ impl Reduce < U512 > for Scalar {
1377
+ type Bytes = [ u8 ; 64 ] ;
1378
+
1379
+ fn reduce ( n : U512 ) -> Self {
1380
+ Scalar :: from_bytes_mod_order_wide ( & n. to_le_bytes ( ) )
1381
+ }
1382
+
1383
+ fn reduce_bytes ( bytes : & Self :: Bytes ) -> Self {
1384
+ Scalar :: from_bytes_mod_order_wide ( bytes)
1385
+ }
1386
+ }
1387
+
1388
+ #[ cfg( feature = "group" ) ]
1389
+ impl IsHigh for Scalar {
1390
+ fn is_high ( & self ) -> Choice {
1391
+ self . is_canonical ( )
1392
+ }
1393
+ }
1394
+
1395
+ #[ cfg( feature = "group" ) ]
1396
+ impl Invert for Scalar {
1397
+ type Output = Self ;
1398
+ fn invert ( & self ) -> Self :: Output {
1399
+ self . invert ( )
1400
+ }
1401
+ }
1402
+
1403
+ #[ cfg( feature = "group" ) ]
1404
+ impl FromUintUnchecked for Scalar {
1405
+ type Uint = U256 ;
1406
+
1407
+ fn from_uint_unchecked ( n : Self :: Uint ) -> Self {
1408
+ Scalar :: from_bytes_mod_order ( n. to_le_bytes ( ) )
1409
+ }
1410
+ }
1411
+
1346
1412
/// Read one or more u64s stored as little endian bytes.
1347
1413
///
1348
1414
/// ## Panics
0 commit comments