| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- 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
- }
|