@@ -39,27 +39,31 @@ impl<const SIZE: usize> Decode for EcdsaPrivateKey<SIZE> {
39
39
40
40
fn decode ( reader : & mut impl Reader ) -> Result < Self > {
41
41
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
43
46
if len == SIZE . checked_add ( 1 ) . ok_or ( encoding:: Error :: Length ) ? {
44
- // Strip leading zero
45
47
// TODO(tarcieri): make sure leading zero was necessary
46
48
if u8:: decode ( reader) ? != 0 {
47
49
return Err ( Error :: FormatEncoding ) ;
48
50
}
51
+
52
+ len = SIZE ;
49
53
}
50
54
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 ( ) ) ;
62
59
}
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..] ) ?;
63
67
Ok ( Self { bytes } )
64
68
} )
65
69
}
0 commit comments