@@ -26,9 +26,10 @@ use bitcoin::hashes::sha256::Hash as Sha256;
26
26
use bitcoin:: hashes:: sha256d:: Hash as Sha256dHash ;
27
27
use bitcoin:: hash_types:: WPubkeyHash ;
28
28
29
- use bitcoin:: secp256k1:: { PublicKey , Scalar , Secp256k1 , SecretKey , Signing } ;
29
+ use bitcoin:: secp256k1:: { KeyPair , PublicKey , Scalar , Secp256k1 , SecretKey , Signing } ;
30
30
use bitcoin:: secp256k1:: ecdh:: SharedSecret ;
31
31
use bitcoin:: secp256k1:: ecdsa:: { RecoverableSignature , Signature } ;
32
+ use bitcoin:: secp256k1:: schnorr;
32
33
use bitcoin:: { PackedLockTime , secp256k1, Sequence , Witness } ;
33
34
34
35
use crate :: util:: transaction_utils;
@@ -41,6 +42,8 @@ use crate::ln::{chan_utils, PaymentPreimage};
41
42
use crate :: ln:: chan_utils:: { HTLCOutputInCommitment , make_funding_redeemscript, ChannelPublicKeys , HolderCommitmentTransaction , ChannelTransactionParameters , CommitmentTransaction , ClosingTransaction } ;
42
43
use crate :: ln:: msgs:: { UnsignedChannelAnnouncement , UnsignedGossipMessage } ;
43
44
use crate :: ln:: script:: ShutdownScript ;
45
+ use crate :: offers:: invoice:: UnsignedBolt12Invoice ;
46
+ use crate :: offers:: invoice_request:: UnsignedInvoiceRequest ;
44
47
45
48
use crate :: prelude:: * ;
46
49
use core:: convert:: TryInto ;
@@ -619,6 +622,36 @@ pub trait NodeSigner {
619
622
/// Errors if the [`Recipient`] variant is not supported by the implementation.
620
623
fn sign_invoice ( & self , hrp_bytes : & [ u8 ] , invoice_data : & [ u5 ] , recipient : Recipient ) -> Result < RecoverableSignature , ( ) > ;
621
624
625
+ /// Signs the [`TaggedHash`] of a BOLT 12 invoice request.
626
+ ///
627
+ /// May be called by a function passed to [`UnsignedInvoiceRequest::sign`] where
628
+ /// `invoice_request` is the callee.
629
+ ///
630
+ /// Implementors may check that the `invoice_request` is expected rather than blindly signing
631
+ /// the tagged hash. An `Ok` result should sign `invoice_request.tagged_hash().as_digest()` with
632
+ /// the node's signing key or an ephemeral key to preserve privacy, whichever is associated with
633
+ /// [`UnsignedInvoiceRequest::payer_id`].
634
+ ///
635
+ /// [`TaggedHash`]: crate::offers::merkle::TaggedHash
636
+ fn sign_bolt12_invoice_request (
637
+ & self , invoice_request : & UnsignedInvoiceRequest
638
+ ) -> Result < schnorr:: Signature , ( ) > ;
639
+
640
+ /// Signs the [`TaggedHash`] of a BOLT 12 invoice.
641
+ ///
642
+ /// May be called by a function passed to [`UnsignedBolt12Invoice::sign`] where `invoice` is the
643
+ /// callee.
644
+ ///
645
+ /// Implementors may check that the `invoice` is expected rather than blindly signing the tagged
646
+ /// hash. An `Ok` result should sign `invoice.tagged_hash().as_digest()` with the node's signing
647
+ /// key or an ephemeral key to preserve privacy, whichever is associated with
648
+ /// [`UnsignedBolt12Invoice::signing_pubkey`].
649
+ ///
650
+ /// [`TaggedHash`]: crate::offers::merkle::TaggedHash
651
+ fn sign_bolt12_invoice (
652
+ & self , invoice : & UnsignedBolt12Invoice
653
+ ) -> Result < schnorr:: Signature , ( ) > ;
654
+
622
655
/// Sign a gossip message.
623
656
///
624
657
/// Note that if this fails, LDK may panic and the message will not be broadcast to the network
@@ -1449,6 +1482,24 @@ impl NodeSigner for KeysManager {
1449
1482
Ok ( self . secp_ctx . sign_ecdsa_recoverable ( & hash_to_message ! ( & Sha256 :: hash( & preimage) ) , secret) )
1450
1483
}
1451
1484
1485
+ fn sign_bolt12_invoice_request (
1486
+ & self , invoice_request : & UnsignedInvoiceRequest
1487
+ ) -> Result < schnorr:: Signature , ( ) > {
1488
+ let message = invoice_request. tagged_hash ( ) . as_digest ( ) ;
1489
+ let keys = KeyPair :: from_secret_key ( & self . secp_ctx , & self . node_secret ) ;
1490
+ let aux_rand = self . get_secure_random_bytes ( ) ;
1491
+ Ok ( self . secp_ctx . sign_schnorr_with_aux_rand ( message, & keys, & aux_rand) )
1492
+ }
1493
+
1494
+ fn sign_bolt12_invoice (
1495
+ & self , invoice : & UnsignedBolt12Invoice
1496
+ ) -> Result < schnorr:: Signature , ( ) > {
1497
+ let message = invoice. tagged_hash ( ) . as_digest ( ) ;
1498
+ let keys = KeyPair :: from_secret_key ( & self . secp_ctx , & self . node_secret ) ;
1499
+ let aux_rand = self . get_secure_random_bytes ( ) ;
1500
+ Ok ( self . secp_ctx . sign_schnorr_with_aux_rand ( message, & keys, & aux_rand) )
1501
+ }
1502
+
1452
1503
fn sign_gossip_message ( & self , msg : UnsignedGossipMessage ) -> Result < Signature , ( ) > {
1453
1504
let msg_hash = hash_to_message ! ( & Sha256dHash :: hash( & msg. encode( ) [ ..] ) [ ..] ) ;
1454
1505
Ok ( self . secp_ctx . sign_ecdsa ( & msg_hash, & self . node_secret ) )
@@ -1557,6 +1608,18 @@ impl NodeSigner for PhantomKeysManager {
1557
1608
Ok ( self . inner . secp_ctx . sign_ecdsa_recoverable ( & hash_to_message ! ( & Sha256 :: hash( & preimage) ) , secret) )
1558
1609
}
1559
1610
1611
+ fn sign_bolt12_invoice_request (
1612
+ & self , invoice_request : & UnsignedInvoiceRequest
1613
+ ) -> Result < schnorr:: Signature , ( ) > {
1614
+ self . inner . sign_bolt12_invoice_request ( invoice_request)
1615
+ }
1616
+
1617
+ fn sign_bolt12_invoice (
1618
+ & self , invoice : & UnsignedBolt12Invoice
1619
+ ) -> Result < schnorr:: Signature , ( ) > {
1620
+ self . inner . sign_bolt12_invoice ( invoice)
1621
+ }
1622
+
1560
1623
fn sign_gossip_message ( & self , msg : UnsignedGossipMessage ) -> Result < Signature , ( ) > {
1561
1624
self . inner . sign_gossip_message ( msg)
1562
1625
}
0 commit comments