I am trying to test my understanding on ECDSA Signature r|s to ASN.1 DER Encoding for NIST P-256. I have r|s and when I convert this into ASN.1 DER in Java. I get following format:

b1 = Length of remaining data
b2 = Length of r
b3 = Length of s

For example, suppose:

r|s = b2b31575f8536b284410d01217f688be3a9faf4ba0ba3a9093f983e40d630ec722a7a25b01403cff0d00b3b853d230f8e96ff832b15d4ccc75203cb65896a2d5

Breakdown ASN.1 DER signature format 0x30|b1|0x02|b2|r|0x02|b3|s:


My question is - will I be getting this format always or will there be a chance that r and s could be converted and to make length of curve?


The ASN.1 DER format is deterministic; i.e. there is only a single sequence of bytes that validly encodes given $r$ and $s$ values. Mind the details, though: the encodings of $r$ and $s$ are minimal-sized signed big-endian. Since $r$ and $s$ are positive values, this means that the top bit of the first byte of each encoding must be zero. In your example, the top byte of $r$ is 0xB2, whose top bit is a 1, so an extra 0x00 byte is added, while the top byte of $s$ is 0x22, whose top bit is a 0, so no extra 0x00 byte here.

However, there are some buggy implementations that produce wrong encodings in some cases (e.g. not including a leading 0x00 byte where necessary, or adding an unnecessary leading 0x00 byte). Thus, ECDSA signature verifiers are often a bit lenient in what they accept.

The ECDSA standards (ANSI X9.62, FIPS 186-4) don't define an ECDSA signature as a sequence of bytes, but as a pair of values $(r,s)$. Encoding of signatures is considered to be out of scope; the protocol that uses ECDSA signatures is responsible for defining which encoding will be used. Different protocols used different conventions. In practice, you will encounter two main encodings for ECDSA signatures:

  • The ASN.1 DER format, described above. It's the one used in X.509 certificates and related protocols.

  • The "raw" format in which $r$ and $s$ are merely concatenated. In that format, $r$ and $s$ must first be represented as sequences of bytes with some convention (usually big-endian), possibly with some extra padding bytes (of value 0x00) so that both $r$ and $s$ encodings have the same size. The "same size" requirement is important because verifiers must know where to split. OpenPGP uses the "raw" format.

  • $\begingroup$ Usually I2OSP is used (integer to octet string) to generate the raw signatures. I2OSP is defined in PKCS#1 for RSA, it specifies how to encode an unsigned, big endian integer into a given number of octets. The number of octets itself is the minimum number of octets to encode a specific maximum value, which is the order of the curve: i.e. $N$. Some curves such as the brainpool curves make sure that $N$ is always dividable by 8, making encoding the curve just slightly easier. Because $N$ - in the end - is just the curve size. $\endgroup$ – Maarten Bodewes Mar 22 '18 at 16:30
  • $\begingroup$ Uh, darn, forgot to say that this is also the way it is defined by the German BSI, e.g. for the ePassport specifications / card verifiable certificates. $\endgroup$ – Maarten Bodewes Mar 22 '18 at 16:40
  • 3
    $\begingroup$ I've seen the name "IEEE P1363 encoding" used to designate the "raw" format, I guess it is in reference to the IEEE standard because of its section 5.5.3 that standardize the ways one may want to convert between integers and octet strings. $\endgroup$ – Lery Mar 22 '18 at 22:15
  • $\begingroup$ PGP isn't 'raw' for ECDSA; it uses the same format as original DSA in rfc4880 5.2.2, which is two 'multiprecision integer's, each a length prefix plus variable-length value, but unlike BER/DER there is no tag, the length field is always encoded as 2 bytes and is measured in bits not octets, and the value is unsigned thus curves with 'exact-bytes' n like P-256 don't have almost half their r,s values expand by an octet to indicate positive. $\endgroup$ – dave_thompson_085 Oct 14 '19 at 19:13

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.