@@ -12,7 +12,7 @@ use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive};
1212use core:: fmt:: { self , Debug } ;
1313use generic_array:: typenum:: Unsigned ;
1414use subtle:: { Choice , ConstantTimeEq } ;
15- use zeroize:: { Zeroize , ZeroizeOnDrop } ;
15+ use zeroize:: { Zeroize , ZeroizeOnDrop , Zeroizing } ;
1616
1717#[ cfg( feature = "arithmetic" ) ]
1818use crate :: { rand_core:: CryptoRngCore , CurveArithmetic , NonZeroScalar , PublicKey } ;
4040 } ,
4141 alloc:: vec:: Vec ,
4242 sec1:: der:: Encode ,
43- zeroize:: Zeroizing ,
4443} ;
4544
4645#[ cfg( all( feature = "arithmetic" , any( feature = "jwk" , feature = "pem" ) ) ) ]
@@ -85,6 +84,11 @@ impl<C> SecretKey<C>
8584where
8685 C : Curve ,
8786{
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+
8892 /// Generate a random [`SecretKey`].
8993 #[ cfg( feature = "arithmetic" ) ]
9094 pub fn random ( rng : & mut impl CryptoRngCore ) -> Self
@@ -148,31 +152,20 @@ where
148152 Ok ( Self { inner } )
149153 }
150154
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.
153159 ///
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.
157161 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 {
168163 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 ( ) ) ;
171167 bytes[ offset..] . copy_from_slice ( slice) ;
172-
173- let ret = Self :: from_bytes ( & bytes) ;
174- bytes. zeroize ( ) ;
175- ret
168+ Self :: from_bytes ( & bytes)
176169 } else {
177170 Err ( Error )
178171 }
0 commit comments