I am trying to implement the X3DH algorithm from Signal in Go. However, I got stuck on how to sign the Public Signed PreKey.
Per the specifications it is supposed to be an X25519 key. In looking at previous implementations on Github they generated a [32]byte
key from the curve25519
package and then converted it to an ed25519
key and then signed it.
However, the packages they used for the conversion are deprecated (github.com/agl/ed25519
). Therefore, I either need to be able to convert the keys to ed25519
so I can sign them with the current ed25519
package (golang.org/x/crypto/25519
) or implement a sign and verify function for curve25519
keys.
Ed25519
keys can be converted to X25519
keys easily, the twisted Edwards curve used by Ed25519
and the Montgomery curve used by X25519
are birationally
equivalent.
Points on the Edwards curve are usually referred to as (x, y
), while points on the Montgomery curve are usually referred to as (u, v
).
You don't need a library to do the conversion, it's really simple...
(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)
(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))
Here is a great blog by Filippo Valsorda, the Golang security lead at Google, discussing this topic.