Skip to content

Commit 88830ae

Browse files
committed
Introduce Paratonnerre
Paratonnerre is a protocol to safely control a remote lightning node from an untrusted application using a secure hardware device.
1 parent b273c85 commit 88830ae

File tree

3 files changed

+330
-0
lines changed

3 files changed

+330
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ For more detail on the process, please read [bLIP-0001](./blip-0001.md) and
2525
| [10](./blip-0010.md) | Podcasting 2.0 | Satoshis Stream | Active |
2626
| [11](./blip-0011.md) | NameDesc | Hampus Sjöberg | Active |
2727
| [17](./blip-0017.md) | Hosted Channels | Anton Kumaigorodskiy | Active |
28+
| [28](./blip-0028.md) | Paratonnerre | Bastien Teinturier | Active |

blip-0002.md

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ bLIPs may create new messages and reserve their type in the following table:
7171
| 63501 | `hc_updated_fail_htlc` | [bLIP 17](./blip-0017.md) |
7272
| 63499 | `hc_update_fail_malformed_htlc` | [bLIP 17](./blip-0017.md) |
7373
| 63497 | `hc_error` | [bLIP 17](./blip-0017.md) |
74+
| 73760 | `hd_init` | [bLIP 28](./blip-0028.md) |
75+
| 73761 | `hd_command` | [bLIP 28](./blip-0028.md) |
76+
| 73762 | `hd_command_result` | [bLIP 28](./blip-0028.md) |
7477

7578
### TLV fields in BOLT messages
7679

blip-0028.md

+326
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
```
2+
bLIP: 28
3+
Title: Paratonnerre
4+
Status: Draft
5+
Author: Bastien Teinturier <[email protected]>
6+
Created: 2023-09-05
7+
License: CC0
8+
```
9+
10+
## Abstract
11+
12+
This bLIP details how hardware devices can be used to securely control a remote lightning node from an untrusted machine.
13+
14+
## Motivation
15+
16+
Lightning nodes are effectively hot wallets, which makes them valuable targets for attackers.
17+
Node operators thus need to take great care when securing access to their node.
18+
But on the other hand, lightning nodes regularly require actions from the node operator (to open and close channels, pay invoices, etc).
19+
We'd like node operators to be able to complete those tasks without exposing their node to additional threats.
20+
21+
The most common ways of completing such tasks are:
22+
23+
- directly connecting to the node's machine (e.g. using ssh) and calling its local RPCs
24+
- exposing the node's RPCs over the internet, with some form of authentication
25+
26+
Both of these options are dangerous if the machine used to perform those tasks is compromised. This where hardware devices such as hardware wallets come in handy: they let their owner securely perform critical operations from a potentially compromised machine.
27+
28+
## Specification
29+
30+
### Terminology
31+
32+
We use the following three components:
33+
34+
- lightning node: the user's lightning node, running on a remote server
35+
- hardware device: a secure hardware device with a trusted display (e.g. Ledger Nano S)
36+
- companion app: an untrusted application used to communicate with the hardware device and the lightning node
37+
38+
The companion app can run on any kind of untrusted hardware: laptop, desktop, mobile phone, smart watch...anything that has network connectivity and a way to communicate with the hardware device (e.g. bluetooth).
39+
40+
### High-level Architecture
41+
42+
```diagram
43+
+-----------------+ commands +---------------+ +----------------+
44+
| |<-----------------------| | TCP packets | |
45+
| Hardware Device | TCP packets | Companion app |<---------------------->| Lightning Node |
46+
| |<---------------------->| | encrypted (Bolt 8) | |
47+
+-----------------+ encrypted (Bolt 8) +---------------+ +----------------+
48+
```
49+
50+
### Initial Setup
51+
52+
On the hardware device:
53+
54+
- generate a secp256k1 private key and securely store it (e.g. in a secure element)
55+
- display the corresponding public key (`hd_node_id`) on the trusted display
56+
57+
On the lightning node:
58+
59+
- add the corresponding `hd_node_id` to a list of trusted hardware devices
60+
61+
The lightning node will then accept custom lightning messages (defined in the [messages](#messages) section below) from Bolt 8 connections that were initiated from a `node_id` in its list of trusted hardware devices.
62+
63+
### Protocol flow
64+
65+
The protocol is fairly simple: the hardware device implements Bolt 8 and establishes a connection to the lightning node, with the help of the companion app which simply forwards encrypted TCP packets in both directions. Since Bolt 8 encryption and decryption is done entirely within the hardware device, the companion app cannot read or modify any of the messages exchanged between the hardware device and the lightning node.
66+
67+
Before sending any message, the hardware device prints its details on its trusted display and waits for confirmation from the node operator. Similarly, messages from the lightning node are printed on the hardware device's trusted display, which lets the node operator verify the result of the commands that were issued.
68+
69+
The companion app is used to provide an easy-to-use interface to prepare commands. If the companion app tries to trick the hardware device into sending a different command to the lightning node, the node operator will notice it when confirming the command on the hardware device's trusted display.
70+
71+
```diagram
72+
Node Operator Companion App Lightning Node
73+
| create command | |
74+
|------------------------------------------------------->| |
75+
| | |
76+
| Hardware Device | |
77+
| | send(command) | |
78+
| |<------------------------------| |
79+
| confirm command | | |
80+
|<-----------------------| | |
81+
| ok | | |
82+
|----------------------->| | |
83+
| | | |
84+
| +---| | |
85+
| encrypt | | | |
86+
| +-->| | |
87+
| | forward(encrypted_packet) | |
88+
| |------------------------------>| |
89+
| | | encrypted_packet |
90+
| | |------------------------->|
91+
| | | |---+
92+
| | | | | - verify that remote `node_id`
93+
| | | | | is allowed to issue command
94+
| | | | | - execute command
95+
| | | | | - send response
96+
| | | |<--+
97+
| | | encrypted_packet |
98+
| | |<-------------------------|
99+
| | receive(encrypted_packet) | |
100+
| |<------------------------------| |
101+
| +---| | |
102+
| decrypt | | | |
103+
| +-->| | |
104+
| | | |
105+
| command result | | |
106+
|<-----------------------| | |
107+
| | | |
108+
```
109+
110+
### Messages
111+
112+
We define the following new lightning messages:
113+
114+
| Type | Name |
115+
|-------|---------------------|
116+
| 73760 | `hd_init` |
117+
| 73761 | `hd_command` |
118+
| 73762 | `hd_command_result` |
119+
120+
#### The `hd_init` message
121+
122+
The `hd_init` message is used to initialize a connection between a hardware device and a lightning node and negotiate the commands that can be issued on that connection.
123+
124+
1. type: 73760 (`hd_init`)
125+
2. data:
126+
- [`u16`:`commands_len`]
127+
- [`commands_len*byte`:`commands`]
128+
129+
The `commands` field is a bitset where the bit at index `i` indicates support for the `hd_command` with `command_type=i`.
130+
131+
#### The `hd_command` message
132+
133+
The `hd_command` message is always sent by the hardware device. It wraps an actual command.
134+
135+
1. type: 73761 (`hd_command`)
136+
2. data:
137+
- [`u16`:`command_type`]
138+
- [`...byte`:`command`]
139+
140+
#### The `hd_command_result` message
141+
142+
The `hd_command_result` message is always sent by the lightning node in response to an `hd_command`.
143+
It lets the node operator know whether the command was successfully applied or not.
144+
145+
1. type: 73762 (`hd_command_result`)
146+
2. data:
147+
- [`u16`:`command_result_type`]
148+
- [`...byte`:`command_result`]
149+
150+
#### Commands
151+
152+
##### Connect
153+
154+
The `connect` command tells the lightning node to connect to another lightning node.
155+
The `address` field uses the same encoding as the corresponding `node_announcement` field.
156+
157+
1. command type: 0
158+
2. data:
159+
- [`point`:`remote_node_id`]
160+
- [`...*byte`:`address`]
161+
162+
The corresponding `hd_command_result` is:
163+
164+
1. command type: 0
165+
2. data:
166+
- [`point`:`remote_node_id`]
167+
- [`byte`:`success`]
168+
169+
##### Disconnect
170+
171+
The `disconnect` command tells the lightning node to disconnect from one of its peers.
172+
173+
1. command type: 1
174+
2. data:
175+
- [`point`:`remote_node_id`]
176+
177+
The corresponding `hd_command_result` is:
178+
179+
1. command type: 1
180+
2. data:
181+
- [`point`:`remote_node_id`]
182+
- [`byte`:`success`]
183+
184+
##### Open Channel
185+
186+
The `open_channel` command tells the lightning node to open a channel to a given peer.
187+
188+
1. command type: 2
189+
2. data:
190+
- [`point`:`remote_node_id`]
191+
- [`u64`:`funding_satoshis`]
192+
- [`u32`:`feerate_per_kw`]
193+
- [`byte`:`announce_channel`]
194+
- [`u16`:`channel_type_len`]
195+
- [`channel_type_len*byte`:`channel_type`]
196+
197+
The corresponding `hd_command_result` is:
198+
199+
1. command type: 2
200+
2. data:
201+
- [`point`:`remote_node_id`]
202+
- [`byte`:`success`]
203+
- [`channel_id`:`channel_id`]
204+
- [`u64`:`funding_fee_satoshis`]
205+
206+
##### Close Channel
207+
208+
The `close_channel` command tells the lightning node to cooperatively close a channel.
209+
210+
1. command type: 3
211+
2. data:
212+
- [`point`:`remote_node_id`]
213+
- [`channel_id`:`channel_id`]
214+
- [`u32`:`feerate_per_kw`]
215+
- [`u16`:`len`]
216+
- [`len*byte`:`scriptpubkey`]
217+
218+
The corresponding `hd_command_result` is:
219+
220+
1. command type: 3
221+
2. data:
222+
- [`point`:`remote_node_id`]
223+
- [`channel_id`:`channel_id`]
224+
- [`byte`:`success`]
225+
226+
##### Force-Close Channel
227+
228+
The `force_close_channel` command tells the lightning node to unilaterally close a channel.
229+
230+
1. command type: 4
231+
2. data:
232+
- [`point`:`remote_node_id`]
233+
- [`channel_id`:`channel_id`]
234+
235+
The corresponding `hd_command_result` is:
236+
237+
1. command type: 4
238+
2. data:
239+
- [`point`:`remote_node_id`]
240+
- [`channel_id`:`channel_id`]
241+
- [`byte`:`success`]
242+
243+
##### Update Relay Fee
244+
245+
The `update_relay_fee` command tells the lightning node to update the routing fees for channels with a given peer.
246+
247+
1. command type: 5
248+
2. data:
249+
- [`point`:`remote_node_id`]
250+
- [`u32`:`fee_base_msat`]
251+
- [`u32`:`fee_proportional_millionths`]
252+
- [`u16`:`cltv_expiry_delta`]
253+
254+
The corresponding `hd_command_result` is:
255+
256+
1. command type: 5
257+
2. data:
258+
- [`point`:`remote_node_id`]
259+
- [`byte`:`success`]
260+
- [`u32`:`previous_fee_base_msat`]
261+
- [`u32`:`fee_base_msat`]
262+
- [`u32`:`previous_fee_proportional_millionths`]
263+
- [`u32`:`fee_proportional_millionths`]
264+
- [`u16`:`previous_cltv_expiry_delta`]
265+
- [`u16`:`cltv_expiry_delta`]
266+
267+
##### Create Invoice
268+
269+
The `create_invoice` command tells the lightning node to create a Bolt 11 invoice.
270+
271+
1. command type: 6
272+
2. data:
273+
- [`u32`:`amount_msat`]
274+
- [`u16`:`description_len`]
275+
- [`description_len*byte`:`description`]
276+
277+
The corresponding `hd_command_result` is:
278+
279+
1. command type: 6
280+
2. data:
281+
- [`u16`:`invoice_len`]
282+
- [`invoice_len*byte`:`invoice`]
283+
284+
##### Pay Invoice
285+
286+
The `pay_invoice` command tells the lightning node to pay a given Bolt 11 invoice.
287+
288+
1. command type: 7
289+
2. data:
290+
- [`u16`:`invoice_len`]
291+
- [`invoice_len*byte`:`invoice`]
292+
- [`u32`:`amount_msat`]
293+
- [`u32`:`max_fee_msat`]
294+
295+
The corresponding `hd_command_result` is:
296+
297+
1. command type: 7
298+
2. data:
299+
- [`byte`:`success`]
300+
- [`32*byte`:`payment_preimage`]
301+
- [`u32`:`routing_fees_msat`]
302+
303+
### Requirements
304+
305+
The hardware device:
306+
307+
- MUST display the `node_id` of the lightning node and wait for confirmation before initiating a connection
308+
- MUST encrypted packets as specified in Bolt 8 before sending them to the companion app
309+
- MUST send `hd_init` instead of the standard `init` message once the connection has been established
310+
- MUST display commands and wait for confirmation before sending them
311+
- MUST send `ping` messages to keep the lightning connection alive
312+
- MUST respond to `ping` messages
313+
- SHOULD NOT require confirmation before sending `ping` and `pong` messages
314+
315+
The lightning node, when receiving a connection from a `node_id` in its configured list of trusted hardware devices:
316+
317+
- MUST send `hd_init` instead of the standard `init` message once the connection has been established
318+
- MUST only send the following messages on that connection:
319+
- `hd_init`
320+
- `hd_command_result`
321+
- `ping`
322+
- `pong`
323+
324+
## Copyright
325+
326+
This bLIP is licensed under the CC0 license.

0 commit comments

Comments
 (0)