What problems identified with bech32 addresses have been resolved with the updated bech32m?

I am aware of one problem with the original bech32, namely length extension mutation weakness but I don't know if there were any others.


As far as I can tell "length extension mutation weakness" is the sole problem that needed to be resolved and is resolved by bech32m. But "length extension mutation weakness" includes both insertion and deletion.

Insertion: if a valid Bech32 string has the suffix p, inserting a single q character immediately before the p will produce another valid Bech32 string.

Deletion: if a valid Bech32 string has the suffix qp, removing the q character will produce another valid Bech32 string.

There are also more complex insertions and deletions that are possible than just "q before final p" too (see Pieter's comment at the bottom) though I haven't found this documented anywhere thus far.

To resolve this problem a new checksum algorithm has been designed by:

replacing the constant 1 that is xored into the checksum at the end with 0x2bc830a3

Bech32m encoding will only be used for SegWit output versions 1 and above. Version 0 will continue to use bech32 as the length extension mutation weakness does not present a problem for version 0 as SegWit v0 addresses are restricted to two specific lengths (No such length restrictions are currently imposed on higher SegWit version addresses.) They are defined to only be 42 characters (P2WPKH) or 62 characters (P2WSH). Although technically you could insert 20 q characters to make a P2WSH address with a valid checksum from a P2WPKH address, the checksum is not designed to guard against adversarial situations or insertions this large. The goal of the checksum is to protect against typos, copy paste errors, transcription errors, errors from being relayed as spoken words.

Pieter added on GitHub:

I think it's a bad idea to have multiple addresses valid for the same scriptPubKey. It only results in confusion when decoding/recoding doesn't roundtrip. v0 outputs use bech32, and I don't think this should ever change, for better or for worse. It also worsens error detection to 29 bits (as every v0 output now has two valid checksums).

Once you have proposed two different encoding schemes (bech32 and now bech32m) this presents a challenge to wallets of knowing which encoding is used and the bech32m draft BIP hence decides to make the two entirely incompatible ie it is impossible for a bech32m address to be a valid bech32 address and vice versa.

Thanks to Pieter Wuille and Russell O'Connor for some corrections on the original post.

  • 1
    The "insertion/deletion of q before final p" is not the only issue that Bech32m addresses, but it does primarily address issues that involve insertions and deletions (generally more complex ones than just "q before final p", though). Both Bech32 and Bech32m have the same performance for substitution-only changes. – Pieter Wuille Jan 5 at 18:20
  • 1
    Yes, you could insert/delete many q before a final p to turn a P2WPKH address into a P2WSH or vice verse. That's a ridiculously unlikely error though. – Pieter Wuille Jan 5 at 18:21
  • You aren't going to accidentally mistype and add 20 q's, that's for sure! I guess I'm thinking of a different scenario where you think you're sending to the address you normally do but actually you are tricked into sending to the normal address with 20 added q's and the checksum doesn't save you. – Michael Folkson Jan 5 at 18:33
  • 2
    A checksum can't save you from adversarial situations. Their goal is protecting against typos / copy paste errors / transcription errors / errors from being relayed as spoken words / ..., but not against someone intentionally trying to make you send to the wrong thing. – Pieter Wuille Jan 5 at 18:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.