1use crate::io;
13use crate::util::ser::{BigSize, Readable, Writeable, Writer};
14use bitcoin::hashes::{sha256, Hash, HashEngine};
15use bitcoin::secp256k1::schnorr::Signature;
16use bitcoin::secp256k1::{self, Message, PublicKey, Secp256k1};
17
18#[allow(unused_imports)]
19use crate::prelude::*;
20
21pub(super) const SIGNATURE_TYPES: core::ops::RangeInclusive<u64> = 240..=1000;
23
24tlv_stream!(SignatureTlvStream, SignatureTlvStreamRef<'a>, SIGNATURE_TYPES, {
25 (240, signature: Signature),
26});
27
28#[derive(Clone, Debug, PartialEq)]
34pub struct TaggedHash {
35 tag: &'static str,
36 merkle_root: sha256::Hash,
37 digest: Message,
38}
39
40impl TaggedHash {
41 pub(super) fn from_valid_tlv_stream_bytes(tag: &'static str, bytes: &[u8]) -> Self {
45 let tlv_stream = TlvStream::new(bytes);
46 Self::from_tlv_stream(tag, tlv_stream)
47 }
48
49 pub(super) fn from_tlv_stream<'a, I: core::iter::Iterator<Item = TlvRecord<'a>>>(
53 tag: &'static str, tlv_stream: I,
54 ) -> Self {
55 let tag_hash = sha256::Hash::hash(tag.as_bytes());
56 let merkle_root = root_hash(tlv_stream);
57 let digest = Message::from_digest(tagged_hash(tag_hash, merkle_root).to_byte_array());
58 Self { tag, merkle_root, digest }
59 }
60
61 pub fn as_digest(&self) -> &Message {
63 &self.digest
64 }
65
66 pub fn tag(&self) -> &str {
68 &self.tag
69 }
70
71 pub fn merkle_root(&self) -> sha256::Hash {
73 self.merkle_root
74 }
75
76 pub(super) fn to_bytes(&self) -> [u8; 32] {
77 *self.digest.as_ref()
78 }
79}
80
81impl AsRef<TaggedHash> for TaggedHash {
82 fn as_ref(&self) -> &TaggedHash {
83 self
84 }
85}
86
87#[derive(Debug, PartialEq)]
89pub enum SignError {
90 Signing,
92 Verification(secp256k1::Error),
94}
95
96pub trait SignFn<T: AsRef<TaggedHash>> {
101 fn sign(&self, message: &T) -> Result<Signature, ()>;
103}
104
105impl<F> SignFn<TaggedHash> for F
106where
107 F: Fn(&TaggedHash) -> Result<Signature, ()>,
108{
109 fn sign(&self, message: &TaggedHash) -> Result<Signature, ()> {
110 self(message)
111 }
112}
113
114pub fn sign_message<F, T>(f: F, message: &T, pubkey: PublicKey) -> Result<Signature, SignError>
124where
125 F: SignFn<T>,
126 T: AsRef<TaggedHash>,
127{
128 let signature = f.sign(message).map_err(|()| SignError::Signing)?;
129
130 let digest = message.as_ref().as_digest();
131 let pubkey = pubkey.into();
132 let secp_ctx = Secp256k1::verification_only();
133 secp_ctx.verify_schnorr(&signature, digest, &pubkey).map_err(|e| SignError::Verification(e))?;
134
135 Ok(signature)
136}
137
138pub fn verify_signature(
141 signature: &Signature, message: &TaggedHash, pubkey: PublicKey,
142) -> Result<(), secp256k1::Error> {
143 let digest = message.as_digest();
144 let pubkey = pubkey.into();
145 let secp_ctx = Secp256k1::verification_only();
146 secp_ctx.verify_schnorr(signature, digest, &pubkey)
147}
148
149fn root_hash<'a, I: core::iter::Iterator<Item = TlvRecord<'a>>>(tlv_stream: I) -> sha256::Hash {
152 let mut tlv_stream = tlv_stream.peekable();
153 let nonce_tag = tagged_hash_engine(sha256::Hash::from_engine({
154 let first_tlv_record = tlv_stream.peek().unwrap();
155 let mut engine = sha256::Hash::engine();
156 engine.input("LnNonce".as_bytes());
157 engine.input(first_tlv_record.record_bytes);
158 engine
159 }));
160 let leaf_tag = tagged_hash_engine(sha256::Hash::hash("LnLeaf".as_bytes()));
161 let branch_tag = tagged_hash_engine(sha256::Hash::hash("LnBranch".as_bytes()));
162
163 let mut leaves = Vec::new();
164 for record in tlv_stream.filter(|record| !SIGNATURE_TYPES.contains(&record.r#type)) {
165 leaves.push(tagged_hash_from_engine(leaf_tag.clone(), &record.record_bytes));
166 leaves.push(tagged_hash_from_engine(nonce_tag.clone(), &record.type_bytes));
167 }
168
169 let num_leaves = leaves.len();
171 for level in 0.. {
172 let step = 2 << level;
173 let offset = step / 2;
174 if offset >= num_leaves {
175 break;
176 }
177
178 let left_branches = (0..num_leaves).step_by(step);
179 let right_branches = (offset..num_leaves).step_by(step);
180 for (i, j) in left_branches.zip(right_branches) {
181 leaves[i] = tagged_branch_hash_from_engine(branch_tag.clone(), leaves[i], leaves[j]);
182 }
183 }
184
185 *leaves.first().unwrap()
186}
187
188fn tagged_hash<T: AsRef<[u8]>>(tag: sha256::Hash, msg: T) -> sha256::Hash {
189 let engine = tagged_hash_engine(tag);
190 tagged_hash_from_engine(engine, msg)
191}
192
193fn tagged_hash_engine(tag: sha256::Hash) -> sha256::HashEngine {
194 let mut engine = sha256::Hash::engine();
195 engine.input(tag.as_ref());
196 engine.input(tag.as_ref());
197 engine
198}
199
200fn tagged_hash_from_engine<T: AsRef<[u8]>>(mut engine: sha256::HashEngine, msg: T) -> sha256::Hash {
201 engine.input(msg.as_ref());
202 sha256::Hash::from_engine(engine)
203}
204
205fn tagged_branch_hash_from_engine(
206 mut engine: sha256::HashEngine, leaf1: sha256::Hash, leaf2: sha256::Hash,
207) -> sha256::Hash {
208 if leaf1 < leaf2 {
209 engine.input(leaf1.as_ref());
210 engine.input(leaf2.as_ref());
211 } else {
212 engine.input(leaf2.as_ref());
213 engine.input(leaf1.as_ref());
214 };
215 sha256::Hash::from_engine(engine)
216}
217
218#[derive(Clone)]
221pub(super) struct TlvStream<'a> {
222 data: io::Cursor<&'a [u8]>,
223}
224
225impl<'a> TlvStream<'a> {
226 pub fn new(data: &'a [u8]) -> Self {
227 Self { data: io::Cursor::new(data) }
228 }
229
230 pub fn range<T>(self, types: T) -> impl core::iter::Iterator<Item = TlvRecord<'a>>
231 where
232 T: core::ops::RangeBounds<u64> + Clone,
233 {
234 let take_range = types.clone();
235 self.skip_while(move |record| !types.contains(&record.r#type))
236 .take_while(move |record| take_range.contains(&record.r#type))
237 }
238}
239
240pub(super) struct TlvRecord<'a> {
242 pub(super) r#type: u64,
243 type_bytes: &'a [u8],
244 pub(super) record_bytes: &'a [u8],
246 pub(super) end: usize,
247}
248
249impl<'a> Iterator for TlvStream<'a> {
250 type Item = TlvRecord<'a>;
251
252 fn next(&mut self) -> Option<Self::Item> {
253 if self.data.position() < self.data.get_ref().len() as u64 {
254 let start = self.data.position();
255
256 let r#type = <BigSize as Readable>::read(&mut self.data).unwrap().0;
257 let offset = self.data.position();
258 let type_bytes = &self.data.get_ref()[start as usize..offset as usize];
259
260 let length = <BigSize as Readable>::read(&mut self.data).unwrap().0;
261 let offset = self.data.position();
262 let end = offset + length;
263
264 let _value = &self.data.get_ref()[offset as usize..end as usize];
265 let record_bytes = &self.data.get_ref()[start as usize..end as usize];
266
267 self.data.set_position(end);
268
269 Some(TlvRecord { r#type, type_bytes, record_bytes, end: end as usize })
270 } else {
271 None
272 }
273 }
274}
275
276impl<'a> Writeable for TlvRecord<'a> {
277 #[inline]
278 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
279 writer.write_all(self.record_bytes)
280 }
281}
282
283#[cfg(test)]
284mod tests {
285 use super::{TlvStream, SIGNATURE_TYPES};
286
287 use crate::ln::channelmanager::PaymentId;
288 use crate::ln::inbound_payment::ExpandedKey;
289 use crate::offers::invoice_request::{InvoiceRequest, UnsignedInvoiceRequest};
290 use crate::offers::nonce::Nonce;
291 use crate::offers::offer::{Amount, CurrencyCode, OfferBuilder};
292 use crate::offers::parse::Bech32Encode;
293 use crate::offers::signer::Metadata;
294 use crate::offers::test_utils::recipient_pubkey;
295 use crate::util::ser::Writeable;
296 use bitcoin::hashes::{sha256, Hash};
297 use bitcoin::hex::FromHex;
298 use bitcoin::secp256k1::schnorr::Signature;
299 use bitcoin::secp256k1::{Keypair, Message, Secp256k1, SecretKey};
300
301 #[test]
302 fn calculates_merkle_root_hash() {
303 const HEX_1: &'static str = "010203e8";
305 let bytes_1 =
306 <Vec<u8>>::from_hex("b013756c8fee86503a0b4abdab4cddeb1af5d344ca6fc2fa8b6c08938caa6f93")
307 .unwrap();
308 assert_eq!(
309 super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(HEX_1).unwrap())),
310 sha256::Hash::from_slice(&bytes_1).unwrap(),
311 );
312
313 const HEX_2: &'static str = concat!("010203e8", "02080000010000020003");
314 let bytes_2 =
315 <Vec<u8>>::from_hex("c3774abbf4815aa54ccaa026bff6581f01f3be5fe814c620a252534f434bc0d1")
316 .unwrap();
317 assert_eq!(
318 super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(HEX_2).unwrap())),
319 sha256::Hash::from_slice(&bytes_2).unwrap(),
320 );
321
322 const HEX_3: &'static str = concat!("010203e8","02080000010000020003", "03310266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c0351800000000000000010000000000000002");
323 let bytes_3 =
324 <Vec<u8>>::from_hex("ab2e79b1283b0b31e0b035258de23782df6b89a38cfa7237bde69aed1a658c5d")
325 .unwrap();
326 assert_eq!(
327 super::root_hash(TlvStream::new(&<Vec<u8>>::from_hex(HEX_3).unwrap())),
328 sha256::Hash::from_slice(&bytes_3).unwrap(),
329 );
330 }
331
332 #[test]
333 fn calculates_merkle_root_hash_from_invoice_request() {
334 let expanded_key = ExpandedKey::new([42; 32]);
335 let nonce = Nonce([0u8; 16]);
336 let secp_ctx = Secp256k1::new();
337 let payment_id = PaymentId([1; 32]);
338
339 let recipient_pubkey = {
340 let secret_bytes = <Vec<u8>>::from_hex(
341 "4141414141414141414141414141414141414141414141414141414141414141",
342 )
343 .unwrap();
344 let secret_key = SecretKey::from_slice(&secret_bytes).unwrap();
345 Keypair::from_secret_key(&secp_ctx, &secret_key).public_key()
346 };
347 let payer_keys = {
348 let secret_bytes = <Vec<u8>>::from_hex(
349 "4242424242424242424242424242424242424242424242424242424242424242",
350 )
351 .unwrap();
352 let secret_key = SecretKey::from_slice(&secret_bytes).unwrap();
353 Keypair::from_secret_key(&secp_ctx, &secret_key)
354 };
355
356 let invoice_request = OfferBuilder::new(recipient_pubkey)
358 .description("A Mathematical Treatise".into())
359 .amount(Amount::Currency {
360 iso4217_code: CurrencyCode::new(*b"USD").unwrap(),
361 amount: 100,
362 })
363 .build_unchecked()
364 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
366 .unwrap()
367 .payer_metadata(Metadata::Bytes(vec![0; 8]))
368 .payer_signing_pubkey(payer_keys.public_key())
369 .build_unchecked()
370 .sign(|message: &UnsignedInvoiceRequest| {
371 Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &payer_keys))
372 })
373 .unwrap();
374 assert_eq!(
375 invoice_request.to_string(),
376 "lnr1qqyqqqqqqqqqqqqqqcp4256ypqqkgzshgysy6ct5dpjk6ct5d93kzmpq23ex2ct5d9ek293pqthvwfzadd7jejes8q9lhc4rvjxd022zv5l44g6qah82ru5rdpnpjkppqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43euzqhrurageg3n7kafgsek6gz3e9w52parv8gs2hlxzk95tzeswywffxlkeyhml0hh46kndmwf4m6xma3tkq2lu04qz3slje2rfthc89vss",
377 );
378
379 let bytes =
380 <Vec<u8>>::from_hex("608407c18ad9a94d9ea2bcdbe170b6c20c462a7833a197621c916f78cf18e624")
381 .unwrap();
382 assert_eq!(
383 super::root_hash(TlvStream::new(&invoice_request.bytes[..])),
384 sha256::Hash::from_slice(&bytes).unwrap(),
385 );
386
387 let bytes = <Vec<u8>>::from_hex("b8f83ea3288cfd6ea510cdb481472575141e8d8744157f98562d162cc1c472526fdb24befefbdebab4dbb726bbd1b7d8aec057f8fa805187e5950d2bbe0e5642").unwrap();
388 assert_eq!(invoice_request.signature(), Signature::from_slice(&bytes).unwrap(),);
389 }
390
391 #[test]
392 fn compute_tagged_hash() {
393 let expanded_key = ExpandedKey::new([42; 32]);
394 let nonce = Nonce([0u8; 16]);
395 let secp_ctx = Secp256k1::new();
396 let payment_id = PaymentId([1; 32]);
397
398 let unsigned_invoice_request = OfferBuilder::new(recipient_pubkey())
399 .amount_msats(1000)
400 .build()
401 .unwrap()
402 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
403 .unwrap()
404 .payer_note("bar".into())
405 .build_unchecked();
406
407 let tagged_hash = unsigned_invoice_request.as_ref();
410 let expected_digest = unsigned_invoice_request.as_ref().as_digest();
411 let tag = sha256::Hash::hash(tagged_hash.tag().as_bytes());
412 let actual_digest = Message::from_digest(
413 super::tagged_hash(tag, tagged_hash.merkle_root()).to_byte_array(),
414 );
415 assert_eq!(*expected_digest, actual_digest);
416 }
417
418 #[test]
419 fn skips_encoding_signature_tlv_records() {
420 let expanded_key = ExpandedKey::new([42; 32]);
421 let nonce = Nonce([0u8; 16]);
422 let secp_ctx = Secp256k1::new();
423 let payment_id = PaymentId([1; 32]);
424
425 let recipient_pubkey = {
426 let secret_key = SecretKey::from_slice(&[41; 32]).unwrap();
427 Keypair::from_secret_key(&secp_ctx, &secret_key).public_key()
428 };
429
430 let invoice_request = OfferBuilder::new(recipient_pubkey)
431 .amount_msats(100)
432 .build_unchecked()
433 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
434 .unwrap()
435 .build_and_sign()
436 .unwrap();
437
438 let mut bytes_without_signature = Vec::new();
439 let tlv_stream_without_signatures = TlvStream::new(&invoice_request.bytes)
440 .filter(|record| !SIGNATURE_TYPES.contains(&record.r#type));
441 for record in tlv_stream_without_signatures {
442 record.write(&mut bytes_without_signature).unwrap();
443 }
444
445 assert_ne!(bytes_without_signature, invoice_request.bytes);
446 assert_eq!(
447 TlvStream::new(&bytes_without_signature).count(),
448 TlvStream::new(&invoice_request.bytes).count() - 1,
449 );
450 }
451
452 #[test]
453 fn iterates_over_tlv_stream_range() {
454 let expanded_key = ExpandedKey::new([42; 32]);
455 let nonce = Nonce([0u8; 16]);
456 let secp_ctx = Secp256k1::new();
457 let payment_id = PaymentId([1; 32]);
458
459 let recipient_pubkey = {
460 let secret_key = SecretKey::from_slice(&[41; 32]).unwrap();
461 Keypair::from_secret_key(&secp_ctx, &secret_key).public_key()
462 };
463
464 let invoice_request = OfferBuilder::new(recipient_pubkey)
465 .amount_msats(100)
466 .build_unchecked()
467 .request_invoice(&expanded_key, nonce, &secp_ctx, payment_id)
468 .unwrap()
469 .build_and_sign()
470 .unwrap();
471
472 let tlv_stream = TlvStream::new(&invoice_request.bytes)
473 .range(0..1)
474 .chain(TlvStream::new(&invoice_request.bytes).range(1..80))
475 .chain(TlvStream::new(&invoice_request.bytes).range(80..160))
476 .chain(TlvStream::new(&invoice_request.bytes).range(160..240))
477 .chain(TlvStream::new(&invoice_request.bytes).range(SIGNATURE_TYPES))
478 .map(|r| r.record_bytes.to_vec())
479 .flatten()
480 .collect::<Vec<u8>>();
481
482 assert_eq!(tlv_stream, invoice_request.bytes);
483 }
484
485 impl AsRef<[u8]> for InvoiceRequest {
486 fn as_ref(&self) -> &[u8] {
487 &self.bytes
488 }
489 }
490
491 impl Bech32Encode for InvoiceRequest {
492 const BECH32_HRP: &'static str = "lnr";
493 }
494
495 impl core::fmt::Display for InvoiceRequest {
496 fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
497 self.fmt_bech32_str(f)
498 }
499 }
500}