Skip to content

Commit c0a0a5f

Browse files
committed
f - extract offer id from invreq bytes
1 parent 70b9dec commit c0a0a5f

File tree

5 files changed

+56
-38
lines changed

5 files changed

+56
-38
lines changed

lightning/src/offers/invoice.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ impl UnsignedBolt12Invoice {
546546
let mut bytes = Vec::new();
547547
unsigned_tlv_stream.write(&mut bytes).unwrap();
548548

549-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
549+
let tagged_hash = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
550550

551551
Self { bytes, contents, tagged_hash }
552552
}
@@ -1225,7 +1225,7 @@ impl TryFrom<Vec<u8>> for UnsignedBolt12Invoice {
12251225
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream)
12261226
)?;
12271227

1228-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
1228+
let tagged_hash = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
12291229

12301230
Ok(UnsignedBolt12Invoice { bytes, contents, tagged_hash })
12311231
}
@@ -1370,7 +1370,7 @@ impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
13701370
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
13711371
Some(signature) => signature,
13721372
};
1373-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
1373+
let tagged_hash = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
13741374
let pubkey = contents.fields().signing_pubkey;
13751375
merkle::verify_signature(&signature, &tagged_hash, pubkey)?;
13761376

@@ -1599,7 +1599,7 @@ mod tests {
15991599
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
16001600
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
16011601

1602-
let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
1602+
let message = TaggedHash::from_bytes(SIGNATURE_TAG, &invoice.bytes);
16031603
assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
16041604

16051605
let digest = Message::from_slice(&invoice.signable_hash()).unwrap();
@@ -1696,7 +1696,7 @@ mod tests {
16961696
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
16971697
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
16981698

1699-
let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
1699+
let message = TaggedHash::from_bytes(SIGNATURE_TAG, &invoice.bytes);
17001700
assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
17011701

17021702
assert_eq!(

lightning/src/offers/invoice_request.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ impl UnsignedInvoiceRequest {
529529
let mut bytes = Vec::new();
530530
unsigned_tlv_stream.write(&mut bytes).unwrap();
531531

532-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
532+
let tagged_hash = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
533533

534534
Self { bytes, contents, tagged_hash }
535535
}
@@ -1026,7 +1026,7 @@ impl TryFrom<Vec<u8>> for UnsignedInvoiceRequest {
10261026
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
10271027
)?;
10281028

1029-
let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
1029+
let tagged_hash = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
10301030

10311031
Ok(UnsignedInvoiceRequest { bytes, contents, tagged_hash })
10321032
}
@@ -1050,7 +1050,7 @@ impl TryFrom<Vec<u8>> for InvoiceRequest {
10501050
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
10511051
Some(signature) => signature,
10521052
};
1053-
let message = TaggedHash::new(SIGNATURE_TAG, &bytes);
1053+
let message = TaggedHash::from_bytes(SIGNATURE_TAG, &bytes);
10541054
merkle::verify_signature(&signature, &message, contents.payer_id)?;
10551055

10561056
Ok(InvoiceRequest { bytes, contents, signature })
@@ -1197,7 +1197,7 @@ mod tests {
11971197
assert_eq!(invoice_request.payer_id(), payer_pubkey());
11981198
assert_eq!(invoice_request.payer_note(), None);
11991199

1200-
let message = TaggedHash::new(SIGNATURE_TAG, &invoice_request.bytes);
1200+
let message = TaggedHash::from_bytes(SIGNATURE_TAG, &invoice_request.bytes);
12011201
assert!(merkle::verify_signature(&invoice_request.signature, &message, payer_pubkey()).is_ok());
12021202

12031203
assert_eq!(
@@ -1302,7 +1302,7 @@ mod tests {
13021302
let mut bytes = Vec::new();
13031303
tlv_stream.write(&mut bytes).unwrap();
13041304

1305-
let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1305+
let message = TaggedHash::from_bytes(INVOICE_SIGNATURE_TAG, &bytes);
13061306
let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
13071307
signature_tlv_stream.signature = Some(&signature);
13081308

@@ -1325,7 +1325,7 @@ mod tests {
13251325
let mut bytes = Vec::new();
13261326
tlv_stream.write(&mut bytes).unwrap();
13271327

1328-
let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1328+
let message = TaggedHash::from_bytes(INVOICE_SIGNATURE_TAG, &bytes);
13291329
let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
13301330
signature_tlv_stream.signature = Some(&signature);
13311331

@@ -1374,7 +1374,7 @@ mod tests {
13741374
let mut bytes = Vec::new();
13751375
tlv_stream.write(&mut bytes).unwrap();
13761376

1377-
let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1377+
let message = TaggedHash::from_bytes(INVOICE_SIGNATURE_TAG, &bytes);
13781378
let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
13791379
signature_tlv_stream.signature = Some(&signature);
13801380

@@ -1397,7 +1397,7 @@ mod tests {
13971397
let mut bytes = Vec::new();
13981398
tlv_stream.write(&mut bytes).unwrap();
13991399

1400-
let message = TaggedHash::new(INVOICE_SIGNATURE_TAG, &bytes);
1400+
let message = TaggedHash::from_bytes(INVOICE_SIGNATURE_TAG, &bytes);
14011401
let signature = merkle::sign_message(recipient_sign, &message, recipient_pubkey()).unwrap();
14021402
signature_tlv_stream.signature = Some(&signature);
14031403

lightning/src/offers/merkle.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,20 @@ pub struct TaggedHash {
3838
}
3939

4040
impl TaggedHash {
41+
/// Creates a tagged hash with the given parameters.
42+
///
43+
/// Panics if `bytes` is not a well-formed TLV stream containing at least one TLV record.
44+
pub(super) fn from_bytes(tag: &'static str, bytes: &[u8]) -> Self {
45+
let tlv_stream = TlvStream::new(bytes);
46+
Self::from_tlv_stream(tag, tlv_stream)
47+
}
48+
4149
/// Creates a tagged hash with the given parameters.
4250
///
4351
/// Panics if `tlv_stream` is not a well-formed TLV stream containing at least one TLV record.
44-
pub(super) fn new(tag: &'static str, tlv_stream: &[u8]) -> Self {
52+
pub(super) fn from_tlv_stream<'a, I: core::iter::Iterator<Item = TlvRecord<'a>>>(
53+
tag: &'static str, tlv_stream: I
54+
) -> Self {
4555
let tag_hash = sha256::Hash::hash(tag.as_bytes());
4656
let merkle_root = root_hash(tlv_stream);
4757
let digest = Message::from_slice(tagged_hash(tag_hash, merkle_root).as_byte_array()).unwrap();
@@ -141,9 +151,10 @@ pub(super) fn verify_signature(
141151

142152
/// Computes a merkle root hash for the given data, which must be a well-formed TLV stream
143153
/// containing at least one TLV record.
144-
fn root_hash(data: &[u8]) -> sha256::Hash {
154+
fn root_hash<'a, I: core::iter::Iterator<Item = TlvRecord<'a>>>(tlv_stream: I) -> sha256::Hash {
155+
let mut tlv_stream = tlv_stream.peekable();
145156
let nonce_tag = tagged_hash_engine(sha256::Hash::from_engine({
146-
let first_tlv_record = TlvStream::new(&data[..]).next().unwrap();
157+
let first_tlv_record = tlv_stream.peek().unwrap();
147158
let mut engine = sha256::Hash::engine();
148159
engine.input("LnNonce".as_bytes());
149160
engine.input(first_tlv_record.record_bytes);
@@ -153,8 +164,7 @@ fn root_hash(data: &[u8]) -> sha256::Hash {
153164
let branch_tag = tagged_hash_engine(sha256::Hash::hash("LnBranch".as_bytes()));
154165

155166
let mut leaves = Vec::new();
156-
let tlv_stream = TlvStream::new(&data[..]);
157-
for record in tlv_stream.skip_signatures() {
167+
for record in TlvStream::skip_signatures(tlv_stream) {
158168
leaves.push(tagged_hash_from_engine(leaf_tag.clone(), &record.record_bytes));
159169
leaves.push(tagged_hash_from_engine(nonce_tag.clone(), &record.type_bytes));
160170
}
@@ -231,8 +241,10 @@ impl<'a> TlvStream<'a> {
231241
.take_while(move |record| take_range.contains(&record.r#type))
232242
}
233243

234-
fn skip_signatures(self) -> core::iter::Filter<TlvStream<'a>, fn(&TlvRecord) -> bool> {
235-
self.filter(|record| !SIGNATURE_TYPES.contains(&record.r#type))
244+
fn skip_signatures(
245+
tlv_stream: impl core::iter::Iterator<Item = TlvRecord<'a>>
246+
) -> impl core::iter::Iterator<Item = TlvRecord<'a>> {
247+
tlv_stream.filter(|record| !SIGNATURE_TYPES.contains(&record.r#type))
236248
}
237249
}
238250

@@ -280,7 +292,7 @@ impl<'a> Writeable for WithoutSignatures<'a> {
280292
#[inline]
281293
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
282294
let tlv_stream = TlvStream::new(self.0);
283-
for record in tlv_stream.skip_signatures() {
295+
for record in TlvStream::skip_signatures(tlv_stream) {
284296
writer.write_all(record.record_bytes)?;
285297
}
286298
Ok(())
@@ -308,15 +320,15 @@ mod tests {
308320
macro_rules! tlv2 { () => { "02080000010000020003" } }
309321
macro_rules! tlv3 { () => { "03310266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c0351800000000000000010000000000000002" } }
310322
assert_eq!(
311-
super::root_hash(&<Vec<u8>>::from_hex(tlv1!()).unwrap()),
323+
super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(tlv1!()).unwrap())),
312324
sha256::Hash::from_slice(&<Vec<u8>>::from_hex("b013756c8fee86503a0b4abdab4cddeb1af5d344ca6fc2fa8b6c08938caa6f93").unwrap()).unwrap(),
313325
);
314326
assert_eq!(
315-
super::root_hash(&<Vec<u8>>::from_hex(concat!(tlv1!(), tlv2!())).unwrap()),
327+
super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(concat!(tlv1!(), tlv2!())).unwrap())),
316328
sha256::Hash::from_slice(&<Vec<u8>>::from_hex("c3774abbf4815aa54ccaa026bff6581f01f3be5fe814c620a252534f434bc0d1").unwrap()).unwrap(),
317329
);
318330
assert_eq!(
319-
super::root_hash(&<Vec<u8>>::from_hex(concat!(tlv1!(), tlv2!(), tlv3!())).unwrap()),
331+
super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(concat!(tlv1!(), tlv2!(), tlv3!())).unwrap())),
320332
sha256::Hash::from_slice(&<Vec<u8>>::from_hex("ab2e79b1283b0b31e0b035258de23782df6b89a38cfa7237bde69aed1a658c5d").unwrap()).unwrap(),
321333
);
322334
}
@@ -348,7 +360,7 @@ mod tests {
348360
"lnr1qqyqqqqqqqqqqqqqqcp4256ypqqkgzshgysy6ct5dpjk6ct5d93kzmpq23ex2ct5d9ek293pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpjkppqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43euzqhrurageg3n7kafgsek6gz3e9w52parv8gs2hlxzk95tzeswywffxlkeyhml0hh46kndmwf4m6xma3tkq2lu04qz3slje2rfthc89vss",
349361
);
350362
assert_eq!(
351-
super::root_hash(&invoice_request.bytes[..]),
363+
super::root_hash(TlvStream::new(&invoice_request.bytes[..])),
352364
sha256::Hash::from_slice(&<Vec<u8>>::from_hex("608407c18ad9a94d9ea2bcdbe170b6c20c462a7833a197621c916f78cf18e624").unwrap()).unwrap(),
353365
);
354366
assert_eq!(

lightning/src/offers/offer.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,13 @@ impl OfferId {
122122
const ID_TAG: &'static str = concat!("lightning", "offer");
123123

124124
fn from_offer_bytes(bytes: &[u8]) -> Self {
125-
let tagged_hash = TaggedHash::new(Self::ID_TAG, &bytes);
125+
let tagged_hash = TaggedHash::from_bytes(Self::ID_TAG, bytes);
126+
Self(tagged_hash.to_bytes())
127+
}
128+
129+
fn from_invreq_bytes(bytes: &[u8]) -> Self {
130+
let tlv_stream = TlvStream::new(bytes).range(OFFER_TYPES);
131+
let tagged_hash = TaggedHash::from_tlv_stream(Self::ID_TAG, tlv_stream);
126132
Self(tagged_hash.to_bytes())
127133
}
128134
}
@@ -889,10 +895,12 @@ impl OfferContents {
889895
_ => true,
890896
}
891897
});
892-
let (keys, nonce) = signer::verify_recipient_metadata(
898+
let keys = signer::verify_recipient_metadata(
893899
metadata, key, IV_BYTES, self.signing_pubkey(), tlv_stream, secp_ctx
894900
)?;
895-
let offer_id = OfferId(nonce);
901+
902+
let offer_id = OfferId::from_invreq_bytes(bytes);
903+
896904
Ok((offer_id, keys))
897905
},
898906
None => Err(()),
@@ -1230,17 +1238,17 @@ mod tests {
12301238

12311239
#[cfg(c_bindings)]
12321240
use super::OfferWithDerivedMetadataBuilder as OfferBuilder;
1233-
let (offer_id, offer) = OfferBuilder
1241+
let offer = OfferBuilder
12341242
::deriving_signing_pubkey(desc, node_id, &expanded_key, &entropy, &secp_ctx)
12351243
.amount_msats(1000)
1236-
.build_with_id().unwrap();
1244+
.build().unwrap();
12371245
assert_eq!(offer.signing_pubkey(), node_id);
12381246

12391247
let invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
12401248
.build().unwrap()
12411249
.sign(payer_sign).unwrap();
12421250
match invoice_request.verify(&expanded_key, &secp_ctx) {
1243-
Ok(invoice_request) => assert_eq!(invoice_request.offer_id, offer_id),
1251+
Ok(invoice_request) => assert_eq!(invoice_request.offer_id, offer.id()),
12441252
Err(_) => panic!("unexpected error"),
12451253
}
12461254

@@ -1291,18 +1299,18 @@ mod tests {
12911299

12921300
#[cfg(c_bindings)]
12931301
use super::OfferWithDerivedMetadataBuilder as OfferBuilder;
1294-
let (offer_id, offer) = OfferBuilder
1302+
let offer = OfferBuilder
12951303
::deriving_signing_pubkey(desc, node_id, &expanded_key, &entropy, &secp_ctx)
12961304
.amount_msats(1000)
12971305
.path(blinded_path)
1298-
.build_with_id().unwrap();
1306+
.build().unwrap();
12991307
assert_ne!(offer.signing_pubkey(), node_id);
13001308

13011309
let invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
13021310
.build().unwrap()
13031311
.sign(payer_sign).unwrap();
13041312
match invoice_request.verify(&expanded_key, &secp_ctx) {
1305-
Ok(invoice_request) => assert_eq!(invoice_request.offer_id, offer_id),
1313+
Ok(invoice_request) => assert_eq!(invoice_request.offer_id, offer.id()),
13061314
Err(_) => panic!("unexpected error"),
13071315
}
13081316

lightning/src/offers/signer.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,11 @@ pub(super) fn verify_recipient_metadata<'a, T: secp256k1::Signing>(
271271
metadata: &[u8], expanded_key: &ExpandedKey, iv_bytes: &[u8; IV_LEN],
272272
signing_pubkey: PublicKey, tlv_stream: impl core::iter::Iterator<Item = TlvRecord<'a>>,
273273
secp_ctx: &Secp256k1<T>
274-
) -> Result<(Option<KeyPair>, Nonce), ()> {
274+
) -> Result<Option<KeyPair>, ()> {
275275
let mut hmac = hmac_for_message(metadata, expanded_key, iv_bytes, tlv_stream)?;
276276
hmac.input(WITHOUT_ENCRYPTED_PAYMENT_ID_HMAC_INPUT);
277277

278-
let keys = verify_metadata(metadata, Hmac::from_engine(hmac), signing_pubkey, secp_ctx)?;
279-
let nonce = Nonce::try_from(&metadata[..Nonce::LENGTH]).unwrap();
280-
Ok((keys, nonce))
278+
verify_metadata(metadata, Hmac::from_engine(hmac), signing_pubkey, secp_ctx)
281279
}
282280

283281
fn verify_metadata<T: secp256k1::Signing>(

0 commit comments

Comments
 (0)