lnwallet: add elkrem root derivation function

The derivation is current bed on an HKDF invocation using our private
key as the secret, and the node’s channel multi-sig key as the salt.
This scheme allows us to derive the key on the fly given data known to
only us and the remote node.

The current derivation is just a place-holder and will be re-visited at
a later time.
This commit is contained in:
Olaoluwa Osuntokun 2016-06-30 12:08:27 -07:00
parent 78346c81e7
commit d85719b5a7
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 31 additions and 1 deletions

View File

@ -2,9 +2,12 @@ package lnwallet
import (
"bytes"
"crypto/sha256"
"fmt"
"math/big"
"golang.org/x/crypto/hkdf"
"github.com/btcsuite/fastsha256"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcd/txscript"
@ -345,6 +348,7 @@ func senderHtlcSpendTimeout(commitScript []byte, outputAmt btcutil.Amount,
// OP_ENDIF
// <sender key> OP_CHECKSIG
// OP_ENDIF
// TODO(roasbeef): rename these to sender vs receiver?
func receiverHTLCScript(absoluteTimeout, relativeTimeout uint32, senderKey,
receiverKey *btcec.PublicKey, revokeHash, paymentHash []byte) ([]byte, error) {
@ -707,7 +711,7 @@ func deriveRevocationPubkey(commitPubKey *btcec.PublicKey,
// a previously revoked commitment transaction.
//
// The private key is derived as follwos:
// revokePriv := commitPriv + revokePrimge mod N
// revokePriv := commitPriv + revokePreimage mod N
//
// Where N is the order of the sub-group.
func deriveRevocationPrivKey(commitPrivKey *btcec.PrivateKey,
@ -730,3 +734,29 @@ func deriveRevocationPrivKey(commitPrivKey *btcec.PrivateKey,
privRevoke, _ := btcec.PrivKeyFromBytes(btcec.S256(), revokePriv.Bytes())
return privRevoke
}
// deriveElkremRoot derives an elkrem root unique to a channel given the
// private key for our public key in the 2-of-2 multi-sig, and the remote
// node's multi-sig public key. The root is derived using the HKDF[1][2]
// instantiated with sha-256. The secret data used is our multi-sig private
// key, with the salt being the remote node's public key.
//
// [1]: https://eprint.iacr.org/2010/264.pdf
// [2]: https://tools.ietf.org/html/rfc5869
func deriveElkremRoot(localMultiSigKey *btcec.PrivateKey,
remoteMultiSigKey *btcec.PublicKey) wire.ShaHash {
secret := localMultiSigKey.Serialize()
salt := remoteMultiSigKey.SerializeCompressed()
info := []byte("elkrem")
rootReader := hkdf.New(sha256.New, secret, salt, info)
// It's safe to ignore the error her as we know for sure that we won't
// be draining the HKDF past its available entropy horizon.
// TODO(roasbeef): revisit...
var elkremRoot wire.ShaHash
rootReader.Read(elkremRoot[:])
return elkremRoot
}