99//! a data part. A checksum at the end of the string provides error detection to prevent mistakes
1010//! when the string is written off or read out loud.
1111//!
12+ //! Please note, so as to support lighting ([BOLT-11]) we explicitly do not do string length checks
13+ //! in the top level API. We do however enforce the 90 character limit within the `segwit` modules.
14+ //!
1215//! # Usage
1316//!
1417//! - If you are doing segwit stuff you likely want to use the [`segwit`] API.
113116//!
114117//! # }
115118//! ```
119+ //!
120+ //! [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
116121
117122#![ cfg_attr( all( not( feature = "std" ) , not( test) ) , no_std) ]
118123// Experimental features we need.
@@ -169,6 +174,8 @@ pub use {
169174/// If your input string has no checksum use the [`CheckedHrpstring`] constructor, which allows
170175/// selecting the checksum algorithm explicitly.
171176///
177+ /// Note: this function does not enforce any restrictions on the total length of the input string.
178+ ///
172179/// # Returns
173180///
174181/// The human-readable part and the encoded data with the checksum removed.
@@ -214,6 +221,15 @@ pub fn decode(s: &str) -> Result<(Hrp, Vec<u8>), DecodeError> {
214221///
215222/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
216223/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
224+ ///
225+ /// ## Deviation from spec (BIP-173)
226+ ///
227+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
228+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
229+ ///
230+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
231+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
232+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
217233#[ cfg( feature = "alloc" ) ]
218234#[ inline]
219235pub fn encode < Ck : Checksum > ( hrp : Hrp , data : & [ u8 ] ) -> Result < String , fmt:: Error > {
@@ -224,6 +240,15 @@ pub fn encode<Ck: Checksum>(hrp: Hrp, data: &[u8]) -> Result<String, fmt::Error>
224240///
225241/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
226242/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
243+ ///
244+ /// ## Deviation from spec (BIP-173)
245+ ///
246+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
247+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
248+ ///
249+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
250+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
251+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
227252#[ cfg( feature = "alloc" ) ]
228253#[ inline]
229254pub fn encode_lower < Ck : Checksum > ( hrp : Hrp , data : & [ u8 ] ) -> Result < String , fmt:: Error > {
@@ -236,6 +261,15 @@ pub fn encode_lower<Ck: Checksum>(hrp: Hrp, data: &[u8]) -> Result<String, fmt::
236261///
237262/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
238263/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
264+ ///
265+ /// ## Deviation from spec (BIP-173)
266+ ///
267+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
268+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
269+ ///
270+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
271+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
272+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
239273#[ cfg( feature = "alloc" ) ]
240274#[ inline]
241275pub fn encode_upper < Ck : Checksum > ( hrp : Hrp , data : & [ u8 ] ) -> Result < String , fmt:: Error > {
@@ -248,6 +282,15 @@ pub fn encode_upper<Ck: Checksum>(hrp: Hrp, data: &[u8]) -> Result<String, fmt::
248282///
249283/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
250284/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
285+ ///
286+ /// ## Deviation from spec (BIP-173)
287+ ///
288+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
289+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
290+ ///
291+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
292+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
293+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
251294#[ inline]
252295pub fn encode_to_fmt < Ck : Checksum , W : fmt:: Write > (
253296 fmt : & mut W ,
@@ -261,6 +304,15 @@ pub fn encode_to_fmt<Ck: Checksum, W: fmt::Write>(
261304///
262305/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
263306/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
307+ ///
308+ /// ## Deviation from spec (BIP-173)
309+ ///
310+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
311+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
312+ ///
313+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
314+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
315+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
264316#[ inline]
265317pub fn encode_lower_to_fmt < Ck : Checksum , W : fmt:: Write > (
266318 fmt : & mut W ,
@@ -279,6 +331,15 @@ pub fn encode_lower_to_fmt<Ck: Checksum, W: fmt::Write>(
279331///
280332/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
281333/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
334+ ///
335+ /// ## Deviation from spec (BIP-173)
336+ ///
337+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
338+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
339+ ///
340+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
341+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
342+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
282343#[ inline]
283344pub fn encode_upper_to_fmt < Ck : Checksum , W : fmt:: Write > (
284345 fmt : & mut W ,
@@ -297,6 +358,15 @@ pub fn encode_upper_to_fmt<Ck: Checksum, W: fmt::Write>(
297358///
298359/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
299360/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
361+ ///
362+ /// ## Deviation from spec (BIP-173)
363+ ///
364+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
365+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
366+ ///
367+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
368+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
369+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
300370#[ cfg( feature = "std" ) ]
301371#[ inline]
302372pub fn encode_to_writer < Ck : Checksum , W : std:: io:: Write > (
@@ -311,6 +381,15 @@ pub fn encode_to_writer<Ck: Checksum, W: std::io::Write>(
311381///
312382/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
313383/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
384+ ///
385+ /// ## Deviation from spec (BIP-173)
386+ ///
387+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
388+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
389+ ///
390+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
391+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
392+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
314393#[ cfg( feature = "std" ) ]
315394#[ inline]
316395pub fn encode_lower_to_writer < Ck : Checksum , W : std:: io:: Write > (
@@ -330,6 +409,15 @@ pub fn encode_lower_to_writer<Ck: Checksum, W: std::io::Write>(
330409///
331410/// Encoded string will be prefixed with the `hrp` and have a checksum appended as specified by the
332411/// `Ck` algorithm (`NoChecksum` to exclude checksum all together).
412+ ///
413+ /// ## Deviation from spec (BIP-173)
414+ ///
415+ /// In order to support [BOLT-11] this function does not restrict the total length of the returned
416+ /// string. To encode [BIP-173] / [BIP-350] compliant segwit addresses use [`segwit::encode`].
417+ ///
418+ /// [BIP-173]: <https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki>
419+ /// [BIP-350]: <https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki>
420+ /// [BOLT-11]: <https://github.com/lightning/bolts/blob/master/11-payment-encoding.md>
333421#[ cfg( feature = "std" ) ]
334422#[ inline]
335423pub fn encode_upper_to_writer < Ck : Checksum , W : std:: io:: Write > (
@@ -493,4 +581,29 @@ mod tests {
493581
494582 assert_eq ! ( got, want) ;
495583 }
584+
585+ #[ test]
586+ fn can_encode_really_long_string ( ) {
587+ // Encode around the bech32 limit, mainly here as documentation.
588+ let tcs = vec ! [
589+ // Also shows there are no limit checks on the data slice (since segwit limits this to 40 bytes).
590+ ( [ 0_u8 ; 50 ] , Hrp :: parse_unchecked( "abc" ) ) , // Encodes to 90 characters.
591+ ( [ 0_u8 ; 50 ] , Hrp :: parse_unchecked( "abcd" ) ) , // Encodes to 91 characters.
592+ ] ;
593+ for ( data, hrp) in tcs {
594+ assert ! ( encode:: <Bech32 >( & hrp, & data) . is_ok( ) ) ;
595+ }
596+
597+ // Encode something arbitrarily long.
598+ let data = [ 0_u8 ; 1024 ] ;
599+ let hrp = Hrp :: parse_unchecked ( "abc" ) ;
600+ assert ! ( encode:: <Bech32m >( & hrp, & data) . is_ok( ) ) ;
601+ }
602+
603+ #[ test]
604+ fn can_decode_long_string ( ) {
605+ // A 91 character long string, greater than the segwit enforced maximum of 90.
606+ let s = "abcd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqrw9z3s" ;
607+ assert ! ( decode( s) . is_ok( ) ) ;
608+ }
496609}
0 commit comments