Skip to content

feat(aba): add aba_routing_decode — ABA routing number (RTN) decode + checksum#93

Merged
xunholy merged 1 commit into
mainfrom
feat/aba-routing-decode
Jun 24, 2026
Merged

feat(aba): add aba_routing_decode — ABA routing number (RTN) decode + checksum#93
xunholy merged 1 commit into
mainfrom
feat/aba-routing-decode

Conversation

@xunholy

@xunholy xunholy commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

Adds aba_routing_decode — the US bank routing-number (ABA RTN) decoder, completing the financial-loot-triage family alongside iban_decode (international account), lei_decode (entity), and isin_decode (security). An RTN + account number moves money over ACH/wire; RTNs appear in ACH-fraud / BEC lures, leaked direct-deposit forms, and check MICR lines.

Breaks an RTN into the 4-digit Federal Reserve routing symbol, the 4-digit ABA institution identifier, and the check digit, validated by the ABA weighted modulus-10 checksum (weights 3,7,1). The leading two digits resolve the institution type + Federal Reserve district by the published numbering ranges (Government / Primary FRB 01-12 / Thrift 21-32 / Electronic-ACH 61-72 / Traveler's cheque 80).

Design — no confidently-wrong output

  • Checksum is the verification anchor — mismatch → checksum_valid=false + note, never "fake bank".
  • District/type derived from fixed ranges, not guessed; an out-of-range prefix leaves the district undetermined.
  • Institution id surfaced raw (bank name lives only in the proprietary ABA registry, not embedded). Only the 12 statutory FRB districts (fixed by the 1913 Federal Reserve Act) are mapped to a city.
  • Low risk — offline, transmits nothing, stdlib only, no new dep.

Verification

Checksum checked against five real US bank RTNs — every assigned RTN satisfies the checksum, so a wrong algorithm couldn't pass all five:

bank RTN
JPMorgan Chase NY 021000021
FRB Boston (FedACH) 011000015
Bank of America CA 121000358
Bank of America NY 026009593
Chase IL 071000013
  • task test — full short suite, 398 ok / 0 fail
  • task lint 0 issues; task vet clean; task eval 12/12; task build exit 0
  • Plus thrift-range district case (322271627→district 12), separator tolerance, bad-checksum soft-note, structural-error boundaries, FuzzDecode, and a tool_search discoverability test.

Files

  • internal/aba/{aba.go,aba_test.go}, internal/tools/aba_routing_decode.go
  • internal/risk/risk.go (Low), registry_size_test.go (688→689), tool_search_test.go

… checksum

Extends the financial-loot-triage decoder family to the US-domestic bank
side. The family has the international account (iban_decode), the entity
(lei_decode) and the security (isin_decode); aba_routing_decode adds the
US bank identifier — the 9-digit ABA routing transit number that, with an
account number, moves money over ACH and wire. It turns up in ACH-fraud /
business-email-compromise lures, leaked direct-deposit forms, and check
MICR-line images, so decoding one off a paste tells an operator whether
the number is internally consistent and which Federal Reserve district
issued it.

It breaks an RTN into the 4-digit Federal Reserve routing symbol, the
4-digit ABA institution identifier, and the check digit, and validates it
with the ABA weighted modulus-10 checksum (weights 3,7,1 repeating). The
leading two digits resolve the institution type and Federal Reserve
district by the published RTN numbering ranges (Government / Primary FRB
01-12 / Thrift 21-32 / Electronic-ACH 61-72 / Traveler's cheque 80).

No confidently-wrong output, matching the iban/lei/isin/iccid design:

- The modulus-10 checksum is the verification anchor. A mismatch is
  reported as checksum_valid=false with a note (a mistyped or transposed
  RTN), never asserted as a definitively fake bank.
- The district/type are derived from the leading digits by fixed ranges,
  not guessed; a prefix outside the assigned ranges leaves the district
  undetermined rather than inventing one.
- The institution identifier is surfaced raw — the bank name lives only
  in the proprietary ABA registry, which is not embedded. Only the 12
  statutory Federal Reserve districts (fixed by the 1913 Federal Reserve
  Act, not drifting data) are mapped to their head-office city.

Native, stdlib only, no new go.mod dep. Offline transform — reads a
string, transmits nothing, so it is Low risk.

Verification: the checksum is checked against five real US bank routing
numbers (JPMorgan Chase 021000021, FRB Boston 011000015, Bank of America
121000358/026009593, Chase 071000013) — every assigned RTN satisfies the
checksum, so an incorrect algorithm could not make all five pass. Plus a
thrift-range district case (322271627 -> district 12), separator
tolerance, the bad-checksum soft-note path, structural-error boundaries,
and a panic-safety fuzz target. Discoverability is pinned by a tool_search
regression test (ABA routing number / RTN / bank routing transit number).

Wired: internal/aba/{aba.go,aba_test.go}, internal/tools/
aba_routing_decode.go, registered Low in internal/risk/risk.go, registry
count 688 -> 689.
@xunholy xunholy merged commit df49bd5 into main Jun 24, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant