@@ -12,7 +12,7 @@ use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive};
12
12
use core:: fmt:: { self , Debug } ;
13
13
use generic_array:: typenum:: Unsigned ;
14
14
use subtle:: { Choice , ConstantTimeEq } ;
15
- use zeroize:: { Zeroize , ZeroizeOnDrop } ;
15
+ use zeroize:: { Zeroize , ZeroizeOnDrop , Zeroizing } ;
16
16
17
17
#[ cfg( feature = "arithmetic" ) ]
18
18
use crate :: { rand_core:: CryptoRngCore , CurveArithmetic , NonZeroScalar , PublicKey } ;
40
40
} ,
41
41
alloc:: vec:: Vec ,
42
42
sec1:: der:: Encode ,
43
- zeroize:: Zeroizing ,
44
43
} ;
45
44
46
45
#[ cfg( all( feature = "arithmetic" , any( feature = "jwk" , feature = "pem" ) ) ) ]
@@ -85,6 +84,11 @@ impl<C> SecretKey<C>
85
84
where
86
85
C : Curve ,
87
86
{
87
+ /// Minimum allowed size of an elliptic curve secret key in bytes.
88
+ ///
89
+ /// This provides the equivalent of 96-bits of symmetric security.
90
+ const MIN_SIZE : usize = 24 ;
91
+
88
92
/// Generate a random [`SecretKey`].
89
93
#[ cfg( feature = "arithmetic" ) ]
90
94
pub fn random ( rng : & mut impl CryptoRngCore ) -> Self
@@ -148,31 +152,20 @@ where
148
152
Ok ( Self { inner } )
149
153
}
150
154
151
- /// Deserialize secret key from an encoded secret scalar passed as a
152
- /// byte slice.
155
+ /// Deserialize secret key from an encoded secret scalar passed as a byte slice.
156
+ ///
157
+ /// The slice is expected to be a minimum of 24-bytes (192-byts) and at most `C::FieldBytesSize`
158
+ /// bytes in length.
153
159
///
154
- /// The slice is expected to be at most `C::FieldBytesSize` bytes in
155
- /// length but may be up to 4-bytes shorter than that, which is handled by
156
- /// zero-padding the value.
160
+ /// Byte slices shorter than the field size are handled by zero padding the input.
157
161
pub fn from_slice ( slice : & [ u8 ] ) -> Result < Self > {
158
- if slice. len ( ) > C :: FieldBytesSize :: USIZE {
159
- return Err ( Error ) ;
160
- }
161
-
162
- /// Maximum number of "missing" bytes to interpret as zeroes.
163
- const MAX_LEADING_ZEROES : usize = 4 ;
164
-
165
- let offset = C :: FieldBytesSize :: USIZE . saturating_sub ( slice. len ( ) ) ;
166
-
167
- if offset == 0 {
162
+ if slice. len ( ) == C :: FieldBytesSize :: USIZE {
168
163
Self :: from_bytes ( FieldBytes :: < C > :: from_slice ( slice) )
169
- } else if offset <= MAX_LEADING_ZEROES {
170
- let mut bytes = FieldBytes :: < C > :: default ( ) ;
164
+ } else if ( Self :: MIN_SIZE ..C :: FieldBytesSize :: USIZE ) . contains ( & slice. len ( ) ) {
165
+ let mut bytes = Zeroizing :: new ( FieldBytes :: < C > :: default ( ) ) ;
166
+ let offset = C :: FieldBytesSize :: USIZE . saturating_sub ( slice. len ( ) ) ;
171
167
bytes[ offset..] . copy_from_slice ( slice) ;
172
-
173
- let ret = Self :: from_bytes ( & bytes) ;
174
- bytes. zeroize ( ) ;
175
- ret
168
+ Self :: from_bytes ( & bytes)
176
169
} else {
177
170
Err ( Error )
178
171
}
0 commit comments