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