diff --git a/vendor/github.com/wsddn/go-ecdh/LICENSE b/vendor/github.com/wsddn/go-ecdh/LICENSE new file mode 100644 index 000000000..c16b0acf7 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2014, tang0th +All rights reserved. + +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 tang0th 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 HOLDER 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. diff --git a/vendor/github.com/wsddn/go-ecdh/Readme.md b/vendor/github.com/wsddn/go-ecdh/Readme.md new file mode 100644 index 000000000..1445f68b1 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/Readme.md @@ -0,0 +1,19 @@ +# ECDH + +[![Build Status](https://travis-ci.org/wsddn/go-ecdh.svg?branch=master)](https://travis-ci.org/wsddn/go-ecdh) + +This is a go implementation of elliptical curve diffie-hellman key exchange method. +It supports the NIST curves (and any curves using the `elliptic.Curve` go interface) +as well as djb's curve25519. + +The library handles generating of keys, generating a shared secret, and the +(un)marshalling of the elliptical curve keys into slices of bytes. + +## Warning and Disclaimer +I am not a cryptographer, this was written as part of a personal project to learn about cryptographic systems and protocols. No claims as to the security of this library are made, I would not advise using it for anything that requires any level of security. Pull requests or issues about security flaws are however still welcome. + +## Compatibility +Works with go 1.2 onwards. + +## TODO + * Improve documentation diff --git a/vendor/github.com/wsddn/go-ecdh/curve25519.go b/vendor/github.com/wsddn/go-ecdh/curve25519.go new file mode 100644 index 000000000..6426cbf8a --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/curve25519.go @@ -0,0 +1,62 @@ +package ecdh + +import ( + "crypto" + "io" + + "golang.org/x/crypto/curve25519" +) + +type curve25519ECDH struct { + ECDH +} + +// NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519 +// elliptical curve. +func NewCurve25519ECDH() ECDH { + return &curve25519ECDH{} +} + +func (e *curve25519ECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) { + var pub, priv [32]byte + var err error + + _, err = io.ReadFull(rand, priv[:]) + if err != nil { + return nil, nil, err + } + + priv[0] &= 248 + priv[31] &= 127 + priv[31] |= 64 + + curve25519.ScalarBaseMult(&pub, &priv) + + return &priv, &pub, nil +} + +func (e *curve25519ECDH) Marshal(p crypto.PublicKey) []byte { + pub := p.(*[32]byte) + return pub[:] +} + +func (e *curve25519ECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) { + var pub [32]byte + if len(data) != 32 { + return nil, false + } + + copy(pub[:], data) + return &pub, true +} + +func (e *curve25519ECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) { + var priv, pub, secret *[32]byte + + priv = privKey.(*[32]byte) + pub = pubKey.(*[32]byte) + secret = new([32]byte) + + curve25519.ScalarMult(secret, priv, pub) + return secret[:], nil +} diff --git a/vendor/github.com/wsddn/go-ecdh/ecdh.go b/vendor/github.com/wsddn/go-ecdh/ecdh.go new file mode 100644 index 000000000..921754fdc --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/ecdh.go @@ -0,0 +1,14 @@ +package ecdh + +import ( + "crypto" + "io" +) + +// The main interface for ECDH key exchange. +type ECDH interface { + GenerateKey(io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) + Marshal(crypto.PublicKey) []byte + Unmarshal([]byte) (crypto.PublicKey, bool) + GenerateSharedSecret(crypto.PrivateKey, crypto.PublicKey) ([]byte, error) +} diff --git a/vendor/github.com/wsddn/go-ecdh/elliptic.go b/vendor/github.com/wsddn/go-ecdh/elliptic.go new file mode 100644 index 000000000..502563c40 --- /dev/null +++ b/vendor/github.com/wsddn/go-ecdh/elliptic.go @@ -0,0 +1,87 @@ +package ecdh + +import ( + "crypto" + "crypto/elliptic" + "io" + "math/big" +) + +type ellipticECDH struct { + ECDH + curve elliptic.Curve +} + +type ellipticPublicKey struct { + elliptic.Curve + X, Y *big.Int +} + +type ellipticPrivateKey struct { + D []byte +} + +// NewEllipticECDH creates a new instance of ECDH with the given elliptic.Curve curve +// to use as the elliptical curve for elliptical curve diffie-hellman. +func NewEllipticECDH(curve elliptic.Curve) ECDH { + return &ellipticECDH{ + curve: curve, + } +} + +func (e *ellipticECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) { + var d []byte + var x, y *big.Int + var priv *ellipticPrivateKey + var pub *ellipticPublicKey + var err error + + d, x, y, err = elliptic.GenerateKey(e.curve, rand) + if err != nil { + return nil, nil, err + } + + priv = &ellipticPrivateKey{ + D: d, + } + pub = &ellipticPublicKey{ + Curve: e.curve, + X: x, + Y: y, + } + + return priv, pub, nil +} + +func (e *ellipticECDH) Marshal(p crypto.PublicKey) []byte { + pub := p.(*ellipticPublicKey) + return elliptic.Marshal(e.curve, pub.X, pub.Y) +} + +func (e *ellipticECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) { + var key *ellipticPublicKey + var x, y *big.Int + + x, y = elliptic.Unmarshal(e.curve, data) + if x == nil || y == nil { + return key, false + } + key = &ellipticPublicKey{ + Curve: e.curve, + X: x, + Y: y, + } + return key, true +} + +// GenerateSharedSecret takes in a public key and a private key +// and generates a shared secret. +// +// RFC5903 Section 9 states we should only return x. +func (e *ellipticECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) { + priv := privKey.(*ellipticPrivateKey) + pub := pubKey.(*ellipticPublicKey) + + x, _ := e.curve.ScalarMult(pub.X, pub.Y, priv.D) + return x.Bytes(), nil +}