multi: store KeyLocator in OpenChannel, use ECDH

This commit adds a RevocationKeyLocator field to the OpenChannel
struct so that the SCB derivation doesn't have to brute-force the
sha chain root key and match the public key. ECDH derivation is now
used to derive the key instead of regular private key derivation a
la DerivePrivKey. The legacy can still be used to recover old
channels.
This commit is contained in:
eugene
2020-10-21 13:34:05 -04:00
parent 986e69c81b
commit bb84f0ebc8
6 changed files with 183 additions and 58 deletions

View File

@@ -124,19 +124,34 @@ type Single struct {
func NewSingle(channel *channeldb.OpenChannel,
nodeAddrs []net.Addr) Single {
// TODO(roasbeef): update after we start to store the KeyLoc for
// shachain root
var shaChainRootDesc keychain.KeyDescriptor
// We'll need to obtain the shachain root which is derived directly
// from a private key in our keychain.
var b bytes.Buffer
channel.RevocationProducer.Encode(&b) // Can't return an error.
// If the channel has a populated RevocationKeyLocator, then we can
// just store that instead of the public key.
if channel.RevocationKeyLocator.Family == keychain.KeyFamilyRevocationRoot {
shaChainRootDesc = keychain.KeyDescriptor{
KeyLocator: channel.RevocationKeyLocator,
}
} else {
// If the RevocationKeyLocator is not populated, then we'll need
// to obtain a public point for the shachain root and store that.
// This is the legacy scheme.
var b bytes.Buffer
_ = channel.RevocationProducer.Encode(&b) // Can't return an error.
// Once we have the root, we'll make a public key from it, such that
// the backups plaintext don't carry any private information. When we
// go to recover, we'll present this in order to derive the private
// key.
_, shaChainPoint := btcec.PrivKeyFromBytes(btcec.S256(), b.Bytes())
// Once we have the root, we'll make a public key from it, such that
// the backups plaintext don't carry any private information. When
// we go to recover, we'll present this in order to derive the
// private key.
_, shaChainPoint := btcec.PrivKeyFromBytes(btcec.S256(), b.Bytes())
shaChainRootDesc = keychain.KeyDescriptor{
PubKey: shaChainPoint,
KeyLocator: keychain.KeyLocator{
Family: keychain.KeyFamilyRevocationRoot,
},
}
}
// If a channel is unconfirmed, the block height of the ShortChannelID
// is zero. This will lead to problems when trying to restore that
@@ -149,21 +164,16 @@ func NewSingle(channel *channeldb.OpenChannel,
}
single := Single{
IsInitiator: channel.IsInitiator,
ChainHash: channel.ChainHash,
FundingOutpoint: channel.FundingOutpoint,
ShortChannelID: chanID,
RemoteNodePub: channel.IdentityPub,
Addresses: nodeAddrs,
Capacity: channel.Capacity,
LocalChanCfg: channel.LocalChanCfg,
RemoteChanCfg: channel.RemoteChanCfg,
ShaChainRootDesc: keychain.KeyDescriptor{
PubKey: shaChainPoint,
KeyLocator: keychain.KeyLocator{
Family: keychain.KeyFamilyRevocationRoot,
},
},
IsInitiator: channel.IsInitiator,
ChainHash: channel.ChainHash,
FundingOutpoint: channel.FundingOutpoint,
ShortChannelID: chanID,
RemoteNodePub: channel.IdentityPub,
Addresses: nodeAddrs,
Capacity: channel.Capacity,
LocalChanCfg: channel.LocalChanCfg,
RemoteChanCfg: channel.RemoteChanCfg,
ShaChainRootDesc: shaChainRootDesc,
}
switch {