Upstream RNS 1.2.4 (2026-05-07) announces it is "probably the last
release that is also published to GitHub" — pip continues until rnpkg
is complete and RNS is self-hosting. All 13 verifiers pass against
1.2.4 / 0.9.7; no wire-format, signing, or protocol behavior changed
between 1.2.0 and 1.2.4, so the changes here are purely currency:
- Pin tools/requirements.txt to rns==1.2.4 / lxmf==0.9.7 so the
verifier stays reproducible if upstream stops mirroring to PyPI
before the migration is ready.
- Add an "Upstream distribution shift" watch-list to todo.md (local
Reticulum node, repo destination hash, rnpkg install/upgrade
commands, rsg signature verification, mirroring source citations).
- Bump SPEC.md frontmatter and re-anchor ~50 line citations across
Identity.py, Transport.py, Resource.py, Link.py, Reticulum.py,
Packet.py, and LXMF/* (Identity.py drift was the heaviest at +13
to +31 lines; Transport.py was variable). Fix one numeric
(MAX_RANDOM_BLOBS = 32 → 64) and one semantic (§6.6.3 LRPROOF MTU
clamp citation pointed at the wrong location — corrected to point
at the transit-relay clamp at Transport.py:1539-1556).
- Update §10.4 decompression-bomb hazard to note upstream's 1.1.9 cap
adoption, with citations to Resource.py:686-691 and Buffer.py:95-97
plus a "do not use one-shot bz2.decompress()" warning.
- Re-anchor 11 flows/ files (version pins + ~30 line citations).
- Bump version labels in tools/README.md, test-vectors/README.md, and
4 verifier docstrings + 2 hardcoded print strings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tools/verify_token_crypto.py — locks in §3:
- Opportunistic Token encrypt/decrypt round-trip with full
ephemeral_pub(32) || iv(16) || aes(...) || hmac(32) layout check.
- HKDF salt = recipient.identity_hash verified by re-deriving
the key by hand and confirming decrypt succeeds.
- Link-derived Token form (no eph_pub prefix) round-trip.
- HMAC-then-AES order proven by tampering each region: HMAC
mismatch raises before AES decrypt.
- PKCS#7 padding boundaries (1B and 16B plaintexts).
tools/verify_announce_roundtrip.py — locks in §4 + §4.5:
- Build via upstream Destination.announce(send=False).
- Body layout walk with context_flag branching for the optional
ratchet slot.
- signed_data reconstruction per §4.2 with empty-bytes-not-absent
ratchet rule.
- dest_hash recompute per §1.2.
- random_hash[5:10] is a recent unix_seconds timestamp per §4.1
(corrected — confirms upstream emits the timestamp half).
- Upstream validate_announce accepts.
- Tamper detection: bit-flips in signature, public_key, name_hash,
random_hash, app_data are all rejected.
tools/verify_lxmf_opportunistic.py — locks in §5.1, §5.2, §5.5, §5.6
plus §3 layered correctly:
- Two identities (Alice, Bob) with mutual discovery.
- LXMessage build with title, content, fields.
- Body layout: dest(16) || src(16) || sig(64) || msgpack.
- Opportunistic-form strip of leading dest_hash before encryption.
- Encrypt to Bob via Token, decrypt as Bob, byte-identical
round-trip.
- Re-prepend dest_hash and run unpack_from_bytes; confirms
signature_validated=True and title/content/fields preserved.
All three pass against RNS 1.2.0 / LXMF 0.9.6.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>