code wiki / _hdl_build / nx_nishifs_cid.nx

nx_nishifs_cid.nx source

↩ module page · 167 lines · 8703 B

1// nx_nishifs_cid.nx -- ladder C2 (the FILE SYSTEM): NishiFS CORE = a content-addressed (CID/Merkle) object store. 2// 3// This is the rung that turns the OS+FS design's headline exceed axis from DESIGN-TARGET into MEASURED reality. 4// June-2026 research (deep-research wf_b31a496b-971): dm-verity is fixed-ADDRESS Merkle (not hash-keyed retrieval), 5// composefs verifies in USERSPACE, and APFS/ext4 have NO data checksums. NishiFS goes content-ADDRESSED: every 6// object is stored BY its sha256 (the CID), git/IPFS-style, at /tmp/nishifs/<cidhex>. Properties, all proven here: 7// * content-addressed put/get: store a blob -> get its CID; retrieve BY CID -> the bytes back. 8// * INTEGRITY-ON-READ: cid_get returns bytes ONLY if they re-hash to the requested CID (tamper -> caught). 9// * DEDUP by construction: identical content -> identical CID -> one object. 10// * MERKLE directory: a dir = (name,childCID) entries; the dir's CID = sha256(serialized) -> the whole-tree 11// state is ONE root CID, so changing ANY leaf changes the root (tamper-evident whole-FS state). 12// composes nx_sha256 (CID = sha256, proven in the C3 installer) + nx_syscalls. CoW snapshots, mount/format onto a 13// C1 partition, and native encryption are the NEXT rungs. 14// NEVER-BRICK (Rule 26): writes FILES only (under /tmp/nishifs); no /dev, no firmware. expect_exit: 0 license_tier: ORIGINAL 15import "nx_syscalls.nx" 16import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 17import "nx_sha256.nx" 18 19const GET_OK: i64 = 0 20const GET_NOTFOUND: i64 = 3 21const GET_INTEGRITY_FAIL: i64 = 7 22 23func ui_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 24// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 25// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 26// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 27// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 28func ui_num(v: i64) -> i64 { nxi_out(v); return 0 } 29func ui_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 30func cid_eq(a: *u8, b: *u8) -> i64 { var i: i64=0; while i<32 { if a[i]!=b[i] { return 0 } i=i+1 } return 1 } 31 32// 32-byte CID -> 64-char lowercase hex (+ NUL) for the object filename. 33func cid_hex(cid: *u8, out: *u8) -> i64 { 34 var i: i64=0 35 while i<32 { 36 let b: i64 = cid[i] as i64 37 let hi: i64 = (b>>4)&15 38 let lo: i64 = b&15 39 var c1: i64 = 48+hi; if hi>9 { c1=87+hi } 40 var c2: i64 = 48+lo; if lo>9 { c2=87+lo } 41 out[i*2]=c1 as u8 42 out[i*2+1]=c2 as u8 43 i=i+1 44 } 45 out[64]=0 as u8 46 return 0 47} 48// object store path = /tmp/nishifs/<cidhex> 49func obj_path(hex: *u8, out: *u8) -> i64 { 50 let pre: *u8 = "/tmp/nishifs/\x00" 51 var i: i64=0 52 while pre[i]!=(0 as u8) { out[i]=pre[i]; i=i+1 } 53 var j: i64=0 54 while hex[j]!=(0 as u8) { out[i]=hex[j]; i=i+1; j=j+1 } 55 out[i]=0 as u8 56 return 0 57} 58func w_file(path: *u8, buf: *u8, n: i64) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd<=0 { return 0-1 } sys_write(fd, buf, n); sys_close(fd); return 0 } 59 60// CID put: object addressed BY its sha256; dedup by construction (same content -> same path -> one object). 61func cid_put(blob: *u8, n: i64, cidout: *u8) -> i64 { 62 sha256_digest(blob, n, cidout) 63 let hex: *u8 = sys_mmap(72) 64 cid_hex(cidout, hex) 65 let path: *u8 = sys_mmap(160) 66 obj_path(hex, path) 67 return w_file(path, blob, n) 68} 69// CID get WITH INTEGRITY-ON-READ: returns bytes only if they re-hash to the requested CID. 70func cid_get(cid: *u8, out: *u8, cap: i64, lenout: *i64) -> i64 { 71 let hex: *u8 = sys_mmap(72) 72 cid_hex(cid, hex) 73 let path: *u8 = sys_mmap(160) 74 obj_path(hex, path) 75 let lenp: *i64 = sys_mmap(8) as *i64 76 let rb: *u8 = sys_read_file(path, lenp) 77 if (rb as i64)==0 { return GET_NOTFOUND } 78 let h2: *u8 = sys_mmap(40) 79 sha256_digest(rb, lenp[0], h2) 80 if cid_eq(h2, cid)==0 { return GET_INTEGRITY_FAIL } // tamper / corruption caught by construction 81 var m: i64 = lenp[0] 82 if m > cap { m = cap } 83 var j: i64=0 84 while j<m { out[j]=rb[j]; j=j+1 } 85 lenout[0]=lenp[0] 86 return GET_OK 87} 88// Merkle directory: serialize (name + 32-byte childCID) per entry; the dir's CID = sha256(serialized). 89func dir_serialize(nA: *u8, cA: *u8, nB: *u8, cB: *u8, out: *u8) -> i64 { 90 var w: i64=0 91 var i: i64=0 92 while nA[i]!=(0 as u8) { out[w]=nA[i]; w=w+1; i=i+1 } 93 out[w]=0 as u8; w=w+1 94 i=0; while i<32 { out[w]=cA[i]; w=w+1; i=i+1 } 95 i=0; while nB[i]!=(0 as u8) { out[w]=nB[i]; w=w+1; i=i+1 } 96 out[w]=0 as u8; w=w+1 97 i=0; while i<32 { out[w]=cB[i]; w=w+1; i=i+1 } 98 return w 99} 100 101func main() -> i64 { 102 ui_puts("ladder C2: NishiFS CORE -- content-addressed (CID/Merkle) object store (the file system)\n" as *u8) 103 104 let A: *u8 = "hello nishi filesystem -- block one\x00" as *u8 105 let A2: *u8 = "hello NISHI filesystem -- block one\x00" as *u8 106 let B: *u8 = "content addressed merkle -- block two\x00" as *u8 107 let nA: i64 = ui_slen(A) 108 let nA2: i64 = ui_slen(A2) 109 let nB: i64 = ui_slen(B) 110 111 let cidA: *u8 = sys_mmap(40) 112 let cidB: *u8 = sys_mmap(40) 113 let cidA_again: *u8 = sys_mmap(40) 114 cid_put(A, nA, cidA) 115 cid_put(B, nB, cidB) 116 cid_put(A, nA, cidA_again) // dedup: same content -> same CID -> same object 117 118 // T1 content-addressed round-trip (capture BEFORE tamper) 119 let outA: *u8 = sys_mmap(256) 120 let lenA: *i64 = sys_mmap(8) as *i64 121 let rget: i64 = cid_get(cidA, outA, 256, lenA) 122 var rtmatch: i64 = 0 123 if rget==GET_OK { if lenA[0]==nA { rtmatch=1; var i: i64=0; while i<nA { if outA[i]!=A[i] { rtmatch=0; i=nA } else { i=i+1 } } } } 124 125 // T2 deterministic content-address (recompute) 126 let cidA_re: *u8 = sys_mmap(40) 127 sha256_digest(A, nA, cidA_re) 128 129 // T5 Merkle root over {a:cidA, b:cidB}, then change one leaf (A->A2) and rebuild 130 let ser: *u8 = sys_mmap(256) 131 let w1: i64 = dir_serialize("a\x00" as *u8, cidA, "b\x00" as *u8, cidB, ser) 132 let rootCID: *u8 = sys_mmap(40) 133 sha256_digest(ser, w1, rootCID) 134 let cidA2: *u8 = sys_mmap(40) 135 sha256_digest(A2, nA2, cidA2) 136 let ser2: *u8 = sys_mmap(256) 137 let w2: i64 = dir_serialize("a\x00" as *u8, cidA2, "b\x00" as *u8, cidB, ser2) 138 let rootCID2: *u8 = sys_mmap(40) 139 sha256_digest(ser2, w2, rootCID2) 140 141 // T4 tamper A's object file -> integrity-on-read must catch 142 let hexA: *u8 = sys_mmap(72) 143 cid_hex(cidA, hexA) 144 let pathA: *u8 = sys_mmap(160) 145 obj_path(hexA, pathA) 146 w_file(pathA, "TAMPERED-NOT-THE-CONTENT\x00" as *u8, 24) 147 let outT: *u8 = sys_mmap(256) 148 let lenT: *i64 = sys_mmap(8) as *i64 149 let rtamper: i64 = cid_get(cidA, outT, 256, lenT) 150 151 var pass: i64=0 152 var ttl: i64=0 153 ttl=ttl+1; ui_puts(" T1 content-addressed round-trip (put A -> get by CID -> bytes match): " as *u8); if rtmatch==1 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 154 ttl=ttl+1; ui_puts(" T2 CID is a deterministic content-address (sha256(A)==cidA): " as *u8); if cid_eq(cidA_re, cidA)==1 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 155 ttl=ttl+1; ui_puts(" T3 dedup by construction (put A twice -> identical CID -> one object): " as *u8); if cid_eq(cidA_again, cidA)==1 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 156 ttl=ttl+1; ui_puts(" T4 integrity-on-read catches tampering (LIAR-KILL): " as *u8); if rtamper==GET_INTEGRITY_FAIL { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 157 ttl=ttl+1; ui_puts(" T5 Merkle root: change ONE leaf (A->A2) -> root CID changes (whole-tree tamper-evident): " as *u8); if cid_eq(rootCID2, rootCID)==0 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 158 ttl=ttl+1; ui_puts(" T6 distinct content -> distinct CID (cidA != cidB): " as *u8); if cid_eq(cidA, cidB)==0 { pass=pass+1; ui_puts("PASS\n" as *u8) } else { ui_puts("FAIL\n" as *u8) } 159 160 let rh: *u8 = sys_mmap(72) 161 cid_hex(rootCID, rh) 162 ui_puts(" NishiFS root CID (one hash over the whole dir tree) = " as *u8); sys_write(1, rh, 16); ui_puts("...\n" as *u8) 163 164 ui_puts("NISHIFS-CID-GATE passed " as *u8); ui_num(pass); ui_puts("/" as *u8); ui_num(ttl) 165 if pass==ttl { ui_puts(" verdict=GREEN (content-addressed object store: CID put/get + dedup + integrity-on-read + Merkle root = the NishiFS core; CoW snapshots + mount-on-C1-partition + encryption = next rungs)\n" as *u8); sys_exit(0); return 0 } 166 ui_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 167}