@@ -39,27 +39,31 @@ impl<const SIZE: usize> Decode for EcdsaPrivateKey<SIZE> {
3939
4040 fn decode ( reader : & mut impl Reader ) -> Result < Self > {
4141 reader. read_prefixed ( |reader| {
42- let len = reader. remaining_len ( ) ;
42+ let mut len = reader. remaining_len ( ) ;
43+
44+ // Strip leading zero if necessary:
45+ // `mpint` is signed and may need a leading zero for unsigned integers
4346 if len == SIZE . checked_add ( 1 ) . ok_or ( encoding:: Error :: Length ) ? {
44- // Strip leading zero
4547 // TODO(tarcieri): make sure leading zero was necessary
4648 if u8:: decode ( reader) ? != 0 {
4749 return Err ( Error :: FormatEncoding ) ;
4850 }
51+
52+ len = SIZE ;
4953 }
5054
51- let mut bytes = [ 0u8 ; SIZE ] ;
52- if SIZE == 66 {
53- // https://stackoverflow.com/questions/50002149/why-p-521-public-key-x-y-some-time-is-65-bytes-some-time-is-66-bytes
54- // although lower keys than 64 are vanishingly possible, but lets stop here
55- if len > 63 {
56- reader. read ( & mut bytes[ ..core:: cmp:: min ( len, SIZE ) ] ) ?;
57- } else {
58- return Err ( encoding:: Error :: Length . into ( ) ) ;
59- }
60- } else {
61- reader. read ( & mut bytes) ?;
55+ // Minimum allowed key size: may be smaller than modulus size
56+ const MIN_SIZE : usize = 32 ;
57+ if len < MIN_SIZE || len > SIZE {
58+ return Err ( encoding:: Error :: Length . into ( ) ) ;
6259 }
60+
61+ // Add leading zeros if the encoded key is smaller than `SIZE`.
62+ // The resulting value is big endian and needs leading zero padding.
63+ let leading_zeros = SIZE . checked_sub ( len) . ok_or ( encoding:: Error :: Length ) ?;
64+
65+ let mut bytes = [ 0u8 ; SIZE ] ;
66+ reader. read ( & mut bytes[ leading_zeros..] ) ?;
6367 Ok ( Self { bytes } )
6468 } )
6569 }
0 commit comments