Skip to content

Commit

Permalink
ecdh, readme, mod: remove dependency on agl/ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
iwasaki-kenta committed Mar 30, 2020
1 parent b89a566 commit a2ae1d2
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 19 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@

- Logging is handled by [uber-go/zap](https://github.com/uber-go/zap).
- Unit tests are handled by [stretchr/testify](https://github.com/stretchr/testify).
- Ed25519 signatures are handled by [oasislabs/ed25519](https://github.com/oasislabs/ed25519).
- Elliptic-curve Diffie Hellman Key Exchange (ECDH) over Curve25519 is handled by [agl/ed25519](https://github.com/agl/ed25519).
- X25519 handshaking and Curve25519 encryption/decryption and Ed25519 signatures are handled by [oasislabs/ed25519](https://github.com/oasislabs/ed25519).

## Setup

Expand Down
54 changes: 41 additions & 13 deletions ecdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,55 @@ package noise

import (
"crypto/ed25519"
"errors"
"crypto/sha512"
"fmt"
"github.com/agl/ed25519/extra25519"
"github.com/oasislabs/ed25519/extra/x25519"
"golang.org/x/crypto/curve25519"
"math/big"
)

// ECDH transform all Ed25519 points to Curve25519 points and performs a Diffie-Hellman handshake
// to derive a shared key. It throws an error should the Ed25519 points be invalid.
func ECDH(ourPrivateKey PrivateKey, peerPublicKey PublicKey) ([]byte, error) {
var (
curve25519Sec [x25519.ScalarSize]byte
curve25519Pub [x25519.PointSize]byte
)
var curve25519P, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10)

extra25519.PrivateKeyToCurve25519(&curve25519Sec, (*[ed25519.PrivateKeySize]byte)(&ourPrivateKey))
func ed25519PublicKeyToCurve25519(pk PublicKey) []byte {
// 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
}
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 := big.NewInt(1)
denom.ModInverse(denom.Sub(denom, y), curve25519P) // 1 / (1 - y)
u := y.Mul(y.Add(y, big.NewInt(1)), denom)
u.Mod(u, curve25519P)

if !extra25519.PublicKeyToCurve25519(&curve25519Pub, (*[ed25519.PublicKeySize]byte)(&peerPublicKey)) {
return nil, errors.New("got an invalid ed25519 public key")
out := make([]byte, curve25519.PointSize)
uBytes := u.Bytes()
for i, b := range uBytes {
out[len(uBytes)-i-1] = b
}

shared, err := x25519.X25519(curve25519Sec[:], curve25519Pub[:])
return out
}

func ed25519PrivateKeyToCurve25519(pk PrivateKey) []byte {
h := sha512.New()
h.Write(pk[:curve25519.ScalarSize])
out := h.Sum(nil)
return out[:curve25519.ScalarSize]
}

// ECDH transform all Ed25519 points to Curve25519 points and performs a Diffie-Hellman handshake
// to derive a shared key. It throws an error should the Ed25519 points be invalid.
func ECDH(ourPrivateKey PrivateKey, peerPublicKey PublicKey) ([]byte, error) {
shared, err := x25519.X25519(ed25519PrivateKeyToCurve25519(ourPrivateKey), ed25519PublicKeyToCurve25519(peerPublicKey))
if err != nil {
return nil, fmt.Errorf("could not derive a shared key: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ go 1.13

require (
github.com/VictoriaMetrics/fastcache v1.5.7
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412
github.com/oasislabs/ed25519 v0.0.0-20191122104632-9d9ffc15f526
github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
go.uber.org/atomic v1.5.1
go.uber.org/goleak v1.0.0
go.uber.org/zap v1.13.0
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/tools v0.0.0-20200129045341-207d3de1faaf // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
Expand All @@ -22,6 +20,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/oasislabs/ed25519 v0.0.0-20191122104632-9d9ffc15f526 h1:xKlK+m6tNFucKVOP4V0GDgU4IgaLbS+HRoiVbN3W8Y4=
github.com/oasislabs/ed25519 v0.0.0-20191122104632-9d9ffc15f526/go.mod h1:xIpCyrK2ouGA4QBGbiNbkoONrvJ00u9P3QOkXSOAC0c=
github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e h1:85L+lUTJHx4O7UP9y/65XV8iq7oaA2Uqe5WiUSB8XE4=
github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e/go.mod h1:xIpCyrK2ouGA4QBGbiNbkoONrvJ00u9P3QOkXSOAC0c=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down

0 comments on commit a2ae1d2

Please sign in to comment.