Почему открытый ключ P-521 X, Y иногда составляет 65 байт, а иногда 66 байт

Я использую golang для создания открытого ключа P-521. исходный код выглядит так:

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 

Почему открытый ключ P-521 X, Y не похож на P-256 или P-384, которые имеют фиксированную длину открытого ключа?


person user9235725    schedule 24.04.2018    source источник
comment
По той же причине, по которой случайное число от 1 до 1000 иногда состоит из 4 цифр, иногда из 3, иногда из 2, а иногда из 1 цифры.   -  person Flimzy    schedule 24.04.2018


Ответы (1)


secp521r1 использует 521-битное простое поле. Таким образом, координаты X или Y представлены в виде 521-битных чисел. Да, 521, а не 512.

521 бит — это 65 полных байтов и один оставшийся бит. При кодировании открытого ключа с фиксированным размером в старшем байте 7 старших битов всегда будут установлены в 0, а 8-й бит будет равен 1 или 0 (таким образом, весь байт равен 0x00 или 0x01).

Поскольку координатное пространство не совсем состоит из всех 521-битных чисел, вероятность того, что старший бит будет установлен для какой-либо конкретной точки, составляет немногим менее 50%.

Метод Go, кажется, возвращает значение, используя представление с минимальным байтом. Итак, вы должны увидеть что-то вроде

  • 66 байт: 49% времени
  • 65 байт: 50% времени
  • 64 байта (все верхние 9 бит равны 0): 0,2%
  • (63 байта и меньше возможны, но с исчезающе малым процентом)
person bartonjs    schedule 24.04.2018
comment
В случае приложений, требующих представления фиксированной длины (например, JWK), как лучше всего отрегулировать длину, если возвращаемый ключ не имеет длины 66 байт? Будет ли это работать, как задумано, если я просто заполню недостающие ячейки нулевой последовательностью? (\х00) - person KawaLo; 06.12.2020
comment
@KawaLo Пока он не находится внутри какой-либо структуры с добавлением длины, конечно, вы можете добавить нули префикса. (например, вы не можете сделать это внутри SubjectPublicKeyInfo сертификата, поскольку он имеет значения длины, вам нужно будет пересчитать все... затем повторно подписать сертификат.) - person bartonjs; 06.12.2020