Skip to content

crypto: validate BTC/ETH address checksums #4

Description

@ClaudiuCeia

Crypto addresses are currently accepted on shape alone — a single-character mutation of a valid address is still detected as a wallet address.

Evidence

  • src/CryptoAddress.ts:60-79 validates Bitcoin addresses only by character set and length
  • src/CryptoAddress.ts:107-167 accepts checksum-invalid Base58Check and Bech32/Bech32m strings
  • src/CryptoAddress.ts:170-184 accepts every mixed-case Ethereum address without EIP-55
  • Negative tests only cover length (tests/CryptoAddress.test.ts:68-89)

Proposal
After the existing cheap shape prefilter:

  • Legacy BTC (P2PKH/P2SH): Base58Check decode, require 25-byte payload, version byte 0x00/0x05, verify 4-byte double-SHA-256 checksum
  • Bech32/Bech32m: verify polymod (Bech32 for v0, Bech32m for v1-16), validate witness program length/padding, accept all-upper or all-lower, reject mixed case
  • ETH: accept all-lower/all-upper freely; require EIP-55 checksum for mixed-case

Tests to add

  • One-character mutations of known-valid BTC/Base58Check and Bech32 addresses → reject
  • Valid uppercase Bech32 → accept
  • Valid mixed-case EIP-55 → accept; same address with one case bit flipped → reject

Performance note
Keep regexes as prefilters so the hashing cost only applies to shape candidates. Inputs are short and bounded. Deno has crypto.subtle for SHA-256; Keccak-256 for EIP-55 needs a small vendored implementation or a dependency decision.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions