Search code examples
algorithmgocryptographyed25519curve-25519

How do I sign a curve25519 key in golang?


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.


Solution

  • 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.