Skip to content

Commit d18f9de

Browse files
committed
crypto: add ECDH interface and implementation
With this commit we create a new interface that abstracts away the ECDH implementation. We also create one implementation that satisfies the interface that can be used if the private key is known directly. Later we will change the generateSharedSecret function to use this interface instead of doing the ECDH operation directly.
1 parent 25954be commit d18f9de

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

crypto.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,55 @@ const (
2222
// the output of a SHA256 hash.
2323
type Hash256 [sha256.Size]byte
2424

25+
// SingleKeyECDH is an abstraction interface that hides the implementation of an
26+
// ECDH operation against a specific private key. We use this abstraction for
27+
// the long term keys which we eventually want to be able to keep in a hardware
28+
// wallet or HSM.
29+
type SingleKeyECDH interface {
30+
// PubKey returns the public key of the private key that is abstracted
31+
// away by the interface.
32+
PubKey() *btcec.PublicKey
33+
34+
// ECDH performs a scalar multiplication (ECDH-like operation) between
35+
// the abstracted private key and a remote public key. The output
36+
// returned will be the sha256 of the resulting shared point serialized
37+
// in compressed format.
38+
ECDH(pubKey *btcec.PublicKey) ([32]byte, error)
39+
}
40+
41+
// PrivKeyECDH is an implementation of the SingleKeyECDH in which we do have the
42+
// full private key. This can be used to wrap a temporary key to conform to the
43+
// SingleKeyECDH interface.
44+
type PrivKeyECDH struct {
45+
// PrivKey is the private key that is used for the ECDH operation.
46+
PrivKey *btcec.PrivateKey
47+
}
48+
49+
// PubKey returns the public key of the private key that is abstracted away by
50+
// the interface.
51+
//
52+
// NOTE: This is part of the SingleKeyECDH interface.
53+
func (p *PrivKeyECDH) PubKey() *btcec.PublicKey {
54+
return p.PrivKey.PubKey()
55+
}
56+
57+
// ECDH performs a scalar multiplication (ECDH-like operation) between the
58+
// abstracted private key and a remote public key. The output returned will be
59+
// the sha256 of the resulting shared point serialized in compressed format. If
60+
// k is our private key, and P is the public key, we perform the following
61+
// operation:
62+
//
63+
// sx := k*P
64+
// s := sha256(sx.SerializeCompressed())
65+
//
66+
// NOTE: This is part of the SingleKeyECDH interface.
67+
func (p *PrivKeyECDH) ECDH(pub *btcec.PublicKey) ([32]byte, error) {
68+
s := &btcec.PublicKey{}
69+
s.X, s.Y = btcec.S256().ScalarMult(pub.X, pub.Y, p.PrivKey.D.Bytes())
70+
71+
return sha256.Sum256(s.SerializeCompressed()), nil
72+
}
73+
2574
// DecryptedError contains the decrypted error message and its sender.
2675
type DecryptedError struct {
2776
// Sender is the node that sent the error. Note that a node may occur in

0 commit comments

Comments
 (0)