reticiulum-specification/audits/resource-tier1-rns-1.2.4.md

141 lines
6.1 KiB
Markdown
Raw Normal View History

# Tier 1 Audit: Resource Fragmentation
Question: Does `SPEC.md` §10 accurately describe the wire-visible Resource
fragmentation behavior of upstream RNS 1.2.4?
Evidence baseline:
- RNS package: `rns==1.2.4`
- Source: installed package paths `RNS/Resource.py`, `RNS/Packet.py`,
`RNS/Link.py`, and `LXMF/LXMessage.py`
- Audit date: 2026-06-08
This began as a Tier 1 source-analysis report. The completed Tier 2 checks
live in `tools/verify_resource.py` and `test-vectors/resources.json`; the
confirmed F1-F6 corrections were promoted into `SPEC.md` §10 on 2026-06-08.
## Confirmed Core Model
The central §10 model matches RNS 1.2.4:
- Resource prepends a throwaway 4-byte prefix, encrypts the complete stream
once with the Link, then slices the ciphertext into parts
(`Resource.py:404-428`, `453-472`; `Packet.py:201-204`).
- Advertisement `r` is a distinct 4-byte salt used for the resource hash and
per-part map hashes (`Resource.py:440-443`, `505-506`).
- Resource integrity is `SHA256(uncompressed_segment_plaintext || r)`, and the
expected proof is `SHA256(uncompressed_segment_plaintext || resource_hash)`
(`Resource.py:440-443`, `681-695`, `752-758`).
- RESOURCE_REQ may carry requested part hashes while also requesting a hashmap
continuation; the sender fulfils parts before emitting RESOURCE_HMU
(`Resource.py:994-1027`, `1027-1064`).
- RESOURCE parts are matched only within the receiver's current window, while
sender lookup is bounded by `COLLISION_GUARD_SIZE`
(`Resource.py:863-890`, `999-1010`).
## Findings Requiring Correction or Clarification
### F1 — Direct LXMF threshold is 319 bytes, not approximately 360
`SPEC.md` §10 introduction says Resource carries an LXMF body larger than
approximately 360 bytes. With default RNS 1.2.4 / LXMF 0.9.7 parameters:
```text
RNS.Link.MDU = 431
LXMessage.LXMF_OVERHEAD = 112
LXMessage.LINK_PACKET_MAX_CONTENT = 319
```
`LXMessage.pack()` selects Resource representation for DIRECT delivery when
`content_size > 319` (`LXMF/LXMessage.py:80-89`, `414-421`).
Recommended Tier 3 correction: say 319 bytes with default parameters, while
noting that the threshold derives from Link MDU and may vary with protocol
parameters.
### F2 — Resource is not the only possible way to carry larger application data
The §10 introduction calls Resource "the only way" to carry payloads exceeding
one Link packet. Resource is the standard RNS mechanism used by LXMF, Link
REQUEST/RESPONSE, and `rncp`, but applications can also stream or sequence data
over Channel or their own Link DATA protocol.
Recommended Tier 3 correction: replace "the only way" with "the standard RNS
mechanism used by LXMF, REQUEST/RESPONSE, and file-transfer utilities".
### F3 — Advertisement `d` is total logical-resource size
For multi-segment resources, advertisement field `d` is `resource.total_size`,
the total uncompressed logical transfer size including metadata, not the
plaintext size of the advertised segment (`Resource.py:281-314`,
`Resource.py:1281-1283`).
Each segment still has its own:
- `t`: encrypted transfer size for this segment
- `n`: part count for this segment
- `h`: integrity hash for this segment
- `r`: salt for this segment
Recommended Tier 3 correction: define `d` as total logical-resource size and
explicitly distinguish it from the current segment's uncompressed plaintext
length, which is not directly advertised.
### F4 — `RESOURCE_RCL` is not a general receiver-side cancel notification
`Resource.reject(advertisement_packet)` sends `RESOURCE_RCL`
(`Resource.py:154-163`). A corrupt receiver also calls `reject()` and tears
down the Link (`Resource.py:1081-1084`).
However, ordinary receiver-side `Resource.cancel()` only removes the incoming
resource locally; it does not send `RESOURCE_RCL`
(`Resource.py:1086-1097`). The current §10.9 wording implies either side can
always notify cancellation on the wire.
Recommended Tier 3 correction: describe `RESOURCE_RCL` as advertisement
rejection / corrupt-resource rejection. Do not claim ordinary receiver cancel
always emits it.
### F5 — Resource-part packet storage wording is imprecise
`SPEC.md` §10.2 says packed wire bytes are stored in `parts[i]`. Upstream stores
pre-packed `RNS.Packet` objects in `parts`; each packet's `data` is the raw
ciphertext slice and its `raw` field is the packed Reticulum packet
(`Resource.py:450-472`).
Recommended Tier 3 clarification: distinguish the stored Packet object, its
Resource body (`part.data`), and complete Reticulum wire packet (`part.raw`).
### F6 — Pinned-source mismatch in §10.7 citation
The exhausted-REQ callout cites RNS 1.2.9 while this repository is pinned to
RNS 1.2.4. The behavior is already present in RNS 1.2.4
(`Resource.py:994-1064`).
Recommended Tier 3 correction: cite the pinned 1.2.4 behavior first; retain a
later-version note only when documenting an actual version change.
## Tier 2 Verifier Scope
The focused verifier is implemented in `tools/verify_resource.py` and avoids
a live threaded transfer. It covers:
1. Construct a Resource with a deterministic fake Link encryption key, fixed
throwaway prefix, and fixed advertisement `r`.
2. Verify whole-stream encryption occurs before slicing.
3. Verify Resource-part Packet bodies are raw slices and are not packet-level
re-encrypted.
4. Verify advertisement dictionary fields, flags, and hashmap first segment.
5. Verify `hash`, `truncated_hash`, `expected_proof`, and map-hash formulas.
6. Verify RESOURCE_REQ parsing for both normal and exhausted-with-parts forms,
including simultaneous part fulfilment and RESOURCE_HMU generation.
7. Verify receiver assembly strips the throwaway prefix, decrypts once,
validates the hash, and emits the expected RESOURCE_PRF bytes.
8. Verify a multi-segment fixture proving `d` remains total logical size while
`t`, `n`, `h`, and `r` describe the current segment.
9. Verify negative cases: malformed ADV, wrong `r`, corrupt part, invalid HMU
boundary, and oversized decompression.
The deterministic fixture is regenerated by `tools/regen_resources.py`.
Tier 2 Resource work is complete for this audit scope; confirmed claims have
been promoted into `SPEC.md` and the Resource flow documents.