BitcoinMachine
TECHNICAL_DOC // KEYS / CHECKSUM
CHECKSUM
A checksum is a short value derived from data used to detect transcription or transmission errors. Bitcoin uses two different checksum schemes: a 4-byte SHA256d truncation for Base58Check (legacy addresses, WIF, extended keys) and a 30-bit BCH polynomial code for Bech32/Bech32m (SegWit addresses). Both prevent funds from being sent to mistyped addresses.
WHY BITCOIN ADDRESSES INCLUDE CHECKSUMS
A Bitcoin address is one-shot: there is no "undo" once a transaction confirms. Without a checksum: Typo → tx broadcasts to invalid hash → funds locked permanently to provably-unspendable script → effectively burned With a checksum: Wallet decodes address, recomputes checksum Mismatch → wallet rejects address before signing → typo caught at input time Bitcoin uses two checksum families: Base58Check (legacy): 4-byte truncation of SHA256(SHA256(payload)) ~32 bits of error-detection power Bech32 / Bech32m (SegWit): 30-bit BCH polynomial code Mathematically guarantees detection of: - any single error (100%) - up to 4 errors (100%) - any number of errors (1 - 2⁻³⁰ ≈ 99.9999999%)
BASE58CHECK CHECKSUM
Method: SHA256d truncation
Size: 4 bytes (32 bits)
Computation: take first 4 bytes of SHA256(SHA256(payload))

Used in: P2PKH, P2SH, WIF, xpub/xprv
Detection: ≈ 99.9999998% of random errors
BECH32 CHECKSUM
Method: BCH polynomial code
Size: 30 bits (6 chars × 5 bits)
Constant: 1 (Bech32) or 0x2bc830a3 (Bech32m)

Used in: P2WPKH, P2WSH, P2TR
Detection: guaranteed for ≤4 errors
Base58Check Verification Procedure
DECODE
When parsing a "1...", "3...", "5...", "K...", "L...", or "xpub..." string, the wallet recomputes the checksum and rejects the input if it does not match.
Input: Base58 string (e.g. "1A1zP1eP5QGefi2D...") Step 1: Base58 decode → bytes decoded = base58_decode(input) (25 bytes for P2PKH) Step 2: Split payload = decoded[:-4] (e.g. version + hash160) expected = decoded[-4:] (last 4 bytes) Step 3: Recompute computed = SHA256(SHA256(payload))[0:4] Step 4: Compare if computed != expected: raise InvalidChecksum else: accept payload
Bech32 BCH Verification
DECODE
Bech32 uses polynomial arithmetic over GF(32). The polymod of the entire decoded string (HRP + data + checksum) must equal a fixed constant.
Input: lowercase string with HRP, "1", and 5-bit chars Step 1: Split at last "1" hrp = "bc" (or "tb") data_chars = "qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4" Step 2: Convert chars to 5-bit values via alphabet Step 3: Build full input values = expand_hrp(hrp) + data_5bit_values Step 4: Compute polymod result = bech32_polymod(values) Step 5: Verify constant Bech32 (witness v0): result must equal 1 Bech32m (witness v1): result must equal 0x2bc830a3 Mismatch → invalid address. Mixed case input → invalid (always lowercase).
TERMINOLOGY_INDEX
SHA256d
SHA256 applied twice. Bitcoin's standard hash. First 4 bytes used as Base58Check checksum.
BCH Code
Bose–Chaudhuri–Hocquenghem cyclic error-correcting code. Used in Bech32/Bech32m for guaranteed error detection.
Polymod
Polynomial modulo operation over GF(32) used to compute the Bech32 checksum.
Hamming Distance
Minimum number of character changes that produce a valid result. Bech32: ≥5. Higher → stronger detection.