go-ethereum/vendor/github.com/wsddn/go-ecdh/elliptic.go
2019-04-08 13:19:37 +02:00

88 lines
1.8 KiB
Go

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
}