Bump dependencies to bitcoin 0.27 and bech32 0.8
[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         PrivateRoute, 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, bech32::Variant::Bech32).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                         Currency::Signet => "tbs",
157                 };
158                 write!(f, "{}", currency_code)
159         }
160 }
161
162 impl Display for SiPrefix {
163         fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
164                 write!(f, "{}",
165                         match *self {
166                                 SiPrefix::Milli => "m",
167                                 SiPrefix::Micro => "u",
168                                 SiPrefix::Nano => "n",
169                                 SiPrefix::Pico => "p",
170                         }
171                 )
172         }
173 }
174
175 fn encode_int_be_base32(int: u64) -> Vec<u5> {
176         let base = 32u64;
177
178         let mut out_vec = Vec::<u5>::new();
179
180         let mut rem_int = int;
181         while rem_int != 0 {
182                 out_vec.push(u5::try_from_u8((rem_int % base) as u8).expect("always <32"));
183                 rem_int /= base;
184         }
185
186         out_vec.reverse();
187         out_vec
188 }
189
190 fn encoded_int_be_base32_size(int: u64) -> usize {
191         for pos in (0..13).rev() {
192                 if int & (0x1f << (5 * pos)) != 0 {
193                         return (pos + 1) as usize;
194                 }
195         }
196         0usize
197 }
198
199 fn encode_int_be_base256<T: Into<u64>>(int: T) -> Vec<u8> {
200         let base = 256u64;
201
202         let mut out_vec = Vec::<u8>::new();
203
204         let mut rem_int: u64 = int.into();
205         while rem_int != 0 {
206                 out_vec.push((rem_int % base) as u8);
207                 rem_int /= base;
208         }
209
210         out_vec.reverse();
211         out_vec
212 }
213
214 /// Appends the default value of `T` to the front of the `in_vec` till it reaches the length
215 /// `target_length`. If `in_vec` already is too lang `None` is returned.
216 fn try_stretch<T>(mut in_vec: Vec<T>, target_len: usize) -> Option<Vec<T>>
217         where T: Default + Copy
218 {
219         if in_vec.len() > target_len {
220                 None
221         } else if in_vec.len() == target_len {
222                 Some(in_vec)
223         } else {
224                 let mut out_vec = Vec::<T>::with_capacity(target_len);
225                 out_vec.append(&mut vec![T::default(); target_len - in_vec.len()]);
226                 out_vec.append(&mut in_vec);
227                 Some(out_vec)
228         }
229 }
230
231 impl ToBase32 for RawDataPart {
232         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
233                 // encode timestamp
234                 self.timestamp.write_base32(writer)?;
235
236                 // encode tagged fields
237                 for tagged_field in self.tagged_fields.iter() {
238                         tagged_field.write_base32(writer)?;
239                 }
240
241                 Ok(())
242         }
243 }
244
245 impl ToBase32 for PositiveTimestamp {
246         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
247                 // FIXME: use writer for int encoding
248                 writer.write(
249                         &try_stretch(encode_int_be_base32(self.as_unix_timestamp()), 7)
250                                 .expect("Can't be longer due than 7 u5s due to timestamp bounds")
251                 )
252         }
253 }
254
255 impl ToBase32 for RawTaggedField {
256         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
257                 match *self {
258                         RawTaggedField::UnknownSemantics(ref content) => {
259                                 writer.write(content)
260                         },
261                         RawTaggedField::KnownSemantics(ref tagged_field) => {
262                                 tagged_field.write_base32(writer)
263                         }
264                 }
265         }
266 }
267
268 impl ToBase32 for Sha256 {
269         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
270                 (&self.0[..]).write_base32(writer)
271         }
272 }
273 impl Base32Len for Sha256 {
274         fn base32_len(&self) -> usize {
275                 (&self.0[..]).base32_len()
276         }
277 }
278
279 impl ToBase32 for Description {
280         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
281                 self.as_bytes().write_base32(writer)
282         }
283 }
284
285 impl Base32Len for Description {
286         fn base32_len(&self) -> usize {
287                 self.0.as_bytes().base32_len()
288         }
289 }
290
291 impl ToBase32 for PayeePubKey {
292         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
293                 (&self.serialize()[..]).write_base32(writer)
294         }
295 }
296
297 impl Base32Len for PayeePubKey {
298         fn base32_len(&self) -> usize {
299                 bytes_size_to_base32_size(secp256k1::constants::PUBLIC_KEY_SIZE)
300         }
301 }
302
303 impl ToBase32 for ExpiryTime {
304         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
305                 writer.write(&encode_int_be_base32(self.as_seconds()))
306         }
307 }
308
309 impl Base32Len for ExpiryTime {
310         fn base32_len(&self) -> usize {
311                 encoded_int_be_base32_size(self.0.as_secs())
312         }
313 }
314
315 impl ToBase32 for MinFinalCltvExpiry {
316         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
317                 writer.write(&encode_int_be_base32(self.0))
318         }
319 }
320
321 impl Base32Len for MinFinalCltvExpiry {
322         fn base32_len(&self) -> usize {
323                 encoded_int_be_base32_size(self.0)
324         }
325 }
326
327 impl ToBase32 for Fallback {
328         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
329                 match *self {
330                         Fallback::SegWitProgram {version: v, program: ref p} => {
331                                 writer.write_u5(v)?;
332                                 p.write_base32(writer)
333                         },
334                         Fallback::PubKeyHash(ref hash) => {
335                                 writer.write_u5(u5::try_from_u8(17).expect("17 < 32"))?;
336                                 (&hash[..]).write_base32(writer)
337                         },
338                         Fallback::ScriptHash(ref hash) => {
339                                 writer.write_u5(u5::try_from_u8(18).expect("18 < 32"))?;
340                                 (&hash[..]).write_base32(writer)
341                         }
342                 }
343         }
344 }
345
346 impl Base32Len for Fallback {
347         fn base32_len(&self) -> usize {
348                 match *self {
349                         Fallback::SegWitProgram {program: ref p, ..} => {
350                                 bytes_size_to_base32_size(p.len()) + 1
351                         },
352                         Fallback::PubKeyHash(_) | Fallback::ScriptHash(_) => {
353                                 33
354                         },
355                 }
356         }
357 }
358
359 impl ToBase32 for PrivateRoute {
360         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
361                 let mut converter = BytesToBase32::new(writer);
362
363                 for hop in (self.0).0.iter() {
364                         converter.append(&hop.src_node_id.serialize()[..])?;
365                         let short_channel_id = try_stretch(
366                                 encode_int_be_base256(hop.short_channel_id),
367                                 8
368                         ).expect("sizeof(u64) == 8");
369                         converter.append(&short_channel_id)?;
370
371                         let fee_base_msat = try_stretch(
372                                 encode_int_be_base256(hop.fees.base_msat),
373                                 4
374                         ).expect("sizeof(u32) == 4");
375                         converter.append(&fee_base_msat)?;
376
377                         let fee_proportional_millionths = try_stretch(
378                                 encode_int_be_base256(hop.fees.proportional_millionths),
379                                 4
380                         ).expect("sizeof(u32) == 4");
381                         converter.append(&fee_proportional_millionths)?;
382
383                         let cltv_expiry_delta = try_stretch(
384                                 encode_int_be_base256(hop.cltv_expiry_delta),
385                                 2
386                         ).expect("sizeof(u16) == 2");
387                         converter.append(&cltv_expiry_delta)?;
388                 }
389
390                 converter.finalize()?;
391                 Ok(())
392         }
393 }
394
395 impl Base32Len for PrivateRoute {
396         fn base32_len(&self) -> usize {
397                 bytes_size_to_base32_size((self.0).0.len() * 51)
398         }
399 }
400
401 impl ToBase32 for TaggedField {
402         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
403                 /// Writes a tagged field: tag, length and data. `tag` should be in `0..32` otherwise the
404                 /// function will panic.
405                 fn write_tagged_field<W, P>(writer: &mut W, tag: u8, payload: &P) -> Result<(), W::Err>
406                         where W: WriteBase32,
407                                   P: ToBase32 + Base32Len,
408                 {
409                         let len = payload.base32_len();
410                         assert!(len < 1024, "Every tagged field data can be at most 1023 bytes long.");
411
412                         writer.write_u5(u5::try_from_u8(tag).expect("invalid tag, not in 0..32"))?;
413                         writer.write(&try_stretch(
414                                 encode_int_be_base32(len as u64),
415                                 2
416                         ).expect("Can't be longer than 2, see assert above."))?;
417                         payload.write_base32(writer)
418                 }
419
420                 match *self {
421                         TaggedField::PaymentHash(ref hash) => {
422                                 write_tagged_field(writer, constants::TAG_PAYMENT_HASH, hash)
423                         },
424                         TaggedField::Description(ref description) => {
425                                 write_tagged_field(writer, constants::TAG_DESCRIPTION, description)
426                         },
427                         TaggedField::PayeePubKey(ref pub_key) => {
428                                 write_tagged_field(writer, constants::TAG_PAYEE_PUB_KEY, pub_key)
429                         },
430                         TaggedField::DescriptionHash(ref hash) => {
431                                 write_tagged_field(writer, constants::TAG_DESCRIPTION_HASH, hash)
432                         },
433                         TaggedField::ExpiryTime(ref duration) => {
434                                 write_tagged_field(writer, constants::TAG_EXPIRY_TIME, duration)
435                         },
436                         TaggedField::MinFinalCltvExpiry(ref expiry) => {
437                                 write_tagged_field(writer, constants::TAG_MIN_FINAL_CLTV_EXPIRY, expiry)
438                         },
439                         TaggedField::Fallback(ref fallback_address) => {
440                                 write_tagged_field(writer, constants::TAG_FALLBACK, fallback_address)
441                         },
442                         TaggedField::PrivateRoute(ref route_hops) => {
443                                 write_tagged_field(writer, constants::TAG_PRIVATE_ROUTE, route_hops)
444                         },
445                         TaggedField::PaymentSecret(ref payment_secret) => {
446                                   write_tagged_field(writer, constants::TAG_PAYMENT_SECRET, payment_secret)
447                         },
448                         TaggedField::Features(ref features) => {
449                                 write_tagged_field(writer, constants::TAG_FEATURES, features)
450                         },
451                 }
452         }
453 }
454
455 impl ToBase32 for InvoiceSignature {
456         fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
457                 let mut converter = BytesToBase32::new(writer);
458                 let (recovery_id, signature) = self.0.serialize_compact();
459                 converter.append(&signature[..])?;
460                 converter.append_u8(recovery_id.to_i32() as u8)?;
461                 converter.finalize()
462         }
463 }
464
465 #[cfg(test)]
466 mod test {
467         use bech32::CheckBase32;
468
469         #[test]
470         fn test_currency_code() {
471                 use Currency;
472
473                 assert_eq!("bc", Currency::Bitcoin.to_string());
474                 assert_eq!("tb", Currency::BitcoinTestnet.to_string());
475                 assert_eq!("bcrt", Currency::Regtest.to_string());
476                 assert_eq!("sb", Currency::Simnet.to_string());
477                 assert_eq!("tbs", Currency::Signet.to_string());
478         }
479
480         #[test]
481         fn test_raw_hrp() {
482                 use ::{Currency, RawHrp, SiPrefix};
483
484                 let hrp = RawHrp {
485                         currency: Currency::Bitcoin,
486                         raw_amount: Some(100),
487                         si_prefix: Some(SiPrefix::Micro),
488                 };
489
490                 assert_eq!(hrp.to_string(), "lnbc100u");
491         }
492
493         #[test]
494         fn test_encode_int_be_base32() {
495                 use ser::encode_int_be_base32;
496
497                 let input: u64 = 33764;
498                 let expected_out = CheckBase32::check_base32(&[1, 0, 31, 4]).unwrap();
499
500                 assert_eq!(expected_out, encode_int_be_base32(input));
501         }
502
503         #[test]
504         fn test_encode_int_be_base256() {
505                 use ser::encode_int_be_base256;
506
507                 let input: u64 = 16842530;
508                 let expected_out = vec![1, 0, 255, 34];
509
510                 assert_eq!(expected_out, encode_int_be_base256(input));
511         }
512 }