The current implementation breaches the TR-03111 encoding specifications for field elements, resulting in failed PACE Authentication with some probability.
The problem:
Util.java > ecPoint2OS > line 1027/1028 the i2os(x) function is used instead of the i2os(x,l) function which would encode the coordinates with leading zeros.
This can in the special case that the x/y coordinates are of unequal length lead to problem since it is no longer possible to reconstruct the ECPoint easily (the implementation of OS2ecPoint fails since it assumes equal lengths)
The solution:
Change the function - sadly it does not seem like the ECPoint itself contains the needed data for it (bitlength of the curve - but e.g. in PACEProtocol > encodePublicKeyForSmartCard can simply be extended to include the curve/bitlength of the curve as well)
The relevant TR-03111:
3.2 Encoding Elliptic Curve Points:
"The uncompressed encoding Pu is defined as Pu=C‖X‖Y, where
C = 0x04
X = FE2OS(Xp)
Y = FE2OS(Yp)"
3.1.3. Conversion between Field Elements and Octet Strings:
"A field element x∈Fp is converted to an octet string of length l=ceil(log256(p)) by applying the conversion function I2OS as described in Section 3.1.2 with parameter l, i.e. FE2OS(x) =I2OS(x,l). "
3.1.2. Conversion between Integers and Octet Strings
... "Note:One or more leading digits will be zero if x < 256^(l−1)"
Anonymous
Thanks, @anonymous, for the bug report. To make sure I understand the issue:
Util.ecPoint2OS(ECPoint, int)
method.PACEProtocol.encodePublicKeyForSmartCard(PublicKey)
method.Last edit: Martijn Oostdijk 2020-12-10