Как подписать ключ curve25519 в golang?

Я пытаюсь реализовать алгоритм X3DH из Signal in Go. Однако я застрял на том, как подписать PreKey с публичной подписью.

Согласно спецификациям это должен быть ключ X25519. Глядя на предыдущие реализации на Github, они создали[32]byte ключ от curve25519 пакет, а затем преобразовал его в ed25519 ключ, а затем подписал его.

Однако пакеты, которые они использовали для преобразования, устарели (github.com/agl/ed25519). Следовательно, мне либо нужно иметь возможность конвертировать ключи вed25519 так что я могу подписать их текущим ed25519 пакет (golang.org/x/crypto/25519) или реализовать функцию подписи и проверки для curve25519 ключи.

2 ответа

Решение

Ed25519 ключи можно преобразовать в X25519 ключей легко, извилистая кривая Эдвардса, используемая Ed25519 и кривая Монтгомери, используемая X25519 являются birationally эквивалент.

Точки на кривой Эдвардса обычно обозначаются как (x, y), а точки на кривой Монтгомери обычно обозначаются как (u, v).

Вам не нужна библиотека для преобразования, это действительно просто...

(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)
(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))

Вот отличный блог Филиппо Валсорда, руководителя службы безопасности Golang в Google, обсуждающего эту тему.

Он принимает открытый ключ curve25519 и преобразует его в открытый ключ ed25519. Я не писал этот код, но, похоже, делаю то, что говорит Вудсток выше. Приветствуется дополнительная информация:

func Verify(publicKey [32]byte, message []byte, signature *[64]byte) bool {

publicKey[31] &= 0x7F

/* Convert the Curve25519 public key into an Ed25519 public key.  In
particular, convert Curve25519's "montgomery" x-coordinate into an
Ed25519 "edwards" y-coordinate:
ed_y = (mont_x - 1) / (mont_x + 1)
NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp
Then move the sign bit into the pubkey from the signature.
*/

var edY, one, montX, montXMinusOne, montXPlusOne FieldElement
FeFromBytes(&montX, &publicKey)
FeOne(&one)
FeSub(&montXMinusOne, &montX, &one)
FeAdd(&montXPlusOne, &montX, &one)
FeInvert(&montXPlusOne, &montXPlusOne)
FeMul(&edY, &montXMinusOne, &montXPlusOne)

var A_ed [32]byte
FeToBytes(&A_ed, &edY)

A_ed[31] |= signature[63] & 0x80
signature[63] &= 0x7F

var sig = make([]byte, 64)
var aed = make([]byte, 32)

copy(sig, signature[:])
copy(aed, A_ed[:])

return ed25519.Verify(aed, message, sig)

Здесь используются функции из "golang.org/x/crypto/ed25519/internal"

Другие вопросы по тегам