Bech32 logic is used for Lightning invoice decoding & encoding, and the bech32 crate is used for that.
This analysis is triggered by the upgrade from bech32 v0.9.1 to bech32 v0.11.0, during which the library API has changed significantly.
The upgrade is being handled by PR #3181 ( #3176 ) .
Here is an analysis of needed/used functionalities, and recommendations:
-
Type for 5-bit numbers
- used to be
u5 type, a wrapped byte, but that's replaced by Fe32, which is roughly similar, but has different focus (field element arithmetic)
Fe32 has some minor shortcomings (no Ord ordering, no default)
- Recommendation is to create own type for this. It is a simple
u8 wrapper with a few conversion methods.
- As this type is used in many places, rolling own implementation minimizes the dependency points to an external crate.
-
Bech32 character encoding.
- This can be used from
Fe32
- Recommendation is to duplicate logic, as it's rather simple (2 lookup tables)
-
Encoding/decoding packed 5 bit values to bytes
- this is an important operation, can be used from
bech32 crate (Fe32IterExt, ByteIterExt).
- it's also possible to duplicate logic, either way seems fine
-
Checksum verification and creation
- This can be used from
bech32 create
- As this has some hashing operations, recommendation is to use from external (implementation can be taken over later; lightning needs only one of the hash method)
-
Parsing of HRP, data part and Checksum
- Can be used from external create, or taken over, minimal logic.
-
Parsing of tagged values
- This is own implementation, as
bech32 has no lightning-specific logic (and probably will not have later, not in scope).
Conclusion:
- Best seems to be to re-implement some logic (
u5 type, packed decoding, etc.), while reusing some logic from the external crate,
but in a reduced and isolated way (checksum handling). Getting rid of the external dependency entirely is also a possibility.
- Own implementation can have the API finetuned for the lightning use case, and reduce the clutter due to type and error conversions.
Options for location of bech32 logic:
- A mod within
lightning crate (e.g. bech32.rs)
- A separate create within the repo (e.g.
bech32-lightning)
- The
lightning-invoice crate is NOT a good option, as lightning crate cannot use it, and currently there is some need there (invoice encoding for signing).
- Later it could be isolated into a new repo, potentially usable by other Rust lightning implementations
Bech32 logic is used for Lightning invoice decoding & encoding, and the
bech32crate is used for that.This analysis is triggered by the upgrade from
bech32 v0.9.1tobech32 v0.11.0, during which the library API has changed significantly.The upgrade is being handled by PR #3181 ( #3176 ) .
Here is an analysis of needed/used functionalities, and recommendations:
Type for 5-bit numbers
u5type, a wrapped byte, but that's replaced byFe32, which is roughly similar, but has different focus (field element arithmetic)Fe32has some minor shortcomings (noOrdordering, no default)u8wrapper with a few conversion methods.Bech32 character encoding.
Fe32Encoding/decoding packed 5 bit values to bytes
bech32crate (Fe32IterExt, ByteIterExt).Checksum verification and creation
bech32createParsing of HRP, data part and Checksum
Parsing of tagged values
bech32has no lightning-specific logic (and probably will not have later, not in scope).Conclusion:
u5type, packed decoding, etc.), while reusing some logic from the external crate,but in a reduced and isolated way (checksum handling). Getting rid of the external dependency entirely is also a possibility.
Options for location of bech32 logic:
lightningcrate (e.g.bech32.rs)bech32-lightning)lightning-invoicecrate is NOT a good option, aslightningcrate cannot use it, and currently there is some need there (invoice encoding for signing).