Skip to content

Commit 67e3312

Browse files
committed
turn TaggedHash into SignatureData enum
1 parent 9de51f0 commit 67e3312

File tree

5 files changed

+181
-68
lines changed

5 files changed

+181
-68
lines changed

lightning/src/offers/invoice.rs

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
//! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
2525
//! use core::convert::{Infallible, TryFrom};
2626
//! use lightning::offers::invoice_request::InvoiceRequest;
27+
//! use lightning::offers::merkle::AsDigest;
2728
//! use lightning::offers::refund::Refund;
2829
//! use lightning::util::ser::Writeable;
2930
//!
@@ -87,7 +88,7 @@
8788
//! .fallback_v0_p2wpkh(&wpubkey_hash)
8889
//! .build()?
8990
//! .sign::<_, Infallible>(
90-
//! |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
91+
//! |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(&message.as_ref().as_digest(), &keys))
9192
//! )
9293
//! .expect("failed verifying signature")
9394
//! .write(&mut buffer)
@@ -115,7 +116,7 @@ use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures, InvoiceRequ
115116
use crate::ln::inbound_payment::ExpandedKey;
116117
use crate::ln::msgs::DecodeError;
117118
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
118-
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, WithoutSignatures, self};
119+
use crate::offers::merkle::{AsDigest, RawData, SignError, SignatureData, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, WithoutSignatures, self};
119120
use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef, Quantity};
120121
use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
121122
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
@@ -149,6 +150,7 @@ pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
149150
invreq_bytes: &'a Vec<u8>,
150151
invoice: InvoiceContents,
151152
signing_pubkey_strategy: S,
153+
raw_data: bool,
152154
}
153155

154156
/// Indicates how [`Bolt12Invoice::signing_pubkey`] was set.
@@ -183,12 +185,12 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
183185
),
184186
};
185187

186-
Self::new(&invoice_request.bytes, contents, ExplicitSigningPubkey {})
188+
Self::new(&invoice_request.bytes, contents, ExplicitSigningPubkey {}, false)
187189
}
188190

189191
pub(super) fn for_refund(
190192
refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
191-
payment_hash: PaymentHash, signing_pubkey: PublicKey
193+
payment_hash: PaymentHash, signing_pubkey: PublicKey,
192194
) -> Result<Self, Bolt12SemanticError> {
193195
let amount_msats = refund.amount_msats();
194196
let contents = InvoiceContents::ForRefund {
@@ -198,7 +200,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
198200
),
199201
};
200202

201-
Self::new(&refund.bytes, contents, ExplicitSigningPubkey {})
203+
Self::new(&refund.bytes, contents, ExplicitSigningPubkey {}, false)
202204
}
203205
}
204206

@@ -216,12 +218,12 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
216218
),
217219
};
218220

219-
Self::new(&invoice_request.bytes, contents, DerivedSigningPubkey(keys))
221+
Self::new(&invoice_request.bytes, contents, DerivedSigningPubkey(keys), false)
220222
}
221223

222224
pub(super) fn for_refund_using_keys(
223225
refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
224-
payment_hash: PaymentHash, keys: KeyPair,
226+
payment_hash: PaymentHash, keys: KeyPair
225227
) -> Result<Self, Bolt12SemanticError> {
226228
let amount_msats = refund.amount_msats();
227229
let signing_pubkey = keys.public_key();
@@ -232,7 +234,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
232234
),
233235
};
234236

235-
Self::new(&refund.bytes, contents, DerivedSigningPubkey(keys))
237+
Self::new(&refund.bytes, contents, DerivedSigningPubkey(keys), false)
236238
}
237239
}
238240

@@ -262,13 +264,14 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
262264
}
263265

264266
fn new(
265-
invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, signing_pubkey_strategy: S
267+
invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, signing_pubkey_strategy: S,
268+
raw_data: bool,
266269
) -> Result<Self, Bolt12SemanticError> {
267270
if contents.fields().payment_paths.is_empty() {
268271
return Err(Bolt12SemanticError::MissingPaths);
269272
}
270273

271-
Ok(Self { invreq_bytes, invoice: contents, signing_pubkey_strategy })
274+
Ok(Self { invreq_bytes, invoice: contents, signing_pubkey_strategy, raw_data })
272275
}
273276

274277
/// Sets the [`Bolt12Invoice::relative_expiry`] as seconds since [`Bolt12Invoice::created_at`].
@@ -327,6 +330,13 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
327330
self.invoice.fields_mut().features.set_basic_mpp_optional();
328331
self
329332
}
333+
334+
/// Indicates that instead of forming a fully formed tagged hash to sign when building and
335+
/// UnsignedBolt12Invoice, we'd like to pass the signer function the raw data instead.
336+
pub fn raw_data(mut self) -> Self {
337+
self.raw_data = true;
338+
self
339+
}
330340
}
331341

332342
impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
@@ -340,7 +350,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
340350
}
341351

342352
let InvoiceBuilder { invreq_bytes, invoice, .. } = self;
343-
Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice))
353+
Ok(UnsignedBolt12Invoice::new(invreq_bytes, invoice, self.raw_data))
344354
}
345355
}
346356

@@ -356,13 +366,13 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
356366
}
357367

358368
let InvoiceBuilder {
359-
invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey(keys)
369+
invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey(keys), raw_data,
360370
} = self;
361-
let unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice);
371+
let unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice, self.raw_data);
362372

363373
let invoice = unsigned_invoice
364374
.sign::<_, Infallible>(
365-
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
375+
|message| Ok(secp_ctx.sign_schnorr_no_aux_rand(&message.as_ref().as_digest(), &keys))
366376
)
367377
.unwrap();
368378
Ok(invoice)
@@ -378,11 +388,11 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
378388
pub struct UnsignedBolt12Invoice {
379389
bytes: Vec<u8>,
380390
contents: InvoiceContents,
381-
tagged_hash: TaggedHash,
391+
data_to_sign: SignatureData,
382392
}
383393

384394
impl UnsignedBolt12Invoice {
385-
fn new(invreq_bytes: &[u8], contents: InvoiceContents) -> Self {
395+
fn new(invreq_bytes: &[u8], contents: InvoiceContents, raw_data: bool) -> Self {
386396
// Use the invoice_request bytes instead of the invoice_request TLV stream as the latter may
387397
// have contained unknown TLV records, which are not stored in `InvoiceRequestContents` or
388398
// `RefundContents`.
@@ -393,14 +403,20 @@ impl UnsignedBolt12Invoice {
393403
let mut bytes = Vec::new();
394404
unsigned_tlv_stream.write(&mut bytes).unwrap();
395405

396-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
406+
let mut data_to_sign = SignatureData::TaggedHash(TaggedHash::new(SIGNATURE_TAG, &bytes));
407+
if raw_data {
408+
data_to_sign = SignatureData::RawData(RawData::new(SIGNATURE_TAG, &bytes))
409+
}
397410

398-
Self { bytes, contents, tagged_hash }
411+
Self { bytes, contents, data_to_sign }
399412
}
400413

401414
/// Returns the [`TaggedHash`] of the invoice to sign.
402415
pub fn tagged_hash(&self) -> &TaggedHash {
403-
&self.tagged_hash
416+
match &self.data_to_sign {
417+
SignatureData::TaggedHash(tagged_hash) => tagged_hash,
418+
SignatureData::RawData(_) => panic!("tagged hash doesn't exist"),
419+
}
404420
}
405421

406422
/// Signs the [`TaggedHash`] of the invoice using the given function.
@@ -429,10 +445,10 @@ impl UnsignedBolt12Invoice {
429445
}
430446
}
431447

432-
impl AsRef<TaggedHash> for UnsignedBolt12Invoice {
433-
fn as_ref(&self) -> &TaggedHash {
434-
&self.tagged_hash
435-
}
448+
impl AsRef<SignatureData> for UnsignedBolt12Invoice {
449+
fn as_ref(&self) -> &SignatureData {
450+
&self.data_to_sign
451+
}
436452
}
437453

438454
/// A `Bolt12Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
@@ -1042,9 +1058,9 @@ impl TryFrom<Vec<u8>> for UnsignedBolt12Invoice {
10421058
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream)
10431059
)?;
10441060

1045-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
1061+
let data_to_sign = SignatureData::TaggedHash(TaggedHash::new(SIGNATURE_TAG, &bytes));
10461062

1047-
Ok(UnsignedBolt12Invoice { bytes, contents, tagged_hash })
1063+
Ok(UnsignedBolt12Invoice { bytes, contents, data_to_sign })
10481064
}
10491065
}
10501066

@@ -1368,7 +1384,7 @@ mod tests {
13681384
Err(e) => panic!("error parsing unsigned invoice: {:?}", e),
13691385
Ok(parsed) => {
13701386
assert_eq!(parsed.bytes, unsigned_invoice.bytes);
1371-
assert_eq!(parsed.tagged_hash, unsigned_invoice.tagged_hash);
1387+
assert_eq!(parsed.tagged_hash(), unsigned_invoice.tagged_hash());
13721388
},
13731389
}
13741390

0 commit comments

Comments
 (0)