1
$\begingroup$

If I run openssl ec on a key that I have generated with openssl ecparam -genkey I get one extra prefixing 0x00 in the private key, and one 0x04 in the public key. While I understand the 0x04 which means uncompressed format, I don't understand the 0x00 in the private one. If I use the openssl asn1parse that 0x00 gets discarded correctly when showing the 32 bytes of the key.

read EC key Private-Key: (256 bit) priv: 00:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx pub: 04:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx ASN1 OID: prime256v1

$\endgroup$
1
$\begingroup$

It's because how ASN.1 (DER, actually) encodes integers.

DER is not a crypto-specific format; it is a method originally designed to encode a large variety of information. So, when they encode an integer, they provide the possibility of encoding a negative integer (even though that never comes up in crypto, it may be used in other usages).

They encode the integer as a big-endian byte string (where the first byte is the most significant one), and they use the convention that the msbit of the first byte indicates the sign of the encoded integer.

This raises an obvious question: what happens if the msbyte of the integer was, say, 0x80? If you made that the first byte of the encoding, the decoder would see that this msbit was 1, and so would assume that the integer was negative. To avoid this possibility, what DER mandates is that, in that case, you prepend a 0x00 byte in front.

This is what is happening; your private key is an integer that just happens to be between $2^{255}$ and $2^{256}$; because the msbit of that msbyte happens to be a 1, a 0x00 is prepended. This will happen on about half of the private keys you'll generate.

$\endgroup$
  • 1
    $\begingroup$ Actually this one is NOT a DER issue (though ECDSA and DSA signatures are); SEC1-later-RFC5915 makes the private value an OCTET STRING wrapping unsigned fixed-length, unlike a DER INTEGER. See crypto.stackexchange.com/questions/48707… . As OP says, asn1parse shows the correct size. It is the -text option that displays it wrong; this is fixed in 1.1.0 up. – $\endgroup$ – dave_thompson_085 Dec 14 '18 at 1:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.