2020-02-06 23:54:13 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
2020-03-21 19:42:46 +00:00
|
|
|
"crypto/sha512"
|
2022-09-13 02:13:48 +00:00
|
|
|
"filippo.io/edwards25519"
|
2020-02-06 23:54:13 +00:00
|
|
|
"golang.org/x/crypto/curve25519"
|
|
|
|
"golang.org/x/crypto/ed25519"
|
|
|
|
)
|
|
|
|
|
|
|
|
// EDH implements diffie hellman using curve25519 keys derived from ed25519 keys
|
2020-03-21 19:42:46 +00:00
|
|
|
func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) ([]byte, error) {
|
2020-02-06 23:54:13 +00:00
|
|
|
var privKeyBytes [64]byte
|
|
|
|
var remotePubKeyBytes [32]byte
|
|
|
|
copy(privKeyBytes[:], privateKey[:])
|
|
|
|
copy(remotePubKeyBytes[:], remotePublicKey[:])
|
2020-03-21 19:42:46 +00:00
|
|
|
var curve25519priv [32]byte
|
|
|
|
|
|
|
|
PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes)
|
2022-10-24 20:00:45 +00:00
|
|
|
remoteCurve25519pub, err := ed25519PublicKeyToCurve25519New(remotePublicKey)
|
|
|
|
if err != nil {
|
|
|
|
return []byte{}, err
|
2022-09-13 02:13:48 +00:00
|
|
|
}
|
2022-10-24 20:00:45 +00:00
|
|
|
secret, err := curve25519.X25519(curve25519priv[:], remoteCurve25519pub[:])
|
2020-03-21 19:42:46 +00:00
|
|
|
return secret, err
|
|
|
|
}
|
|
|
|
|
2022-09-13 02:13:48 +00:00
|
|
|
// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190
|
2022-10-24 20:00:45 +00:00
|
|
|
func ed25519PublicKeyToCurve25519New(pk ed25519.PublicKey) ([]byte, error) {
|
2022-09-13 02:13:48 +00:00
|
|
|
// See https://blog.filippo.io/using-ed25519-keys-for-encryption and
|
|
|
|
// https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery.
|
|
|
|
p, err := new(edwards25519.Point).SetBytes(pk)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2020-03-21 19:42:46 +00:00
|
|
|
}
|
2022-09-13 02:13:48 +00:00
|
|
|
return p.BytesMontgomery(), nil
|
2020-03-21 19:42:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding
|
|
|
|
// curve25519 private key
|
|
|
|
func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey *[64]byte) {
|
|
|
|
h := sha512.New()
|
|
|
|
h.Write(privateKey[:32])
|
|
|
|
digest := h.Sum(nil)
|
|
|
|
|
|
|
|
digest[0] &= 248
|
|
|
|
digest[31] &= 127
|
|
|
|
digest[31] |= 64
|
|
|
|
|
|
|
|
copy(curve25519Private[:], digest)
|
2020-02-06 23:54:13 +00:00
|
|
|
}
|