diff --git a/agessh/agessh.go b/agessh/agessh.go index 9b212ba..5f88d4f 100644 --- a/agessh/agessh.go +++ b/agessh/agessh.go @@ -24,10 +24,10 @@ import ( "errors" "fmt" "io" - "math/big" "filippo.io/age" "filippo.io/age/internal/format" + "filippo.io/edwards25519" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/curve25519" "golang.org/x/crypto/hkdf" @@ -186,37 +186,14 @@ func ParseRecipient(s string) (age.Recipient, error) { return r, nil } -var curve25519P, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10) - func ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) ([]byte, error) { - // ed25519.PublicKey is a little endian representation of the y-coordinate, - // with the most significant bit set based on the sign of the x-coordinate. - bigEndianY := make([]byte, ed25519.PublicKeySize) - for i, b := range pk { - bigEndianY[ed25519.PublicKeySize-i-1] = b + // See https://blog.filippo.io/using-ed25519-keys-for-encryption and + // https://pkg.go.dev/filippo.io/edwards25519#Point.BytesMontgomery. + p, err := (&edwards25519.Point{}).SetBytes(pk) + if err != nil { + return nil, err } - bigEndianY[0] &= 0b0111_1111 - - // The Montgomery u-coordinate is derived through the bilinear map - // - // u = (1 + y) / (1 - y) - // - // See https://blog.filippo.io/using-ed25519-keys-for-encryption. - y := new(big.Int).SetBytes(bigEndianY) - denom := new(big.Int).Sub(big.NewInt(1), y) - if denom = denom.ModInverse(denom, curve25519P); denom == nil { - return nil, errors.New("invalid point") - } - u := y.Mul(y.Add(y, big.NewInt(1)), denom) - u.Mod(u, curve25519P) - - out := make([]byte, curve25519.PointSize) - uBytes := u.Bytes() - for i, b := range uBytes { - out[len(uBytes)-i-1] = b - } - - return out, nil + return p.BytesMontgomery(), nil } const ed25519Label = "age-encryption.org/v1/ssh-ed25519" diff --git a/go.mod b/go.mod index 3245147..084a437 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module filippo.io/age go 1.13 require ( + filippo.io/edwards25519 v1.0.0-beta.3 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 ) diff --git a/go.sum b/go.sum index 7b67eac..4a1c2be 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +filippo.io/edwards25519 v1.0.0-beta.3 h1:WQxB0FH5NzrhciInJ30bgL3soLng3AbdI651yQuVlCs= +filippo.io/edwards25519 v1.0.0-beta.3/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=