|
19 | 19 |
|
20 | 20 | use alloc::collections::BTreeSet; |
21 | 21 |
|
| 22 | +use super::signer::derive_keys; |
22 | 23 | use crate::io; |
23 | 24 | use crate::io::Read; |
| 25 | +use crate::ln::inbound_payment::ExpandedKey; |
24 | 26 | use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG}; |
25 | 27 | use crate::offers::invoice_request::INVOICE_REQUEST_PAYER_ID_TYPE; |
26 | 28 | use crate::offers::merkle::{ |
27 | 29 | self, SelectiveDisclosure, SelectiveDisclosureError, TaggedHash, TlvStream, SIGNATURE_TYPES, |
28 | 30 | }; |
| 31 | +use crate::offers::nonce::Nonce; |
29 | 32 | use crate::offers::parse::Bech32Encode; |
30 | 33 | use crate::types::features::Bolt12InvoiceFeatures; |
31 | 34 | use crate::types::payment::{PaymentHash, PaymentPreimage}; |
@@ -311,6 +314,28 @@ impl UnsignedPayerProof { |
311 | 314 | }) |
312 | 315 | } |
313 | 316 |
|
| 317 | + /// Sign the proof using a key derived from an [`ExpandedKey`] and [`Nonce`]. |
| 318 | + /// |
| 319 | + /// This method derives the payer signing key using the same derivation scheme as invoice |
| 320 | + /// requests with derived signing pubkeys. Use this when the invoice request was created |
| 321 | + /// with `deriving_signing_pubkey` and you want to sign the payer proof with the same key. |
| 322 | + /// |
| 323 | + /// The derived key must match the `payer_id` in the original invoice for the signature |
| 324 | + /// to be valid. |
| 325 | + pub fn sign_with_derived_key( |
| 326 | + self, expanded_key: &ExpandedKey, nonce: Nonce, note: Option<&str>, |
| 327 | + ) -> Result<PayerProof, PayerProofError> { |
| 328 | + let keys = derive_keys(nonce, expanded_key); |
| 329 | + |
| 330 | + // Verify the derived key matches the expected payer_id |
| 331 | + if keys.public_key() != self.payer_id { |
| 332 | + return Err(PayerProofError::InvalidPayerSignature); |
| 333 | + } |
| 334 | + |
| 335 | + let secp_ctx = Secp256k1::new(); |
| 336 | + self.sign(|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message, &keys)), note) |
| 337 | + } |
| 338 | + |
314 | 339 | /// Compute the payer signature message per BOLT 12 signature calculation. |
315 | 340 | fn compute_payer_signature_message(note: Option<&str>, merkle_root: &sha256::Hash) -> Message { |
316 | 341 | let mut inner_hasher = sha256::Hash::engine(); |
|
0 commit comments