BIP-350
BIP-350 defines the Bech32m address encoding format used for SegWit version 1 and later Bitcoin addresses including Taproot.
Key Takeaways
- BIP-350 introduces Bech32m, a modified version of the original Bech32 encoding that fixes a subtle checksum weakness affecting witness versions 1 and higher, including Taproot addresses.
- The only technical change is a different constant in the checksum function: Bech32 uses the constant 1, while Bech32m uses 0x2bc830a3. This single modification eliminates an undetectable insertion/deletion mutation in the original encoding.
- Bech32 (bc1q) remains in use for SegWit version 0 addresses like P2WPKH and P2WSH, while Bech32m (bc1p) is required for P2TR and all future witness versions.
What Is BIP-350?
BIP-350 is a Bitcoin Improvement Proposal authored by Pieter Wuille in December 2020 that defines the Bech32m address encoding format. It amends the original Bech32 specification (BIP-173) to use a modified checksum algorithm for native SegWit outputs of version 1 and later, while preserving the original Bech32 encoding for version 0 outputs.
The proposal emerged after researchers discovered a specific weakness in Bech32's error detection: when the last character of an encoded string is "p," inserting or deleting any number of "q" characters immediately before it does not invalidate the checksum. This mutation goes completely undetected. While version 0 addresses are protected by fixed length constraints, future witness versions with variable-length programs would be vulnerable. Bech32m closes this gap with a single, carefully chosen constant change.
How It Works
To understand BIP-350, it helps to first understand the encoding it modifies. BIP-173 defined the original Bech32 format for all native SegWit addresses. A Bech32-encoded address consists of three parts:
- A human-readable part (HRP): "bc" for mainnet, "tb" for testnet
- A separator: the character "1"
- A data part: the witness version, witness program, and a 6-character checksum
The checksum is computed using a polynomial over GF(2^5), designed to detect common transcription errors. In the original Bech32, the final step of checksum verification XORs the result with the constant 1. In Bech32m, this constant is replaced with 0x2bc830a3.
The Checksum Constant
The constant 0x2bc830a3 was not chosen arbitrarily. Pieter Wuille and Greg Maxwell tested all 2^30 possible constant values through exhaustive analysis, applying multiple filtering stages for error detection properties. From roughly one billion candidates, they narrowed the field to 12,054, then to 79, and finally selected 0x2bc830a3 as the single optimal choice that minimizes undetectable error classes while preserving Bech32's strong substitution error detection guarantees.
# Bech32 verification (BIP-173)
def bech32_verify_checksum(hrp, data):
return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1
# Bech32m verification (BIP-350)
BECH32M_CONST = 0x2bc830a3
def bech32m_verify_checksum(hrp, data):
return bech32_polymod(bech32_hrp_expand(hrp) + data) == BECH32M_CONSTThe polymod function, character set, HRP expansion, and every other aspect of the encoding remain identical between Bech32 and Bech32m. Only the final comparison constant differs.
The Bech32 Weakness
The original Bech32 checksum has a specific insertion/deletion vulnerability. Whenever the final character of the data part is "p" (value 1 in the Bech32 character set), inserting or deleting any number of "q" characters (value 0) immediately before it produces another valid checksum. For example, these would all produce valid checksums:
bc1q...xyzp (original)
bc1q...xyzqp (one q inserted: still valid checksum!)
bc1q...xyzqqp (two q's inserted: still valid checksum!)
bc1q...xyzqqqp (three q's: still valid!)For version 0 addresses, this is not exploitable because P2WPKH requires exactly 20 bytes and P2WSH requires exactly 32 bytes. Any insertion or deletion changes the length and is rejected before the checksum is even evaluated. However, future witness versions could allow variable-length programs, making this weakness a real risk.
Version-Based Encoding Rules
BIP-350 establishes a strict rule for which encoding to use based on the witness version:
| Witness Version | Encoding | Address Prefix | Current Use |
|---|---|---|---|
| 0 | Bech32 (BIP-173) | bc1q | P2WPKH, P2WSH |
| 1 | Bech32m (BIP-350) | bc1p | P2TR (Taproot) |
| 2 through 16 | Bech32m (BIP-350) | Varies | Reserved for future use |
Implementations must enforce this mapping strictly. A version 0 address encoded with Bech32m must be rejected as invalid, and a version 1 address encoded with Bech32 must also be rejected. This ensures that all software agrees on which checksum algorithm to use for validation.
Why It Matters
BIP-350 is essential infrastructure for Taproot, Bitcoin's most significant upgrade since SegWit. Every P2TR address that uses Schnorr signatures and Taproot script trees relies on Bech32m encoding. Without BIP-350, Taproot addresses would inherit the original Bech32 weakness, potentially allowing undetected address mutations when users copy and paste or manually transcribe addresses.
The proposal also future-proofs Bitcoin's address format. Any new witness version (2 through 16) will automatically use Bech32m, ensuring robust error detection regardless of the witness program length. This means future upgrades like proposals requiring new witness versions can rely on a proven, safe encoding scheme from day one.
For a deeper look at how Bitcoin address formats have evolved from legacy to Taproot, see the guide to Bitcoin address types.
Use Cases
- Taproot addresses: every bc1p address on Bitcoin mainnet uses Bech32m encoding. Sending to or receiving from a Taproot address requires BIP-350 support in the wallet or service handling the transaction.
- Future witness versions: any new SegWit version introduced through a soft fork will use Bech32m, providing consistent error detection properties without requiring another encoding change.
- Address validation: wallets and exchanges use BIP-350 to determine which checksum algorithm to apply when validating a user-provided address. The witness version byte dictates whether to verify with Bech32 or Bech32m.
- Cross-platform interoperability: BIP-350 provides a single, unambiguous standard for encoding and decoding Taproot addresses across wallets, block explorers, payment processors, and Layer 2 protocols like Spark that build on Bitcoin's address infrastructure.
Risks and Considerations
Wallet Compatibility
Bech32m addresses are not backward compatible with wallets that only support the original Bech32 encoding. Bitcoin Core added full BIP-350 support in version 22.0 (September 2021), and most major wallets and exchanges followed through 2022 and 2023. However, some older or unmaintained wallet software may still reject bc1p addresses entirely, displaying an "invalid address" error when users attempt to send to a Taproot address.
Before sending funds to a bc1p address, verify that the sending wallet or exchange supports Bech32m. If not, the transaction will fail at the address validation stage: funds will not be lost, but the payment will not go through.
Address Format Confusion
The existence of two visually similar encoding schemes (bc1q for Bech32, bc1p for Bech32m) can confuse users. Both formats share the same character set, the same "bc1" prefix, and the same general structure. The distinguishing character after "bc1" indicates the witness version: "q" maps to version 0 (Bech32), while "p" maps to version 1 (Bech32m).
For a complete breakdown of all Bitcoin address types and when to use each, see the glossary entry on address types.
Implementation Correctness
Software that validates or generates Bitcoin addresses must correctly implement both checksum algorithms and apply them based on witness version. A common implementation mistake is applying Bech32m validation to all addresses (breaking version 0 compatibility) or applying Bech32 validation to all addresses (breaking Taproot support). Reference implementations in multiple languages are available in the BIP-350 reference repository.
For more technical context on how Taproot uses Bech32m addresses and Schnorr signatures, see the Taproot and Schnorr signatures explainer.
This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.