Skip to content

Commit c9dc3ef

Browse files
offer: make the merkle tree signature public
This is helpfull for the users that want to use the merkle tree signature in their own code, for example to verify the signature of bolt12 invoices or recreate it. Very useful for people that are building command line tools for the bolt12 offers. Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent 1d507f2 commit c9dc3ef

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

lightning/src/offers/invoice.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,4 +3560,37 @@ mod tests {
35603560
),
35613561
}
35623562
}
3563+
3564+
#[test]
3565+
fn verifies_invoice_signature_with_tagged_hash() {
3566+
let secp_ctx = Secp256k1::new();
3567+
let expanded_key = ExpandedKey::new([42; 32]);
3568+
let entropy = FixedEntropy {};
3569+
let nonce = Nonce::from_entropy_source(&entropy);
3570+
let node_id = recipient_pubkey();
3571+
let payment_paths = payment_paths();
3572+
let now = Duration::from_secs(123456);
3573+
let payment_id = PaymentId([1; 32]);
3574+
3575+
let offer = OfferBuilder::new(node_id).amount_msats(1000).build().unwrap();
3576+
3577+
let invoice_request = offer
3578+
.request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
3579+
.unwrap()
3580+
.build_and_sign()
3581+
.unwrap();
3582+
3583+
let invoice = invoice_request
3584+
.respond_with_no_std(payment_paths, payment_hash(), now)
3585+
.unwrap()
3586+
.build()
3587+
.unwrap()
3588+
.sign(recipient_sign)
3589+
.unwrap();
3590+
3591+
let issuer_sign_pubkey = offer.issuer_signing_pubkey().unwrap();
3592+
let tagged_hash = invoice.tagged_hash();
3593+
let signature = invoice.signature();
3594+
assert!(merkle::verify_signature(&signature, tagged_hash, issuer_sign_pubkey).is_ok());
3595+
}
35633596
}

lightning/src/offers/merkle.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub enum SignError {
9494
}
9595

9696
/// A function for signing a [`TaggedHash`].
97-
pub(super) trait SignFn<T: AsRef<TaggedHash>> {
97+
pub trait SignFn<T: AsRef<TaggedHash>> {
9898
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
9999
fn sign(&self, message: &T) -> Result<Signature, ()>;
100100
}
@@ -117,9 +117,7 @@ where
117117
///
118118
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
119119
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
120-
pub(super) fn sign_message<F, T>(
121-
f: F, message: &T, pubkey: PublicKey,
122-
) -> Result<Signature, SignError>
120+
pub fn sign_message<F, T>(f: F, message: &T, pubkey: PublicKey) -> Result<Signature, SignError>
123121
where
124122
F: SignFn<T>,
125123
T: AsRef<TaggedHash>,
@@ -136,7 +134,7 @@ where
136134

137135
/// Verifies the signature with a pubkey over the given message using a tagged hash as the message
138136
/// digest.
139-
pub(super) fn verify_signature(
137+
pub fn verify_signature(
140138
signature: &Signature, message: &TaggedHash, pubkey: PublicKey,
141139
) -> Result<(), secp256k1::Error> {
142140
let digest = message.as_digest();

0 commit comments

Comments
 (0)