package ecdh import ( "crypto" "io" "golang.org/x/crypto/curve25519" ) type curve25519ECDH struct { ECDH } // NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519 // elliptical curve. func NewCurve25519ECDH() ECDH { return &curve25519ECDH{} } func (e *curve25519ECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) { var pub, priv [32]byte var err error _, err = io.ReadFull(rand, priv[:]) if err != nil { return nil, nil, err } priv[0] &= 248 priv[31] &= 127 priv[31] |= 64 curve25519.ScalarBaseMult(&pub, &priv) return &priv, &pub, nil } func (e *curve25519ECDH) Marshal(p crypto.PublicKey) []byte { pub := p.(*[32]byte) return pub[:] } func (e *curve25519ECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) { var pub [32]byte if len(data) != 32 { return nil, false } copy(pub[:], data) return &pub, true } func (e *curve25519ECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) { var priv, pub, secret *[32]byte priv = privKey.(*[32]byte) pub = pubKey.(*[32]byte) secret = new([32]byte) curve25519.ScalarMult(secret, priv, pub) return secret[:], nil }