Boolean value for y-coordinate?
While implementing the feature of signing and verification with ES256 / ES384 / ES512 algorithms into my Java library for CBOR / COSE / CWT (authlete/cbor), I noticed that “IANA COSE Key Type Parameters” states that the y-coordinate of EC2 keys can be represented as a boolean value instead of an integer value.
Through an internet search, I found the following sentence in “2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion” of “SEC 1: Elliptic Curve Cryptography”.
Derive from yP a single bit ỹP as follows (this allows the y-coordinate to be represented compactly using a single bit)
When the y-coordinate is represented as a single bit (which can be represented as a boolean value), the actual value of the y-coordinate needs to be calculated using other parameters such as the x-coordinate and elliptic curve parameters.
In the case of “prime finite fields”, which is the case for P-256, P-384 and P-521 (which are elliptic curves used by ES256, ES384 and ES512 algorithms, respectively), the y-coordinate (yp) is calculated by the following steps as instructed in “2.3.4 Octet-String-to-Elliptic-Curve-Point Conversion”.
- Compute the field element α ≡ x³p + axp + b (mod p)
- Compute a square root β of α modulo p
- Output “invalid” and stop if there are no square roots of α modulo p
- Otherwise set yp = β if β ≡ ỹp (mod 2), and set yp = p - β if β ≢ ỹp (mod 2)
I implemented the calculation steps (
uncompressY() in ECDSA.java) based on a certain answer found on Stack Overflow. But, to be honest, I haven’t tested it yet, so I’m not sure if it’s a correct implementation.
DER or P1363?
The algorithm results in a pair of integers (R, S). There are two major ways to encode the two integers into a byte array. One is DER and the other is P1363.
If you pass
"SHA256withECDSA" to the
getInstance(String) method of the
java.security.Signature class, the returned
Signature instance presumes that the format of signatures is DER.