如何在 golang 中签署 curve25519 密钥?
How do I sign a curve25519 key in golang?
我正在尝试使用 Go 中的 Signal 实现 X3DH 算法。但是,我卡在了如何签署 Public Signed PreKey 上。
根据规范,它应该是 X25519 密钥。在查看 Github 之前的实现时,他们从 curve25519
包中生成了一个 [32]byte
密钥,然后将其转换为 ed25519
密钥,然后对其进行签名。
但是,他们用于转换的包已弃用 (github.com/agl/ed25519
)。因此,我要么需要能够将密钥转换为 ed25519
,以便我可以使用当前的 ed25519
包 (golang.org/x/crypto/25519
) 对它们进行签名,要么为 [=11 实现签名和验证功能=]键。
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))
Google 的 Golang 安全主管 Filippo Valsorda 就此话题进行了精彩的 blog 讨论。
这会接收 public curve25519 密钥并将其转换为 ed25519 public 密钥。我没有写这段代码,但似乎在做上面伍德斯托克所说的事情。欢迎提供更多信息:
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”的函数
我正在尝试使用 Go 中的 Signal 实现 X3DH 算法。但是,我卡在了如何签署 Public Signed PreKey 上。
根据规范,它应该是 X25519 密钥。在查看 Github 之前的实现时,他们从 curve25519
包中生成了一个 [32]byte
密钥,然后将其转换为 ed25519
密钥,然后对其进行签名。
但是,他们用于转换的包已弃用 (github.com/agl/ed25519
)。因此,我要么需要能够将密钥转换为 ed25519
,以便我可以使用当前的 ed25519
包 (golang.org/x/crypto/25519
) 对它们进行签名,要么为 [=11 实现签名和验证功能=]键。
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))
Google 的 Golang 安全主管 Filippo Valsorda 就此话题进行了精彩的 blog 讨论。
这会接收 public curve25519 密钥并将其转换为 ed25519 public 密钥。我没有写这段代码,但似乎在做上面伍德斯托克所说的事情。欢迎提供更多信息:
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”的函数