1 // This file is Copyright its original authors, visible in version control
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
10 use crate::utils::test_logger;
11 use bech32::{u5, FromBase32, ToBase32};
12 use bitcoin::secp256k1::{Secp256k1, SecretKey};
13 use lightning_invoice::{
14 Bolt11Invoice, RawBolt11Invoice, RawDataPart, RawHrp, RawTaggedField, TaggedField,
16 use std::str::FromStr;
19 pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
20 // Read a fake HRP length byte
21 let hrp_len = std::cmp::min(*data.get(0).unwrap_or(&0) as usize, data.len());
22 if let Ok(s) = std::str::from_utf8(&data[..hrp_len]) {
23 let hrp = match RawHrp::from_str(s) {
28 data.iter().skip(hrp_len).map(|x| u5::try_from_u8(x % 32).unwrap()).collect::<Vec<_>>();
29 let invoice_data = match RawDataPart::from_base32(&bech32) {
30 Ok(invoice) => invoice,
34 // Our data encoding is not worse than the input
35 assert!(invoice_data.to_base32().len() <= bech32.len());
37 // Our data serialization is loss-less
39 RawDataPart::from_base32(&invoice_data.to_base32())
40 .expect("faild parsing out own encoding"),
44 if invoice_data.tagged_fields.iter().any(|field| {
45 matches!(field, RawTaggedField::KnownSemantics(TaggedField::PayeePubKey(_)))
47 // We could forge a signature using the fact that signing is insecure in fuzz mode, but
48 // easier to just skip and rely on the fact that no-PayeePubKey invoices do pubkey
53 let raw_invoice = RawBolt11Invoice { hrp, data: invoice_data };
54 let signed_raw_invoice = match raw_invoice.sign(|hash| {
55 let private_key = SecretKey::from_slice(&[42; 32]).unwrap();
56 Ok::<_, ()>(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))
62 if let Ok(invoice) = Bolt11Invoice::from_signed(signed_raw_invoice) {
63 invoice.amount_milli_satoshis();
68 pub fn bolt11_deser_test<Out: test_logger::Output>(data: &[u8], out: Out) {
73 pub extern "C" fn bolt11_deser_run(data: *const u8, datalen: usize) {
74 do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});