code wiki / (root) / nx_swhid.nx

nx_swhid.nx source

↩ module page · 69 lines · 3017 B

1// nx_swhid.nx -- thin CLI over nx_swhid_lib. Compute the ISO/IEC 18670:2025 identifier of a file. 2// 3// The construction lives in the LIB so this command line and any in-process consumer prove the SAME 4// code, and so the gate can IMPORT the logic rather than fork this binary -- a fork is a boundary the 5// mutation harness is blind across, and a gate that cannot be mutated returns a GREEN that reads like 6// a proof while proving nothing. 7// 8// WHY A LIBRARIAN EMITS THIS ALONGSIDE ITS OWN sha256 AND NOT INSTEAD OF IT: 9// the SWHID is what the WORLD can check -- computed identically by everyone, from the bytes alone, 10// with no registry and no forge in the loop, and accepted as an identifier by SPDX 2.3 Annex F and 11// DataCite 4.7. The sha256 plus byte length is what WE trust, because SHA-1 has chosen-prefix 12// collisions (SHAttered, 2017) and is therefore an interoperable NAME, never tamper evidence. 13// Emitting only the SWHID would be a downgrade wearing a standard's number. 14// license_tier: ORIGINAL 15import "nx_syscalls.nx" 16import "nx_swhid_lib.nx" 17 18func swc_puts(s: *u8) -> i64 { sys_write(1, s, sw_len(s)); return 0 } 19 20func swc_num(v: i64) -> i64 { 21 let b: *u8 = sys_mmap(SW_HDR_MAX) 22 let n: i64 = sw_decimal(v, b, 0) 23 sys_write(1, b, n) 24 sys_munmap(b, SW_HDR_MAX) 25 return 0 26} 27 28func main(argc: i64, argv: *i64) -> i64 { 29 if argc < 3 { 30 swc_puts("usage: nx_swhid file <path>\n" as *u8) 31 swc_puts(" prints swh:1:cnt:<40 hex> -- the ISO/IEC 18670:2025 content identifier.\n" as *u8) 32 swc_puts(" Computed from the file BYTES alone: no filename, no path, no mtime, so it is\n" as *u8) 33 swc_puts(" stable across forges, renames and re-hosting, and anyone can recompute it.\n" as *u8) 34 swc_puts(" Also prints bytes=, because a digest says which bytes and only a LENGTH says how many.\n" as *u8) 35 return 3 36 } 37 let verb: *u8 = argv[1] as *u8 38 var isfile: i64 = 1 39 let f: *u8 = "file" as *u8 40 var i: i64 = 0 41 while f[i] != (0 as u8) { if verb[i] != f[i] { isfile = 0 } i = i + 1 } 42 if isfile == 1 { if verb[i] != (0 as u8) { isfile = 0 } } 43 if isfile == 0 { 44 swc_puts("REFUSED unknown-verb -- only 'file' exists today\n" as *u8) 45 return 3 46 } 47 48 let path: *u8 = argv[2] as *u8 49 // sys_read_file sizes its buffer FROM THE FILE and cannot short-read, so there is no cap to tune 50 // and no truncated read that would produce a confident WRONG identifier. 51 let lp: *i64 = sys_mmap(16) as *i64 52 let body: *u8 = sys_read_file(path, lp) 53 if (body as i64) == 0 { 54 swc_puts("REFUSED unreadable-file -- no identifier is emitted for bytes we do not hold\n" as *u8) 55 return 4 56 } 57 let n: i64 = lp[0] 58 let out: *u8 = sys_mmap(SW_IDLEN + 8) 59 let r: i64 = swhid_cnt(body, n, out) 60 if r < 0 { 61 swc_puts("REFUSED could-not-compute\n" as *u8) 62 return 4 63 } 64 swc_puts(out) 65 swc_puts(" bytes=" as *u8) 66 swc_num(n) 67 swc_puts("\n" as *u8) 68 return 0 69}