2

I am using the FIPS 186-3 recommended curves for Diffie-Hellman Elliptic Curves. I'm trying to determine the max length of the private keys, according to RFC 5915 it should be:

ceiling (log2(n)/8) ,where n is the order of the curve

For the P-256 curve I get max length 32 which corresponds to what I'm seeing in my code (assuming an unsigned representation). However for the P-521 curve I get max length 65, however I am getting length 66 private keys in my code. Here is one example 66 bytes private key from the P-521 curve:

5367794175793176027889969828113014603157344894208126643379049713388781962338446363455749219733919077469072043715066195336337088038146192289964998476049182286

in hex:

01 90 59 2F 64 1C 73 AB F8 57 C4 F0 F2 A3 17 DD 5E 5F 64 B1 3C 61 15 8F E2 AC 34 DD 3F FC 6F 9B F1 38 9B 66 0F 27 34 60 75 E3 32 B0 B2 80 DF 9F 2A FE AC FF 82 BE 36 00 77 7A 92 B1 CB F7 7F 98 6E 4E

The public key for this was (without the leading 0x04 byte):

01 F0 64 36 14 25 89 F8 7E 0D 5F 0E F9 26 36 D7 5C 4A 45 D7 9C 86 BD F8 C5 B9 A7 AA C4 C2 EB 56 52 DD BD BE E1 A0 5B DD A1 1F D8 79 D8 BA 2A 18 68 56 C0 D7 0A 4D D6 2B AB BD 8E D9 33 7F B1 FF E5 18 00 B2 06 21 D9 DA C1 BA A2 E7 43 69 06 FF 03 2F 05 FC 0E 44 74 A1 A3 3B 2E 7E B1 68 01 B2 7F B9 94 EB 8C C7 47 D7 02 A5 46 4E 88 32 59 DD 27 DE 72 C2 6D 8D B4 3B D0 45 67 31 AF 8E 1C 30 87 42 38 9F

Does anybody know why it's possible to get 66 byte length private keys? According to the FIPS 186-3 document the order of the P-521 curve is:

n = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449

Which gives ceiling (log2(n)/8) = 65.

Regards, -Martin Lansler

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
lanzlord
  • 101
  • 6

2 Answers2

3

according to python (which i may be misusing in some way), log2(n)/8 is 65.125 so the ceiling of that is 66.

and n is 521 bits long (as i assume would be expected - i checked by printing out the hex representation, which starts with "1" and has 131 hex digits). and 521 / 8 is 65.125.

andrew cooke
  • 45,717
  • 10
  • 93
  • 143
0

Thanks Andrew... It was indeed our log2 function (missing in standard Java) which was incorrectly implemented, we were using BigInteger instead of BigDecimal which causes loss or precision during division.

The correct log2 code looks like (off-topic, but could be of interest for other Java developers):

private static final double LOG_2 = Math.log(2);
private static final BigDecimal BI_1024 = new BigDecimal("1024");

public static double log2(double num) {
    return (Math.log(num) / LOG_2);
}

private static double log2(BigDecimal value) {
    if (value.compareTo(BI_1024) < 0) {
        return log2(value.doubleValue());
    }
    return 10 + log2(value.divide(BI_1024));
}
lanzlord
  • 101
  • 6