package crypto import ( "crypto/rand" "errors" "golang.org/x/crypto/curve25519" ) // KeyExchange manages the exchange of keys type curve25519KEX struct { secret [32]byte public [32]byte } var _ KeyExchange = &curve25519KEX{} // NewCurve25519KEX creates a new KeyExchange using Curve25519, see https://cr.yp.to/ecdh.html func NewCurve25519KEX() KeyExchange { c := &curve25519KEX{} if n, err := rand.Reader.Read(c.secret[:]); n != 32 || err != nil { panic("Curve25519: could not create private key") } // See https://cr.yp.to/ecdh.html c.secret[0] &= 248 c.secret[31] &= 127 c.secret[31] |= 64 curve25519.ScalarBaseMult(&c.public, &c.secret) return c } func (c *curve25519KEX) PublicKey() []byte { return c.public[:] } func (c *curve25519KEX) CalculateSharedKey(otherPublic []byte) ([]byte, error) { if len(otherPublic) != 32 { return nil, errors.New("Curve25519: expected public key of 32 byte") } var res [32]byte var otherPublicArray [32]byte copy(otherPublicArray[:], otherPublic) curve25519.ScalarMult(&res, &c.secret, &otherPublicArray) return res[:], nil }