From d6ba0a5b85d0280e4c3d1886c5bacbf2d77b158b Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Tue, 28 Apr 2020 10:06:17 +0200 Subject: [PATCH] keychain: add new abstraction interfaces --- keychain/derivation.go | 62 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/keychain/derivation.go b/keychain/derivation.go index 2fbc5387..18a1b345 100644 --- a/keychain/derivation.go +++ b/keychain/derivation.go @@ -167,8 +167,8 @@ type KeyRing interface { DeriveKey(keyLoc KeyLocator) (KeyDescriptor, error) } -// SecretKeyRing is a similar to the regular KeyRing interface, but it is also -// able to derive *private keys*. As this is a super-set of the regular +// SecretKeyRing is a ring similar to the regular KeyRing interface, but it is +// also able to derive *private keys*. As this is a super-set of the regular // KeyRing, we also expect the SecretKeyRing to implement the fully KeyRing // interface. The methods in this struct may be used to extract the node key in // order to accept inbound network connections, or to do manual signing for @@ -194,5 +194,63 @@ type SecretKeyRing interface { ScalarMult(keyDesc KeyDescriptor, pubKey *btcec.PublicKey) ([]byte, error) } +// DigestSignerRing is an interface that abstracts away basic low-level ECDSA +// signing on keys within a key ring. +type DigestSignerRing interface { + // SignDigest signs the given SHA256 message digest with the private key + // described in the key descriptor. + SignDigest(keyDesc KeyDescriptor, digest [32]byte) (*btcec.Signature, + error) + + // SignDigestCompact signs the given SHA256 message digest with the + // private key described in the key descriptor and returns the signature + // in the compact, public key recoverable format. + SignDigestCompact(keyDesc KeyDescriptor, digest [32]byte) ([]byte, error) +} + +// SingleKeyDigestSigner is an abstraction interface that hides the +// implementation of the low-level ECDSA signing operations by wrapping a +// single, specific private key. +type SingleKeyDigestSigner interface { + // PubKey returns the public key of the wrapped private key. + PubKey() *btcec.PublicKey + + // SignDigest signs the given SHA256 message digest with the wrapped + // private key. + SignDigest(digest [32]byte) (*btcec.Signature, error) + + // SignDigestCompact signs the given SHA256 message digest with the + // wrapped private key and returns the signature in the compact, public + // key recoverable format. + SignDigestCompact(digest [32]byte) ([]byte, error) +} + +// ECDHRing is an interface that abstracts away basic low-level ECDH shared key +// generation on keys within a key ring. +type ECDHRing interface { + // ECDH performs a scalar multiplication (ECDH-like operation) between + // the target key descriptor and remote public key. The output + // returned will be the sha256 of the resulting shared point serialized + // in compressed format. If k is our private key, and P is the public + // key, we perform the following operation: + // + // sx := k*P + // s := sha256(sx.SerializeCompressed()) + ECDH(keyDesc KeyDescriptor, pubKey *btcec.PublicKey) ([32]byte, error) +} + +// SingleKeyECDH is an abstraction interface that hides the implementation of an +// ECDH operation by wrapping a single, specific private key. +type SingleKeyECDH interface { + // PubKey returns the public key of the wrapped private key. + PubKey() *btcec.PublicKey + + // ECDH performs a scalar multiplication (ECDH-like operation) between + // the wrapped private key and remote public key. The output returned + // will be the sha256 of the resulting shared point serialized in + // compressed format. + ECDH(pubKey *btcec.PublicKey) ([32]byte, error) +} + // TODO(roasbeef): extend to actually support scalar mult of key? // * would allow to push in initial handshake auth into interface as well