From 9012720973f2d5c78ddadc69f563c09a4bc9699f Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 12 Sep 2022 19:13:48 -0700 Subject: [PATCH] Remove bignum ed25519->curve25519 implementation / replace with filippo.io/edwards25519 --- go.mod | 2 +- go.sum | 3 --- utils/crypto.go | 71 +++++++++---------------------------------------- 3 files changed, 14 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 754a84f..c4a9ec5 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module git.openprivacy.ca/cwtch.im/tapir go 1.17 require ( + filippo.io/edwards25519 v1.0.0 git.openprivacy.ca/openprivacy/connectivity v1.8.6 git.openprivacy.ca/openprivacy/log v1.0.3 github.com/gtank/merlin v0.1.1 @@ -12,7 +13,6 @@ require ( ) require ( - filippo.io/edwards25519 v1.0.0 // indirect git.openprivacy.ca/openprivacy/bine v0.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect diff --git a/go.sum b/go.sum index 2a30915..bc615b4 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -38,7 +36,6 @@ golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWI golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/utils/crypto.go b/utils/crypto.go index 5bcfda1..fd5f0d6 100644 --- a/utils/crypto.go +++ b/utils/crypto.go @@ -2,9 +2,9 @@ package utils import ( "crypto/sha512" + "filippo.io/edwards25519" "golang.org/x/crypto/curve25519" "golang.org/x/crypto/ed25519" - "math/big" ) // EDH implements diffie hellman using curve25519 keys derived from ed25519 keys @@ -16,68 +16,23 @@ func EDH(privateKey ed25519.PrivateKey, remotePublicKey ed25519.PublicKey) ([]by var curve25519priv [32]byte PrivateKeyToCurve25519(&curve25519priv, &privKeyBytes) - curve25519pub := ed25519PublicKeyToCurve25519(remotePublicKey) + curve25519pub, err := ed25519PublicKeyToCurve25519(remotePublicKey) + if err == nil { + return nil, err + } secret, err := curve25519.X25519(curve25519priv[:], curve25519pub[:]) return secret, err } -// https://github.com/FiloSottile/age/blob/master/internal/age/ssh.go#L174 -// Copyright 2019 Google LLC -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are -//met: -// -// * Redistributions of source code must retain the above copyright -//notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -//copyright notice, this list of conditions and the following disclaimer -//in the documentation and/or other materials provided with the -//distribution. -// * Neither the name of Google LLC nor the names of its -//contributors may be used to endorse or promote products derived from -//this software without specific prior written permission. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -//A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -//OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -//SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -//LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -//OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -var curve25519P, _ = new(big.Int).SetString("57896044618658097711785492504343953926634992332820282019728792003956564819949", 10) - -func ed25519PublicKeyToCurve25519(pk ed25519.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 +// reproduced from https://github.com/FiloSottile/age/blob/main/agessh/agessh.go#L190 +func ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) ([]byte, error) { + // 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 } - 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) - - out := make([]byte, curve25519.PointSize) - uBytes := u.Bytes() - for i, b := range uBytes { - out[len(uBytes)-i-1] = b - } - - return out + return p.BytesMontgomery(), nil } // PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding