nx_bt_v2_merkle_gate.nx source
↩ module page · 57 lines · 3657 B
1// nx_bt_v2_merkle_gate.nx -- proves the BitTorrent v2 SHA-256 merkle tree + inclusion proofs: build a root over 4
2// blocks, prove ONE block belongs to the root with log2(n) siblings (verifiable random access), and show tamper
3// detection + wrong-proof rejection. expect_exit: 0 license_tier: ORIGINAL
4import "nx_bt_v2_merkle.nx"
5import "nx_sha256.nx"
6import "nx_syscalls.nx"
7
8func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
9func g_ck(name: *u8, cond: i64, st: *i64) -> i64 { st[1]=st[1]+1; if cond==1 { st[0]=st[0]+1; g_puts(" [OK] " as *u8) } else { g_puts(" [FAIL] " as *u8) } g_puts(name); g_puts("\n" as *u8); return 0 }
10func g_hex(b: *u8, n: i64) -> i64 { let hx: *u8="0123456789abcdef" as *u8; var i: i64=0; while i<n { let o: *u8=sys_mmap(2); o[0]=hx[((b[i] as i64)>>4)&15]; o[1]=hx[(b[i] as i64)&15]; sys_write(1,o,2); i=i+1 } return 0 }
11func lp(leaves: *u8, i: i64) -> *u8 { return (leaves as i64 + i*32) as *u8 }
12
13func main() -> i64 {
14 g_puts("=== nx_bt_v2_merkle_gate: BitTorrent v2 SHA-256 merkle tree + inclusion proofs ===\n" as *u8)
15 let st: *i64 = sys_mmap(64) as *i64; st[0]=0; st[1]=0
16
17 let leaves: *u8 = sys_mmap(4*32)
18 mk_leaf("block-alpha" as *u8, 11, lp(leaves,0))
19 mk_leaf("block-bravo" as *u8, 11, lp(leaves,1))
20 mk_leaf("block-charl" as *u8, 11, lp(leaves,2))
21 mk_leaf("block-delta" as *u8, 11, lp(leaves,3))
22
23 let root: *u8 = sys_mmap(32); mk_root(leaves, 4, root)
24 g_puts(" merkle root = "); g_hex(root, 32); g_puts("\n" as *u8)
25
26 // T1 deterministic: rebuilding from the same leaves gives the same root
27 let root2: *u8 = sys_mmap(32); mk_root(leaves, 4, root2)
28 g_ck("T1 root is deterministic (rebuild == root)" as *u8, mk_memeq(root, root2, 32), st)
29
30 // T2 tamper: change one block -> different root
31 let lt: *u8 = sys_mmap(4*32); var c: i64=0; while c<4*32 { lt[c]=leaves[c]; c=c+1 }
32 mk_leaf("block-XXXXX" as *u8, 11, lp(lt,2))
33 let rootT: *u8 = sys_mmap(32); mk_root(lt, 4, rootT)
34 g_ck("T2 tamper detection (one block changed -> root differs)" as *u8, (mk_memeq(rootT, root, 32))==0, st)
35
36 // T3 inclusion proof for leaf 2 verifies against the root (log2(4)=2 siblings)
37 let proof: *u8 = sys_mmap(8*32); let np: i64 = mk_proof(leaves, 4, 2, proof)
38 g_ck("T3 inclusion proof: block #2 verified with 2 siblings" as *u8, (np==2) & (mk_verify(lp(leaves,2), 2, proof, np, root)==1), st)
39
40 // T4 wrong leaf with a valid proof path is REJECTED
41 g_ck("T4 wrong block + block#2's proof -> REJECTED" as *u8, mk_verify(lp(leaves,0), 2, proof, np, root)==0, st)
42
43 // T5 structural: 2-leaf root == SHA-256(h0 || h1) via mk_node directly
44 let root2l: *u8 = sys_mmap(32); mk_root(leaves, 2, root2l)
45 let node01: *u8 = sys_mmap(32); mk_node(lp(leaves,0), lp(leaves,1), node01)
46 g_ck("T5 2-leaf root == node(h0,h1) (tree math correct)" as *u8, mk_memeq(root2l, node01, 32), st)
47
48 // T6 a different leaf's proof also verifies
49 let proof0: *u8 = sys_mmap(8*32); let np0: i64 = mk_proof(leaves, 4, 0, proof0)
50 g_ck("T6 inclusion proof for block #0 also verifies" as *u8, mk_verify(lp(leaves,0), 0, proof0, np0, root)==1, st)
51
52 g_puts("\n PASS " as *u8); if st[0]==st[1] { g_puts("ALL" as *u8) } else { g_puts("PARTIAL" as *u8) }
53 let p: *u8=sys_mmap(8); p[0]=(48+st[0]) as u8; p[1]=47 as u8; p[2]=(48+st[1]) as u8; p[3]=0 as u8
54 g_puts(" ("); g_puts(p); g_puts(")\n" as *u8)
55 if st[0]==st[1] { g_puts("=== GREEN (BitTorrent v2 merkle: content root + verifiable random-access proofs) ===\n" as *u8); sys_exit(0); return 0 }
56 g_puts("=== RED ===\n" as *u8); sys_exit(1); return 1
57}