nx_trace_merkle.nx
buildroot/runtime/nx_trace_merkle.nx
about
nx_trace_merkle.nx -- merkle-root summary of a provenance chain.
Per [[feedback-end-to-end-bit-traceability-architecture]]:
"federated via Merkle-root + branch fetch with per-call mutual
consent." nx_trace_merkle computes the merkle-root of a chain range
so cross-host verification can confirm "did your chain end with the
same root as mine?" without transmitting every link.
V1 ships:
- struct NxMerkleNode with hash + left/right child indices
- struct NxMerkleTree built from a contiguous span of trace entries
- root computation (bottom-up hash composition)
- verify_membership (does a given (call_id, output_hash) appear
in the tree summarized by this root?)
HASH COMPOSITION RULE: parent = combine(left_hash, right_hash) where
combine is V1 simple-XOR-with-rotate. V2 swaps in BLAKE3 once the
existing nx_blake2b primitive is wired here. The current combine is
NOT cryptographically secure; V1's purpose is the STRUCTURE
(merkle-tree composition + verify pattern), V2 makes the hash strong.
Composes:
nx_trace_log -- the entries we summarize
nx_provenance_chain -- alternative source (in-memory ring)
nx_methyl -- merkle roots can be methyl-marked for sharing
nx_pollinate -- merkle roots travel as XENO_OBSERVATION payloads
(one root verifies a whole trace range)
Gap list (V1 honest perf verdict):
- combine is XOR-with-rotate, NOT cryptographically secure
(V2 swaps to BLAKE3 via nx_blake2b)
- tree is balanced binary; odd-leaf-count uses duplicate-last
pattern (standard merkle convention)
- no streaming-build (whole tree built from finite range in V1)
dependencies 3 imports · 2 importers
imports: nx_syscalls.nxnx_tier.nxnx_trace_log.nx
imported by: nx_session_audit_compose_test.nxnx_trace_merkle_test.nx
structs
| 53 | struct NxMerkleTree |
consts
| 40 | const NX_MK_OK: nx_int = 0 |
| 41 | const NX_MK_ERR_EMPTY: nx_int = 1 |
| 42 | const NX_MK_ERR_BAD_RANGE: nx_int = 2 |
| 43 | const NX_MK_ERR_TOO_LARGE: nx_int = 3 |
| 44 | const NX_MK_NOT_MEMBER: nx_int = 4 |
| 45 | const NX_MK_MEMBER: nx_int = 5 |
| 60 | const NX_MK_MAX_LEAVES: nx_size = 256 |
functions
| 68 | func _mk_combine(left: nx_size, right: nx_size) -> nx_size called by 1: nx_trace_merkle_build |
| 80 | func nx_trace_merkle_build(log: *NxTraceLog, |
| 135 | func nx_trace_merkle_root(t: *NxMerkleTree) -> nx_size |
| 145 | func nx_trace_merkle_verify_member(t: *NxMerkleTree, |
| 160 | func nx_trace_merkle_leaf_count(t: *NxMerkleTree) -> nx_size called by 1: main |
| 171 | func nx_trace_merkle_roots_equal(a: *NxMerkleTree, b: *NxMerkleTree) -> nx_int |