Skip to content

Commit 66c4fcf

Browse files
committed
Support signing BOLT 12 messages in NodeSigner
BOLT 12 messages need to be signed in the following scenarios: - constructing an InvoiceRequest after scanning an Offer, - constructing an Invoice after scanning a Refund, and - constructing an Invoice when handling an InvoiceRequest. Extend the NodeSigner trait to support signing BOLT 12 messages such that it can be used in these contexts. The method could be used then in OnionMessenger and an OffersMessageHandler.
1 parent a9c2acd commit 66c4fcf

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ use crate::utils::test_persister::TestPersister;
5858
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
5959
use bitcoin::secp256k1::ecdh::SharedSecret;
6060
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
61+
use bitcoin::secp256k1::schnorr;
6162

6263
use std::mem;
6364
use std::cmp::{self, Ordering};
@@ -212,6 +213,12 @@ impl NodeSigner for KeyProvider {
212213
unreachable!()
213214
}
214215

216+
fn sign_bolt12_message(
217+
&self, _digest: &Message, _tag: &str, _bytes: &[u8], _metadata: &[u8]
218+
) -> Result<schnorr::Signature, ()> {
219+
unreachable!()
220+
}
221+
215222
fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
216223
let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
217224
let secp_ctx = Secp256k1::signing_only();

fuzz/src/full_stack.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use crate::utils::test_persister::TestPersister;
5656
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
5757
use bitcoin::secp256k1::ecdh::SharedSecret;
5858
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
59+
use bitcoin::secp256k1::schnorr;
5960

6061
use std::cell::RefCell;
6162
use hashbrown::{HashMap, hash_map};
@@ -316,6 +317,12 @@ impl NodeSigner for KeyProvider {
316317
unreachable!()
317318
}
318319

320+
fn sign_bolt12_message(
321+
&self, _digest: &Message, _tag: &str, _bytes: &[u8], _metadata: &[u8]
322+
) -> Result<schnorr::Signature, ()> {
323+
unreachable!()
324+
}
325+
319326
fn sign_gossip_message(&self, msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
320327
let msg_hash = Message::from_slice(&Sha256dHash::hash(&msg.encode()[..])[..]).map_err(|_| ())?;
321328
let secp_ctx = Secp256k1::signing_only();

fuzz/src/onion_message.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Imports that need to be added manually
22
use bitcoin::bech32::u5;
33
use bitcoin::blockdata::script::Script;
4-
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
4+
use bitcoin::secp256k1::{Message, PublicKey, Scalar, Secp256k1, SecretKey};
55
use bitcoin::secp256k1::ecdh::SharedSecret;
66
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
7+
use bitcoin::secp256k1::schnorr;
78

89
use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
910
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
@@ -158,6 +159,12 @@ impl NodeSigner for KeyProvider {
158159
unreachable!()
159160
}
160161

162+
fn sign_bolt12_message(
163+
&self, _digest: &Message, _tag: &str, _bytes: &[u8], _metadata: &[u8]
164+
) -> Result<schnorr::Signature, ()> {
165+
unreachable!()
166+
}
167+
161168
fn sign_gossip_message(&self, _msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
162169
unreachable!()
163170
}

lightning/src/sign/mod.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ use bitcoin::hashes::sha256::Hash as Sha256;
2626
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
2727
use bitcoin::hash_types::WPubkeyHash;
2828

29-
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey, Signing};
29+
use bitcoin::secp256k1::{Message, PublicKey, Scalar, Secp256k1, SecretKey, Signing};
3030
use bitcoin::secp256k1::ecdh::SharedSecret;
3131
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
32+
use bitcoin::secp256k1::schnorr;
3233
use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
3334

3435
use crate::util::transaction_utils;
@@ -620,6 +621,19 @@ pub trait NodeSigner {
620621
/// Errors if the [`Recipient`] variant is not supported by the implementation.
621622
fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()>;
622623

624+
/// Signs a BOLT 12 message.
625+
///
626+
/// The message is given in `bytes` as a serialized TLV stream with `tag` identifying the
627+
/// message type as defined in the BOLT 12 spec's "Signature Calculation" section. The `digest`
628+
/// is the tagged merkle root to be signed and can be re-calculated using `tag` and `bytes` if
629+
/// blindly signing the digest should be avoided.
630+
///
631+
/// `metadata` is either the payer or offer metadata, depending on the message type and origin,
632+
/// and may be useful in order to derive the signing keys.
633+
fn sign_bolt12_message(
634+
&self, digest: &Message, tag: &str, bytes: &[u8], metadata: &[u8]
635+
) -> Result<schnorr::Signature, ()>;
636+
623637
/// Sign a gossip message.
624638
///
625639
/// Note that if this fails, LDK may panic and the message will not be broadcast to the network
@@ -1437,6 +1451,12 @@ impl NodeSigner for KeysManager {
14371451
Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
14381452
}
14391453

1454+
fn sign_bolt12_message(
1455+
&self, digest: &Message, tag: &str, bytes: &[u8], metadata: &[u8]
1456+
) -> Result<schnorr::Signature, ()> {
1457+
todo!()
1458+
}
1459+
14401460
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
14411461
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
14421462
Ok(self.secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
@@ -1545,6 +1565,12 @@ impl NodeSigner for PhantomKeysManager {
15451565
Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
15461566
}
15471567

1568+
fn sign_bolt12_message(
1569+
&self, digest: &Message, tag: &str, bytes: &[u8], metadata: &[u8]
1570+
) -> Result<schnorr::Signature, ()> {
1571+
todo!()
1572+
}
1573+
15481574
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
15491575
self.inner.sign_gossip_message(msg)
15501576
}

lightning/src/util/test_utils.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ use bitcoin::blockdata::block::Block;
4040
use bitcoin::network::constants::Network;
4141
use bitcoin::hash_types::{BlockHash, Txid};
4242

43-
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
43+
use bitcoin::secp256k1::{Message, PublicKey, Scalar, Secp256k1, SecretKey};
4444
use bitcoin::secp256k1::ecdh::SharedSecret;
4545
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
46+
use bitcoin::secp256k1::schnorr;
4647

4748
use regex;
4849

@@ -782,6 +783,12 @@ impl NodeSigner for TestNodeSigner {
782783
unreachable!()
783784
}
784785

786+
fn sign_bolt12_message(
787+
&self, _digest: &Message, _tag: &str, _bytes: &[u8], _metadata: &[u8]
788+
) -> Result<schnorr::Signature, ()> {
789+
unreachable!()
790+
}
791+
785792
fn sign_gossip_message(&self, _msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
786793
unreachable!()
787794
}
@@ -822,6 +829,12 @@ impl NodeSigner for TestKeysInterface {
822829
self.backing.sign_invoice(hrp_bytes, invoice_data, recipient)
823830
}
824831

832+
fn sign_bolt12_message(
833+
&self, digest: &Message, tag: &str, bytes: &[u8], metadata: &[u8]
834+
) -> Result<schnorr::Signature, ()> {
835+
self.backing.sign_bolt12_message(digest, tag, bytes, metadata)
836+
}
837+
825838
fn sign_gossip_message(&self, msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
826839
self.backing.sign_gossip_message(msg)
827840
}

0 commit comments

Comments
 (0)