From aj at erisian.com.au Fri Oct 16 20:53:55 2015 From: aj at erisian.com.au (Anthony Towns) Date: Sat, 17 Oct 2015 06:53:55 +1000 Subject: [Lightning-dev] daemon/p2p protocol Message-ID: <20151016205355.GA18796@navy> Hey *, A few thoughts on the daemon/p2p protocol in slightly longer form than is feasible on IRC... # protobufs or capnp or flatbuffers or ... Currently lightning relies on protobuf's with union support, which requires a newer version of protobuf-c than is in Debian or Ubuntu. I've filed this as http://bugs.debian.org/801950 -- seems to be an easy fix. 11:43 * rusty looks at capnproto, is tempted to see what that would look like compared to protobufs. capnp's canonical implementation is in C++ rather than C; the C version is serialisaion-only, which seems like it loses the fancy time-travel RPC feature? C and Python versions of capnp don't seem to be packaged for Debian. Not a show-stopper afaics, but I'm not seeing the benefit? 11:44 But it still doesn't have fixed-length fields, which is a PITA. FWIW, I think that "fixed-length fields" is just a schema/IDL thing? ie the serialised format should still have a byte or two to specify format and length (because it's no big deal and slightly safer/saner when deserialising), but if it's not the correct value from the schema/.proto file, you get an error when you try to de/serialise. With protobufs, I think you could do this with custom field options: https://developers.google.com/protocol-buffers/docs/proto?hl=en#customoptions Something like: import "descriptor.proto"; extend google.protobuf.FieldOptions { optional int32 fixed_size = 59797; } // Protobufs don't have fixed-length fields, so these are a hack. message sha256_hash2 { required bytes hash = 1 [(fixed_size)=32]; } seems like it works as documentation. Not obvious how to get it passed through to C somehow so that you could actually check it automatically. (Not sure what's with the brackets around fixed_size; it whines if you don't have them.) # lightning public keys... I think there are (at least) three uses for public key crypto in lightning: 1) routing keys -- used for constructing the onion. the routing public key is essentially the node's identity as far as lightning is concerned and must be well known and associated with channels and fees for routing to be possible. *However* a single lightning instance might play host to multiple routing keys. (This would be less efficient for the network, but might be a win for privacy or might be dictated by deployment reasons...) 2) anchor keys -- used for spending the anchor transaction for a channel and thus signing commitment transactions; only needs to be known by the counterparty you're constructing a channel with; can be different for every channel. 3) p2p keys -- used for establishing a shared secret when talking to a node, to avoid your p2p communications being available to someone else (either a passive observer or a MITM). could be different for every connection, or could just have one the lightning instance. # p2p protocol... If Alice tries to connect to Bob, I think the current protocol (as of git commit gc7eaa4f, from daemon/cryptopkt.c) is: Alice: "Call me ." Bob: "Call me ." Then, encrypted to key based on ECDH(RichGirl57914, MoneyBag70623): Alice: "RichGirl57914 is actually Alice, signed " Bob: "MoneyBags70623 is actually Bob, signed " This is secure against passive monitoring; and after the signatures are verified, it's also secure against MITM attacks. It seems like it has a couple of downsides though: - if you're accepting incoming p2p connections, you'll reveal your node id to anyone who asks - if the node you're connecting to is MITM'ed, you'll reveal your node id before realising you're MITM'ed - you can't run multiple node ids on a single connection - Bob has to do crypto operations for every connection, leading to potential DoS attacks I think treating the relationship between a network address (IPv4/IPv6 addr and port, tor service) and the lightning network address as sensitive is valuable. Revealing a network address helps reveal physical identity, makes denial-of-service attacks straightforward, and gives a point of entry for targetted hacking to steal your money.