mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-21 14:10:35 +02:00
Initial brain dump of ln-hornet
This commit is contained in:
167
hornet.go
Normal file
167
hornet.go
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/btcsuite/btcd/btcec"
|
||||||
|
"golang.org/x/crypto/ripemd160"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ========== Half Baked Idea to Allow Re-Routes via the Onion Route ==========
|
||||||
|
// So, it seems that using onion routing break re-routing by intermediate nodes
|
||||||
|
// (for w/e reason they deem neccessary). aj stumbled unto this realization in
|
||||||
|
// one of his latest mailing lists posts (I plan to post to the ML myself soon,
|
||||||
|
// but only after I've figured out all the quirks etc). ASIDE:: looks like Rusty is
|
||||||
|
// using zeroes as padding? HORNET uses random bytes in a way that still doesn't
|
||||||
|
// give away node position.
|
||||||
|
//
|
||||||
|
// I've thought of a way to allow intermdiate nodes to re-route, but it requires
|
||||||
|
// communicating with the source backwards on the onion route. Using HORNET,
|
||||||
|
// (during the set up phase) we can give each node in the hop the backwards
|
||||||
|
// AHDR (this allows them to route backwards to the source with a message) from
|
||||||
|
// their point of view. So basically, then have a partial onion (full onion is to destination).
|
||||||
|
// This would allow each of them to communicate back to the source since positions
|
||||||
|
// information isn't given away by the sphinx header, nor the data transmission header.
|
||||||
|
// This would let the intermediate nodes give recommendations of the route in a
|
||||||
|
// way. In the example: because a route is cheaper more capacity, non-responsive,
|
||||||
|
// rebalance route, etc.
|
||||||
|
//
|
||||||
|
// So, at first glance this looks to work. It avoids requiring the source to
|
||||||
|
// have a syncrhnous connection to *each* hop (which also makes the onio stuff
|
||||||
|
// pointless).
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// ==== Half Baked Thought About Control/Message separation along route =====
|
||||||
|
// Hop to hop data transmission implementation (negotiating changes to the commitment txns, adding htlc, etc)
|
||||||
|
// doesn't matter. Meaning, hop-to-hop the nodes can use w/e protos dictated
|
||||||
|
// by w/e protocol their running. Could even do some version exchange on first
|
||||||
|
// connect (yo I support v1, v2, vRusty (could have protocol bridges etc)).
|
||||||
|
// So the main standardization point is then on the fronts on control
|
||||||
|
// information within the onion routing: set up HTLC, re-route request, etc.
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
// TODO(roasbeef): Might need to change? due to the PRG* requirements? But
|
||||||
|
// yeh, once I add the LN specific stuff FSLength will change. Also doesn't
|
||||||
|
// 20 hops seem a bit excessive? 7?
|
||||||
|
const NumMaxHops = 20
|
||||||
|
const FSLength = 48
|
||||||
|
|
||||||
|
// Hmm appears that they use k = 128 throughout the paper?
|
||||||
|
|
||||||
|
// HMAC -> SHA-256
|
||||||
|
// * or could use Poly1035: https://godoc.org/golang.org/x/crypto/poly1305
|
||||||
|
// * but, the paper specs: {0, 1}^k x {0, 1}* -> {0, 1}^k
|
||||||
|
// * Poly1035 is actually: {0, 1}^k x {0, 1}* -> {0, 1}^(2/k)
|
||||||
|
// * Also with Poly, I guess the key is treated as a nonce, tagging two messages
|
||||||
|
// with the same key allows an attacker to forge message or something like that
|
||||||
|
|
||||||
|
// Size of a forwarding segment is 32 bytes, the MAC is 16 bytes, so c = 48 bytes
|
||||||
|
// * NOTE: this doesn't include adding R to the forwarding segment, and w/e esle
|
||||||
|
|
||||||
|
// Hmmm since each uses diff key, just use AES-CTR with blank nonce, given key,
|
||||||
|
// encrypt plaintext of all zeroes, this'll give us our len(plaintext) rand bytes.
|
||||||
|
// PRG0 -> {0, 1}^k -> {0, 1}^r(c+k) or {0, 1}^1280 (assuming 20 hops, like rusty, but, is that too large? maybe, idk)
|
||||||
|
// PRG1 -> {0, 1}^k -> {0, 1}^r(c+k) or {0, 1}^1280 (assuming 20 hops)
|
||||||
|
// PRG2 -> {0, 1}^k -> {0, 1}^rc or {0, 1}^960 (assuming 20 hops, c=48)
|
||||||
|
// * NOTE: in second version of paper (accepted to CCS'15), all the PRG*'s are like PRG2
|
||||||
|
// * so makes it simpler
|
||||||
|
|
||||||
|
// PRP -> AES? or
|
||||||
|
// * {0, 1}^k x {0, 1}^a -> {0, 1}^a
|
||||||
|
|
||||||
|
// Do we need AEAD for the below? Or are is the per-hop MAC okay?
|
||||||
|
// ENC: AES-CTR or CHACHA20?
|
||||||
|
|
||||||
|
// DEC: AES-CTR or CHACHA20?
|
||||||
|
|
||||||
|
// h_op: G^* -> {0, 1}^k
|
||||||
|
// * op (elem of) {MAC, PRGO, PRG!, PRP, ENC, DEC}
|
||||||
|
// * key gen for the above essentially
|
||||||
|
|
||||||
|
// paper doesn't really specify the format, gotta read the Sphinx paper for it.
|
||||||
|
// SphinxHeader...
|
||||||
|
type SphinxHeader struct {
|
||||||
|
// pretty sure this MAC will extend to the chdr also
|
||||||
|
}
|
||||||
|
|
||||||
|
// SphinxPayload...
|
||||||
|
type SphinxPayload struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// SphinxPacket...
|
||||||
|
type SphinxPacket struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateSphinxHeader...
|
||||||
|
// Will create sphinx headers for the forward and backwards path, gen the shared
|
||||||
|
// sym keys via DH, and output the ephemeral key pair we used to gen the shared
|
||||||
|
// key with the nodes long-term DH key.
|
||||||
|
func GenerateSphinxHeader() (*SphinxHeader, *SphinxHeader, [][32]byte, []*btcec.PrivateKey) {
|
||||||
|
return nil, nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoutingSegment...
|
||||||
|
// NOTE: Length of routing segment in the paper is 8 bytes (enough for their
|
||||||
|
// imaginary network, I guess). But, looking like they'll be (20 + 33 bytes)
|
||||||
|
// 53 bytes. Or 52 if we use curve25519
|
||||||
|
type RoutingSegment struct {
|
||||||
|
nextHop *btcec.PublicKey // NOTE: or, is this a LN addr? w/e that is?
|
||||||
|
// nextHop [32]byte
|
||||||
|
rCommitment [ripemd160.Size]byte
|
||||||
|
|
||||||
|
// stuff perhaps?
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForwardingSegment....
|
||||||
|
type ForwardingSegment struct {
|
||||||
|
// Here's hash(R), attempt to make an HTLC with the next hop. If
|
||||||
|
// successful, then pass along the onion so we can finish getting the
|
||||||
|
// payment circuit set up.
|
||||||
|
// TODO(roasbeef): Do we create HTLC's with the minimum amount
|
||||||
|
// possible? 1 satoshi or is it 1 mili-satoshi?
|
||||||
|
rs RoutingSegment
|
||||||
|
|
||||||
|
// To defend against replay attacks. Intermediate nodes will drop the
|
||||||
|
// FS if it deems it's expired.
|
||||||
|
expiration uint64
|
||||||
|
|
||||||
|
// Key shared by intermediate node with the source, used to peel a layer
|
||||||
|
// off the onion for the next hop.
|
||||||
|
sharedSymmetricKey [32]byte // TODO(roasbeef): or, 16?
|
||||||
|
|
||||||
|
mac [32]byte // TODO(roasbeef): or, 16?
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnonymousHeader...
|
||||||
|
type AnonymousHeader struct {
|
||||||
|
// Forwarding info for the current hop. When serialized, it'll be
|
||||||
|
// encrypted with SV, the secret key for this node known to no-one but
|
||||||
|
// the node. It also contains a secret key shared with this node and the
|
||||||
|
// source, so it can peel off a layer of the onion for the next hop.
|
||||||
|
FS ForwardingSegment
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommonHeader...
|
||||||
|
type CommonHeader struct {
|
||||||
|
// TODO(roasbeef): maybe can use this to extend HORNET with additiona control signals
|
||||||
|
// for LN nodes?
|
||||||
|
controlType uint8
|
||||||
|
hops uint8
|
||||||
|
nonce [8]byte // either interpreted as EXP or nonce, little-endian? idk
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataPacket...
|
||||||
|
type DataPacket struct {
|
||||||
|
Chdr CommonHeader
|
||||||
|
Ahdr AnonymousHeader // TODO(roasbeef): MAC in ahdr includes the chdr?
|
||||||
|
Onion [FSLength * NumMaxHops]byte // TODO(roasbeef): or, is it NumMaxHops - 1?
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionSetupPacket...
|
||||||
|
type SessionSetupPacket struct {
|
||||||
|
Chdr CommonHeader
|
||||||
|
Shdr SphinxHeader
|
||||||
|
Sp SphinxPayload
|
||||||
|
FsPayload [FSLength * NumMaxHops]byte // ? r*c
|
||||||
|
// TODO(roabeef): hmm does this implcitly mean messages are a max of 48 bytes?
|
||||||
|
}
|
||||||
|
|
||||||
|
// will add other LN specific control packets below, I guess
|
Reference in New Issue
Block a user