nx_install_hash.nx
buildroot/runtime/nx_install_hash.nx
about
nx_install_hash.nx -- compute install_hash from NxInstallPlan via
canonical serialization + SHA-256.
SA-7 partial milestone of NISHI_SELF_ASSEMBLY_ROADMAP.md. The
install_hash is the racing-line "ProvenanceLink" per
[[feedback-end-to-end-bit-traceability-architecture]]: every
install attestation carries a hash that future audits can
reproduce by replaying the selector against the recorded inputs.
install_hash = SHA-256(canonical_serialize(plan))
Canonical serialization rules:
1. Magic tag "NXIPLN01" (8 bytes) so plans of different schema
versions cannot collide
2. Every fixed i64 field written little-endian, in declared
struct order
3. EXCLUDED: canary_pre + canary_post (tamper-detect, not
content); ts_us (timestamp varies across runs but inputs same)
4. selected_variant_ids array written after n_selected (which
acts as the length prefix), each i64 little-endian
Reproducibility gate (the SA-7 verification): same inputs
(probe + calibration + policy + selection) produce bit-equal
install_hash. Differences in ts_us or canaries do NOT affect
the hash (excluded by design).
Sensitivity gate: any change to a content field (probe, calibration,
policy, selection) produces a different install_hash. This makes
the install_hash a sensitive integrity check, not just a
deterministic value.
Refuses to hash a tampered plan: nx_install_plan_is_valid must
return 1 before serialization; otherwise returns
NX_HASH_BAD_PLAN. Canary tamper is a substrate-honesty signal,
not something to silently hash over.
Deferred per roadmap:
- in-toto link metadata serialization with the hash chained
to source.nx file hashes (SA-7 remainder)
- Rekor-class append-only audit log local-by-default (SA-7
dependencies 3 imports · 11 importers
diagram shows first 10 each side; +0 more imports, +1 more importers in the complete lists below.
imports: nx_syscalls.nxnx_install_plan.nxnx_sha256.nx
imported by: nx_emitted_substrate.nxnx_install_attest.nxnx_install_attest_signed.nxnx_install_attest_signed_test.nxnx_install_attest_test.nxnx_install_hash_test.nxnx_install_pipeline.nxnx_install_pipeline_test.nxnx_spore_up_lifecycle_test.nxnx_spore_up_network_test.nxnx_spore_up_test.nx
structs
| none |
consts
| 80 | const NX_HASH_OK: i64 = 0 |
| 81 | const NX_HASH_BAD_PLAN: i64 = 1 |
| 82 | const NX_HASH_BAD_OUT: i64 = 2 |
| 85 | const NX_INSTALL_HASH_BYTES: i64 = 32 // SHA-256 digest size |
| 86 | const NX_INSTALL_HASH_BUF_SIZE: i64 = 4096 // serialization scratch |
functions
| 94 | func _store_i64_le(buf: *u8, off: i64, v: i64) -> i64 called by 1: nx_install_plan_serialize |
| 107 | func _store_magic_tag(buf: *u8, off: i64) -> i64 called by 1: nx_install_plan_serialize |
| 123 | func nx_install_plan_serialize(plan: *NxInstallPlan, buf: *u8) -> i64 |
| 179 | func nx_install_hash_compute(plan: *NxInstallPlan, out_digest: *u8) -> i64 |
| 197 | func nx_install_hash_eq(a: *u8, b: *u8) -> i64 |