Glossary

Bech32 and Bech32m

Human-readable address encoding formats for SegWit and Taproot Bitcoin addresses, with error detection and no mixed-case confusion.

Key Takeaways

  • Bech32 (BIP 173) is the address encoding used for SegWit version 0 outputs like P2WPKH. It uses a 32-character lowercase alphabet, a BCH error-detecting checksum, and a human-readable prefix (bc1 for mainnet) that makes addresses easy to verify and compact in QR codes.
  • Bech32m (BIP 350) fixes a length-extension vulnerability in bech32 by changing a single constant in the checksum algorithm. All witness version 1 and higher addresses, including Taproot (P2TR), use bech32m encoding instead of bech32.
  • Together these encodings replaced base58check for native SegWit addresses, delivering smaller QR codes, guaranteed detection of up to 4 character errors, lower transaction fees, and elimination of mixed-case confusion.

What Is Bech32?

Bech32 is a checksummed address encoding format introduced in BIP 173 by Pieter Wuille and Greg Maxwell in 2017. It was designed specifically for Segregated Witness outputs, giving Bitcoin its first native SegWit address format. Addresses encoded with bech32 begin with bc1q on mainnet and tb1q on testnet.

Before bech32, Bitcoin addresses used base58check encoding (seen in legacy P2PKH and P2SH addresses). Base58 mixed uppercase and lowercase letters, forced QR codes into inefficient byte mode, offered no guaranteed error-detection bounds, and was slow to decode due to repeated division. Bech32 solved all of these problems by using a 32-character lowercase alphabet and a BCH error-correcting code designed from first principles. For a full comparison of Bitcoin address types, see the address types deep dive.

How It Works

Every bech32 (and bech32m) address consists of three parts separated by a clear structure:

Address Structure

  1. Human-readable part (HRP): identifies the network. For Bitcoin mainnet this is bc, for testnet tb, and for regtest bcrt. The HRP is included in the checksum computation, so an address valid on mainnet will fail validation on testnet.
  2. Separator: always the character 1. Because 1 is excluded from the data character set, it unambiguously marks where the HRP ends and the data begins.
  3. Data part: encoded using 32 characters from the set qpzry9x8gf2tvdw0s3jn54khce6mua7l. The first character encodes the witness version (0 for SegWit v0, 1 for Taproot), followed by the witness program, followed by a 6-character checksum.
bc   1   q   w508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
──   ─   ─   ──────────────────────────────────────────
HRP  sep ver  witness program + checksum (bech32 chars)

The Character Set

Bech32 uses 32 characters drawn from the 36 alphanumeric characters (0-9, a-z) with four exclusions to avoid visual ambiguity:

  • 1 excluded: resembles lowercase l
  • b excluded: uppercase B resembles 8
  • i excluded: uppercase I resembles l
  • o excluded: uppercase O resembles 0

The ordering of characters within the set is not alphabetical. Visually similar character pairs are arranged to differ by a single bit, which maximizes the BCH code's ability to detect substitution errors between confusable characters.

BCH Checksum

The name "Bech32" combines "BCH" (the error-correction algorithm family) with "32" (the character set size). The checksum uses a degree-6 BCH code over the finite field GF(32), selected from 159,605 candidates through exhaustive computational analysis.

This checksum guarantees detection of up to 4 character-level errors in any address up to 89 characters long. It can locate up to 2 errors, though BIP 173 advises against automatic correction: an incorrect "fix" could produce a valid but wrong address, causing irreversible fund loss. The random failure rate for larger error patterns is less than 1 in 109.

// Simplified bech32 checksum verification
function bech32VerifyChecksum(hrp, data) {
  // Expand HRP: high bits, separator zero, low bits
  const values = hrpExpand(hrp).concat(data);
  // Valid bech32 when polymod equals 1
  // Valid bech32m when polymod equals 0x2bc830a3
  return polymod(values) === 1;
}

Bech32m: Fixing the Length Extension Vulnerability

After bech32 was deployed, researchers discovered a weakness: whenever the final data character before the checksum is p (which encodes value 1), inserting or removing any number of q characters (value 0) immediately before it does not invalidate the checksum. The detection failure probability for this specific mutation drops to roughly 1 in 1,024, far worse than the intended 1 in 109.

This was harmless for SegWit v0 because P2WPKH addresses must be exactly 42 characters and P2WSH addresses must be exactly 62 characters. Any length change from q-insertion would be caught by length validation, not the checksum. But future witness versions (including Taproot) could support variable-length witness programs of 2 to 40 bytes, making the vulnerability dangerous.

BIP 350 (bech32m), published by Pieter Wuille in 2021, fixes this by changing a single constant in the checksum algorithm:

EncodingChecksum constantUsed for
Bech320x00000001Witness version 0 (P2WPKH, P2WSH)
Bech32m0x2bc830a3Witness versions 1-16 (P2TR and future)

The constant 0x2bc830a3 was selected from over 230 candidates through exhaustive analysis to minimize problematic error classes. No valid bech32 string can also be valid bech32m at the same length: they differ by at least 3 characters, ensuring decoders can unambiguously distinguish them.

Address Types Summary

PrefixWitness versionEncodingOutput type
bc1q0Bech32P2WPKH (20-byte) or P2WSH (32-byte)
bc1p1Bech32mP2TR / Taproot (32-byte)
bc1...2-16Bech32mReserved for future witness versions

Why It Matters

Bech32 and bech32m are not just encoding details: they have practical consequences for every Bitcoin user and wallet developer.

  • QR code efficiency: bech32 addresses in uppercase use QR alphanumeric mode, which is 45% more compact than the byte mode required by mixed-case base58 addresses. This matters for QR code payments on mobile and point-of-sale devices.
  • Lower fees: native SegWit outputs encoded with bech32/bech32m produce smaller witness data on chain, saving 25-40% on transaction fees compared to legacy address types.
  • Error detection: the BCH checksum catches typos before funds are sent. This is critical in a system where transactions are irreversible.
  • No case confusion: because addresses are all lowercase (or all uppercase for QR), an entire class of transcription errors is eliminated.

Any wallet or layer-2 protocol built on Bitcoin benefits from these properties. Spark, for example, operates on top of Bitcoin's Taproot outputs, which use bech32m encoding. When a user performs an on-chain deposit to Spark, they send funds to a bc1p address whose encoding guarantees that typos are caught before broadcast.

Use Cases

Wallet Address Generation

Modern HD wallets following BIP 84 derive native SegWit addresses encoded as bech32 (bc1q). Wallets following BIP 86 derive Taproot addresses encoded as bech32m (bc1p). The derivation path determines which encoding applies. For a comparison of wallet implementations, see the wallet SDK comparison.

Payment Requests and Invoices

Bech32 addresses appear in on-chain payment requests, PSBTs, and any context where a user shares a receiving address. The compact QR representation is especially important for in-person payments and mobile wallet interactions.

Taproot Adoption

Every P2TR output requires bech32m encoding. As Taproot adoption grows, driven by Schnorr signatures, key-path spending efficiency, and protocols like Ordinals and Runes, bech32m addresses have become increasingly common on the network. The Taproot and Schnorr deep dive covers how these addresses enable more efficient and private transactions.

Risks and Considerations

Backward Compatibility

Older wallets and services that predate SegWit cannot send to bech32 or bech32m addresses. While most major wallets and exchanges added bech32 support between 2018 and 2020, bech32m (P2TR) support rolled out more gradually after Taproot activation in November 2021. Some smaller services, ATMs, and custodial platforms still lack full P2TR send support. Users should verify recipient compatibility before requesting payment to a bc1p address.

Encoding Confusion

Decoders must verify that the encoding matches the witness version: version 0 requires bech32, versions 1 and above require bech32m. Software that fails to enforce this rule could accept addresses with the wrong checksum type, undermining the error-detection guarantees that bech32m was designed to provide. Wallet developers should validate both the witness version and the encoding type during address parsing.

No Automatic Error Correction

Although the BCH code can locate up to 2 errors, BIP 173 explicitly recommends against automatic correction. A "corrected" address that passes the checksum may still be a valid but wrong address, sending funds to an unrecoverable destination. Wallets should flag errors and ask the user to re-enter the address rather than attempting repairs.

Length Validation Remains Essential

The bech32m fix addresses the length-extension vulnerability at the checksum level, but implementations should still enforce valid witness program lengths (20 or 32 bytes for version 0, 32 bytes for version 1, 2 to 40 bytes for future versions). Checksum validation alone is not sufficient: length constraints are a separate layer of defense.

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.