8811926782348a263735b55824ea74fb65d662cb
[rust-lightning] / lightning-invoice / src / ser.rs
1 use std::fmt;
2 use std::fmt::{Display, Formatter};
3 use bech32::{ToBase32, u5, WriteBase32, Base32Len};
4
5 use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
6         RouteHint, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart};
7
8 /// Converts a stream of bytes written to it to base32. On finalization the according padding will
9 /// be applied. That means the results of writing two data blocks with one or two `BytesToBase32`
10 /// converters will differ.
11 struct BytesToBase32<'a, W: WriteBase32 + 'a> {
12         /// Target for writing the resulting `u5`s resulting from the written bytes
13         writer: &'a mut W,
14         /// Holds all unwritten bits left over from last round. The bits are stored beginning from
15         /// the most significant bit. E.g. if buffer_bits=3, then the byte with bits a, b and c will
16         /// look as follows: [a, b, c, 0, 0, 0, 0, 0]
17         buffer: u8,
18         /// Amount of bits left over from last round, stored in buffer.
19         buffer_bits: u8,
20 }
21
22 impl<'a, W: WriteBase32> BytesToBase32<'a, W> {
23         /// Create a new bytes-to-base32 converter with `writer` as  a sink for the resulting base32
24         /// data.
25         pub fn new(writer: &'a mut W) -> BytesToBase32<'a, W> {
26                 BytesToBase32 {
27                         writer,
28                         buffer: 0,
29                         buffer_bits: 0,
30                 }
31         }
32
33         /// Add more bytes to the current conversion unit
34         pub fn append(&mut self, bytes: &[u8]) -> Result<(), W::Err> {
35                 for b in bytes {
36                         self.append_u8(*b)?;
37                 }
38                 Ok(())
39         }
40
41         pub fn append_u8(&mut self, byte: u8) -> Result<(), W::Err> {
42                 // Write first u5 if we have to write two u5s this round. That only happens if the
43                 // buffer holds too many bits, so we don't have to combine buffer bits with new bits
44                 // from this rounds byte.
45                 if self.buffer_bits >= 5 {
46                         self.writer.write_u5(
47                                 u5::try_from_u8((self.buffer & 0b11111000) >> 3 ).expect("<32")
48                         )?;
49                         self.buffer = self.buffer << 5;
50                         self.buffer_bits -= 5;
51                 }
52
53                 // Combine all bits from buffer with enough bits from this rounds byte so that they fill
54                 // a u5. Save reamining bits from byte to buffer.
55                 let from_buffer = self.buffer >> 3;
56                 let from_byte = byte >> (3 + self.buffer_bits); // buffer_bits <= 4
57
58                 self.writer.write_u5(u5::try_from_u8(from_buffer | from_byte).expect("<32"))?;
59                 self.buffer = byte << (5 - self.buffer_bits);
60                 self.buffer_bits = 3 + self.buffer_bits;
61
62                 Ok(())
63         }
64
65         pub fn finalize(mut self) ->  Result<(), W::Err> {
66                 self.inner_finalize()?;
67                 std::mem::forget(self);
68                 Ok(())
69         }
70
71         fn inner_finalize(&mut self) -> Result<(), W::Err>{
72                 // There can be at most two u5s left in the buffer after processing all bytes, write them.
73                 if self.buffer_bits >= 5 {
74                         self.writer.write_u5(
75                                 u5::try_from_u8((self.buffer & 0b11111000) >> 3).expect("<32")
76                         )?;
77                         self.buffer = self.buffer << 5;
78                         self.buffer_bits -= 5;
79                 }
80
81                 if self.buffer_bits != 0 {
82                         self.writer.write_u5(u5::try_from_u8(self.buffer >> 3).expect("<32"))?;
83                 }
84
85                 Ok(())
86         }
87 }
88
89 impl<'a, W: WriteBase32> Drop for BytesToBase32<'a, W> {
90         fn drop(&mut self) {
91                 self.inner_finalize()
92                         .expect("Unhandled error when finalizing conversion on drop. User finalize to handle.")
93         }
94 }
95
96 /// Calculates the base32 encoded size of a byte slice
97 fn bytes_size_to_base32_size(byte_size: usize) -> usize {
98         let bits = byte_size * 8;
99         if bits % 5 == 0 {
100                 // without padding bits
101                 bits / 5
102         } else {
103                 // with padding bits
104                 bits / 5 + 1
105         }
106 }
107
108 impl Display for Invoice {
109         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
110                 self.signed_invoice.fmt(f)
111         }
112 }
113
114 impl Display for SignedRawInvoice {
115         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
116                 let hrp = self.raw_invoice.hrp.to_string();
117                 let mut data  = self.raw_invoice.data.to_base32();
118                 data.extend_from_slice(&self.signature.to_base32());
119
120                 bech32::encode_to_fmt(f, &hrp, data).expect("HRP is valid")?;
121
122                 Ok(())
123         }
124 }
125
126 /// (C-not exported)
127 impl Display for RawHrp {
128         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
129                 let amount = match self.raw_amount {
130                         Some(ref amt) => amt.to_string(),
131                         None => String::new(),
132                 };
133
134                 let si_prefix = match self.si_prefix {
135                         Some(ref si) => si.to_string(),
136                         None => String::new(),
137                 };
138
139                 write!(
140                         f,
141                         "ln{}{}{}",
142                         self.currency,
143                         amount,
144                         si_prefix
145                 )
146         }
147 }
148
149 impl Display for Currency {
150         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
151                 let currency_code = match *self {
152                         Currency::Bitcoin => "bc",
153                         Currency::BitcoinTestnet => "tb",
154                         Currency::Regtest => "bcrt",
155                         Currency::Simnet => "sb",
156                 };
157                 write!(f, "{}", currency_code)
158         }
159 }
160
161 impl Display for SiPrefix {
162         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
163                 write!(f, "{}",
164                         match *self {
165                                 SiPrefix::Milli => "m",
166                                 SiPrefix::Micro => "u",
167                                 SiPrefix::Nano => "n",
168                                 SiPrefix::Pico => "p",
169                         }
170                 )
171         }
172 }
173
174 fn encode_int_be_base32(int: u64) -> Vec<u5> {
175         let base = 32u64;
176
177         let mut out_vec = Vec::<u5>::new();
178
179         let mut rem_int = int;
180         while rem_int != 0 {
181                 out_vec.push(u5::try_from_u8((rem_int % base) as u8).expect("always <32"));
182                 rem_int /= base;
183         }
184
185         out_vec.reverse();
186         out_vec
187 }
188
189 fn encoded_int_be_base32_size(int: u64) -> usize {
190         for pos in (0..13).rev() {
191                 if int & (0x1f << (5 * pos)) != 0 {
192                         return (pos + 1) as usize;
193                 }
194         }
195         0usize
196 }
197
198 fn encode_int_be_base256<T: Into<u64>>(int: T) -> Vec<u8> {
199         let base = 256u64;
200
201         let mut out_vec = Vec::<u8>::new();
202
203         let mut rem_int: u64 = int.into();
204         while rem_int != 0 {
205                 out_vec.push((rem_int % base) as u8);
206                 rem_int /= base;
207         }
208
209         out_vec.reverse();
210         out_vec
211 }
212
213 /// Appends the default value of `T` to the front of the `in_vec` till it reaches the length
214 /// `target_length`. If `in_vec` already is too lang `None` is returned.
215 fn try_stretch<T>(mut in_vec: Vec<T>, target_len: usize) -> Option<Vec<T>>
216         where T: Default + Copy
217 {
218         if in_vec.len() > target_len {
219                 None
220         } else if in_vec.len() == target_len {
221                 Some(in_vec)
222         } else {
223                 let mut out_vec = Vec::<T>::with_capacity(target_len);
224                 out_vec.append(&mut vec![T::default(); target_len - in_vec.len()]);
225                 out_vec.append(&mut in_vec);
226                 Some(out_vec)
227         }
228 }
229
230 impl ToBase32 for RawDataPart {
231         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
232                 // encode timestamp
233                 self.timestamp.write_base32(writer)?;
234
235                 // encode tagged fields
236                 for tagged_field in self.tagged_fields.iter() {
237                         tagged_field.write_base32(writer)?;
238                 }
239
240                 Ok(())
241         }
242 }
243
244 impl ToBase32 for PositiveTimestamp {
245         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
246                 // FIXME: use writer for int encoding
247                 writer.write(
248                         &try_stretch(encode_int_be_base32(self.as_unix_timestamp()), 7)
249                                 .expect("Can't be longer due than 7 u5s due to timestamp bounds")
250                 )
251         }
252 }
253
254 impl ToBase32 for RawTaggedField {
255         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
256                 match *self {
257                         RawTaggedField::UnknownSemantics(ref content) => {
258                                 writer.write(content)
259                         },
260                         RawTaggedField::KnownSemantics(ref tagged_field) => {
261                                 tagged_field.write_base32(writer)
262                         }
263                 }
264         }
265 }
266
267 impl ToBase32 for Sha256 {
268         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
269                 (&self.0[..]).write_base32(writer)
270         }
271 }
272 impl Base32Len for Sha256 {
273         fn base32_len(&self) -> usize {
274                 (&self.0[..]).base32_len()
275         }
276 }
277
278 impl ToBase32 for Description {
279         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
280                 self.as_bytes().write_base32(writer)
281         }
282 }
283
284 impl Base32Len for Description {
285         fn base32_len(&self) -> usize {
286                 self.0.as_bytes().base32_len()
287         }
288 }
289
290 impl ToBase32 for PayeePubKey {
291         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
292                 (&self.serialize()[..]).write_base32(writer)
293         }
294 }
295
296 impl Base32Len for PayeePubKey {
297         fn base32_len(&self) -> usize {
298                 bytes_size_to_base32_size(secp256k1::constants::PUBLIC_KEY_SIZE)
299         }
300 }
301
302 impl ToBase32 for ExpiryTime {
303         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
304                 writer.write(&encode_int_be_base32(self.as_seconds()))
305         }
306 }
307
308 impl Base32Len for ExpiryTime {
309         fn base32_len(&self) -> usize {
310                 encoded_int_be_base32_size(self.0.as_secs())
311         }
312 }
313
314 impl ToBase32 for MinFinalCltvExpiry {
315         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
316                 writer.write(&encode_int_be_base32(self.0))
317         }
318 }
319
320 impl Base32Len for MinFinalCltvExpiry {
321         fn base32_len(&self) -> usize {
322                 encoded_int_be_base32_size(self.0)
323         }
324 }
325
326 impl ToBase32 for Fallback {
327         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
328                 match *self {
329                         Fallback::SegWitProgram {version: v, program: ref p} => {
330                                 writer.write_u5(v)?;
331                                 p.write_base32(writer)
332                         },
333                         Fallback::PubKeyHash(ref hash) => {
334                                 writer.write_u5(u5::try_from_u8(17).expect("17 < 32"))?;
335                                 (&hash[..]).write_base32(writer)
336                         },
337                         Fallback::ScriptHash(ref hash) => {
338                                 writer.write_u5(u5::try_from_u8(18).expect("18 < 32"))?;
339                                 (&hash[..]).write_base32(writer)
340                         }
341                 }
342         }
343 }
344
345 impl Base32Len for Fallback {
346         fn base32_len(&self) -> usize {
347                 match *self {
348                         Fallback::SegWitProgram {program: ref p, ..} => {
349                                 bytes_size_to_base32_size(p.len()) + 1
350                         },
351                         Fallback::PubKeyHash(_) | Fallback::ScriptHash(_) => {
352                                 33
353                         },
354                 }
355         }
356 }
357
358 impl ToBase32 for RouteHint {
359         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
360                 let mut converter = BytesToBase32::new(writer);
361
362                 for hop in self.iter() {
363                         converter.append(&hop.src_node_id.serialize()[..])?;
364                         let short_channel_id = try_stretch(
365                                 encode_int_be_base256(hop.short_channel_id),
366                                 8
367                         ).expect("sizeof(u64) == 8");
368                         converter.append(&short_channel_id)?;
369
370                         let fee_base_msat = try_stretch(
371                                 encode_int_be_base256(hop.fees.base_msat),
372                                 4
373                         ).expect("sizeof(u32) == 4");
374                         converter.append(&fee_base_msat)?;
375
376                         let fee_proportional_millionths = try_stretch(
377                                 encode_int_be_base256(hop.fees.proportional_millionths),
378                                 4
379                         ).expect("sizeof(u32) == 4");
380                         converter.append(&fee_proportional_millionths)?;
381
382                         let cltv_expiry_delta = try_stretch(
383                                 encode_int_be_base256(hop.cltv_expiry_delta),
384                                 2
385                         ).expect("sizeof(u16) == 2");
386                         converter.append(&cltv_expiry_delta)?;
387                 }
388
389                 converter.finalize()?;
390                 Ok(())
391         }
392 }
393
394 impl Base32Len for RouteHint {
395         fn base32_len(&self) -> usize {
396                 bytes_size_to_base32_size(self.0.len() * 51)
397         }
398 }
399
400 impl ToBase32 for TaggedField {
401         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
402                 /// Writes a tagged field: tag, length and data. `tag` should be in `0..32` otherwise the
403                 /// function will panic.
404                 fn write_tagged_field<W, P>(writer: &mut W, tag: u8, payload: &P) -> Result<(), W::Err>
405                         where W: WriteBase32,
406                                   P: ToBase32 + Base32Len,
407                 {
408                         let len = payload.base32_len();
409                         assert!(len < 1024, "Every tagged field data can be at most 1023 bytes long.");
410
411                         writer.write_u5(u5::try_from_u8(tag).expect("invalid tag, not in 0..32"))?;
412                         writer.write(&try_stretch(
413                                 encode_int_be_base32(len as u64),
414                                 2
415                         ).expect("Can't be longer than 2, see assert above."))?;
416                         payload.write_base32(writer)
417                 }
418
419                 match *self {
420                         TaggedField::PaymentHash(ref hash) => {
421                                 write_tagged_field(writer, constants::TAG_PAYMENT_HASH, hash)
422                         },
423                         TaggedField::Description(ref description) => {
424                                 write_tagged_field(writer, constants::TAG_DESCRIPTION, description)
425                         },
426                         TaggedField::PayeePubKey(ref pub_key) => {
427                                 write_tagged_field(writer, constants::TAG_PAYEE_PUB_KEY, pub_key)
428                         },
429                         TaggedField::DescriptionHash(ref hash) => {
430                                 write_tagged_field(writer, constants::TAG_DESCRIPTION_HASH, hash)
431                         },
432                         TaggedField::ExpiryTime(ref duration) => {
433                                 write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
434                         },
435                         TaggedField::MinFinalCltvExpiry(ref expiry) => {
436                                 write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY, expiry)
437                         },
438                         TaggedField::Fallback(ref fallback_address) => {
439                                 write_tagged_field(writer, constants::TAG_FALLBACK, fallback_address)
440                         },
441                         TaggedField::Route(ref route_hops) => {
442                                 write_tagged_field(writer, constants::TAG_ROUTE, route_hops)
443                         },
444                         TaggedField::PaymentSecret(ref payment_secret) => {
445                                   write_tagged_field(writer, constants::TAG_PAYMENT_SECRET, payment_secret)
446                         },
447                         TaggedField::Features(ref features) => {
448                                 write_tagged_field(writer, constants::TAG_FEATURES, features)
449                         },
450                 }
451         }
452 }
453
454 impl ToBase32 for InvoiceSignature {
455         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
456                 let mut converter = BytesToBase32::new(writer);
457                 let (recovery_id, signature) = self.0.serialize_compact();
458                 converter.append(&signature[..])?;
459                 converter.append_u8(recovery_id.to_i32() as u8)?;
460                 converter.finalize()
461         }
462 }
463
464 #[cfg(test)]
465 mod test {
466         use bech32::CheckBase32;
467
468         #[test]
469         fn test_currency_code() {
470                 use Currency;
471
472                 assert_eq!("bc", Currency::Bitcoin.to_string());
473                 assert_eq!("tb", Currency::BitcoinTestnet.to_string());
474                 assert_eq!("bcrt", Currency::Regtest.to_string());
475                 assert_eq!("sb", Currency::Simnet.to_string());
476         }
477
478         #[test]
479         fn test_raw_hrp() {
480                 use ::{Currency, RawHrp, SiPrefix};
481
482                 let hrp = RawHrp {
483                         currency: Currency::Bitcoin,
484                         raw_amount: Some(100),
485                         si_prefix: Some(SiPrefix::Micro),
486                 };
487
488                 assert_eq!(hrp.to_string(), "lnbc100u");
489         }
490
491         #[test]
492         fn test_encode_int_be_base32() {
493                 use ser::encode_int_be_base32;
494
495                 let input: u64 = 33764;
496                 let expected_out = CheckBase32::check_base32(&[1, 0, 31, 4]).unwrap();
497
498                 assert_eq!(expected_out, encode_int_be_base32(input));
499         }
500
501         #[test]
502         fn test_encode_int_be_base256() {
503                 use ser::encode_int_be_base256;
504
505                 let input: u64 = 16842530;
506                 let expected_out = vec![1, 0, 255, 34];
507
508                 assert_eq!(expected_out, encode_int_be_base256(input));
509         }
510 }