reticiulum-specification/tools/regen_resources.py
John Poole 7433063bfb Completed the Resource three-tier work unit.
Added deterministic `resources.json` and `regen_resources.py`.
Extended `verify_resource.py` with receiver assembly/proof and requested negative cases.
Updated specification, audit, status, and tool documentation.
Fixed an unrelated nondeterministic wrong-ticket test in verify_stamps.py.
Confirmed vector regeneration is byte-identical.
Confirmed no tracked reliance on specenv or user-specific paths.
git diff --check: pass.
Complete pinned suite: 16 passed, 0 failed.
2026-06-08 13:38:24 -07:00

146 lines
5 KiB
Python

"""
Regenerator for test-vectors/resources.json.
Builds a deterministic multi-part Resource over a fixed fake Link. The link
Token key, Token IV, throwaway prefix, and Resource random-hash salt are pinned
so every ciphertext byte, part packet, map hash, advertisement, and proof is
reproducible against the pinned RNS version.
Run from repo root:
python tools/regen_resources.py
Updates `test-vectors/resources.json` in place. Exit 0 on success.
"""
from __future__ import annotations
import json
import os
import sys
import RNS
from RNS.Cryptography.Token import Token
from RNS.Resource import Resource, ResourceAdvertisement
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OUT_PATH = os.path.join(REPO_ROOT, "test-vectors", "resources.json")
FIXED_TOKEN_KEY = bytes(range(64))
FIXED_TOKEN_IV = bytes.fromhex("404142434445464748494a4b4c4d4e4f")
FIXED_PREFIX = bytes.fromhex("10111213")
FIXED_RANDOM_HASH = bytes.fromhex("20212223")
PLAINTEXT = bytes(range(256)) * 5
class FakeLink:
"""Minimum deterministic Link surface needed by Resource construction."""
def __init__(self):
self.type = RNS.Destination.LINK
self.status = RNS.Link.ACTIVE
self.mtu = RNS.Reticulum.MTU
self.mdu = RNS.Link.MDU
self.hash = bytes.fromhex("00112233445566778899aabbccddeeff")
self.link_id = self.hash
self.rtt = 0.1
self.traffic_timeout_factor = 1
self.last_outbound = 0
self.tx = 0
self.txbytes = 0
self._token = Token(FIXED_TOKEN_KEY)
def encrypt(self, data: bytes) -> bytes:
return self._token.encrypt(data)
def decrypt(self, data: bytes) -> bytes:
return self._token.decrypt(data)
def main() -> None:
print(f"regen_resources.py against RNS {RNS.__version__}")
token_mod = sys.modules["RNS.Cryptography.Token"]
real_urandom = token_mod.os.urandom
real_get_random_hash = RNS.Identity.get_random_hash
random_hashes = [
FIXED_PREFIX + bytes(28),
FIXED_RANDOM_HASH + bytes(28),
]
def fixed_urandom(length: int) -> bytes:
if length == 16:
return FIXED_TOKEN_IV
return real_urandom(length)
def fixed_random_hash() -> bytes:
if not random_hashes:
raise RuntimeError("unexpected additional Resource random-hash request")
return random_hashes.pop(0)
token_mod.os.urandom = fixed_urandom
RNS.Identity.get_random_hash = staticmethod(fixed_random_hash)
try:
link = FakeLink()
resource = Resource(PLAINTEXT, link, advertise=False, auto_compress=False)
finally:
token_mod.os.urandom = real_urandom
RNS.Identity.get_random_hash = staticmethod(real_get_random_hash)
encrypted_stream = b"".join(part.data for part in resource.parts)
advertisement = ResourceAdvertisement(resource).pack()
proof = resource.hash + resource.expected_proof
vector = {
"label": "fixed_link_uncompressed_multi_part",
"inputs": {
"plaintext_hex": PLAINTEXT.hex(),
"token_key_hex": FIXED_TOKEN_KEY.hex(),
"token_iv_hex": FIXED_TOKEN_IV.hex(),
"throwaway_prefix_hex": FIXED_PREFIX.hex(),
"random_hash_hex": FIXED_RANDOM_HASH.hex(),
"link_hash_hex": link.hash.hex(),
"mtu": link.mtu,
"auto_compress": False,
},
"expected": {
"encrypted_stream_hex": encrypted_stream.hex(),
"resource_hash_hex": resource.hash.hex(),
"expected_proof_hex": resource.expected_proof.hex(),
"resource_prf_body_hex": proof.hex(),
"hashmap_hex": resource.hashmap.hex(),
"advertisement_plaintext_hex": advertisement.hex(),
"parts": [
{
"body_hex": part.data.hex(),
"map_hash_hex": part.map_hash.hex(),
"raw_hex": part.raw.hex(),
}
for part in resource.parts
],
},
"rns_version_at_generation": RNS.__version__,
"generator_script": "tools/regen_resources.py",
"verifies_spec_sections": ["10.2", "10.3", "10.4", "10.8", "10.12"],
}
payload = {
"_about": (
"Deterministic Resource transfer vector over a fixed Link Token key. "
"The Resource is uncompressed and spans multiple RESOURCE packets. "
"A clean-room implementation should encrypt `throwaway_prefix || "
"plaintext` once with the recorded Token key and IV, slice the "
"ciphertext at the Resource SDU, reproduce every part and map hash, "
"pack the advertisement, then assemble and emit the recorded PRF body."
),
"vectors": [vector],
}
with open(OUT_PATH, "w", encoding="utf-8", newline="\n") as output:
json.dump(payload, output, indent=2, sort_keys=False)
output.write("\n")
print(f"Wrote {OUT_PATH} with 1 vector")
print("ALL PASS")
if __name__ == "__main__":
main()