-1

I use golang generate the P-521 public key. source code look like that:

curve:=elliptic.P521()
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
xBytes:=x.Bytes()
yBytes:=y.bytes()
//len(xBytes)  some time is 65 bytes ,some time is 66 bytes 

Why P-521 public key X,Y not like P-256 or P-384 that have a fixed public key length?

user9235725
  • 23
  • 1
  • 2
  • 5
    For the same reason that a random number from 1 and 1000 is some times 4 digits, some times, 3, sometimes 2, or sometimes 1 digit. – Jonathan Hall Apr 24 '18 at 12:58

1 Answers1

8

secp521r1 uses a 521-bit prime field. So the X or Y coordinates are represented as 521-bit numbers. Yes, 521, not 512.

521 bits is 65 full bytes and one bit left over. In a fixed-size encoding of the public key the most significant byte would always have the 7 most significant bits set to 0, and the 8th bit will be 1 or 0 (so the whole byte is 0x00 or 0x01).

Since the coordinate space isn't quite all of the 521-bit numbers, you have a slightly less than 50% chance of the high bit being set for any particular point.

Go's method seems to be returning the value using a minimum-byte representation. So you should see something like

  • 66 bytes: 49% of the time
  • 65 bytes: 50% of the time
  • 64 bytes (top 9 bits are all 0): 0.2%
  • (63 bytes and below are possible, but with vanishingly small percentages)
bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • In case of applications that requires fixed length representation (such as JWK), what is the "best way" to adjust length if the returned key is not 66 bytes long ? Will it work as intended if I just fill the missing cells with a null sequence ? ("\x00") – KawaLo Dec 06 '20 at 16:52
  • 1
    @KawaLo So long as it's not inside any sort of length-prepended structure, sure, you could add prefix zeroes. (e.g. you couldn't do it inside a certificate's SubjectPublicKeyInfo since it has length values, you'd need to recompute everything... then re-sign the cert.) – bartonjs Dec 06 '20 at 16:56
  • do yo happen to know the RFC document explaining this binary format in details? it would greatly help me!. – m.eldehairy Jan 27 '22 at 10:24
  • @m.eldehairy It's just a big-endian representation of an integer with all leading zeros omitted. There's not really a spec to consult (to my knowledge). – bartonjs Jan 27 '22 at 16:48
  • @bartonjs, thanks for your reply. I meant for the whole key coordinates + private key including the prefix byte X, Y and optionally the private key – m.eldehairy Jan 28 '22 at 09:10
  • @m.eldehairy probably https://www.secg.org/sec1-v2.pdf, then. That’s all the “how do you write down ECC” stuff – bartonjs Jan 28 '22 at 16:12