code wiki / (root) / nx_homefwd_adversary.nx

nx_homefwd_adversary.nx source

↩ module page · 104 lines · 3227 B

1// nx_homefwd_adversary.nx -- SELF-CHECKING adversary KAT for G10 home- 2// forwarding + G11 chain fusion. Prints each answer AND returns the number of 3// FAILED checks (0 = all pass), so the differential gauntlet catches wrong 4// VALUES (baseline exit 0 vs candidate exit N), not just crashes. 5// T1 G10 STORE-GUARD: a = x; x = x + 1; b += (x - a) -> b == n (3). 6// (X86_NEGCTL_FWD_IGNORE_STORE forwards a's load past the store -> b=0.) 7// T2 POSITIVE: s += arr[j] -> 600. 8// T3 DOUBLE-USE: y += t + t, t = x2 (use_count 2, never forwarded) -> 36. 9// T4 G11 MID-CHAIN READ: x3 = x3*3 + 1 + x3 -- the second read of x3 sits 10// INSIDE the would-be chain window; the scan must ABORT the fusion. 2 11// iters from 2: 9 -> 37. (X86_NEGCTL_CHAIN_IGNORE_READ fuses anyway -> 12// the second read sees the mutated home -> 14 -> 86 -> RED.) 13// T5 G11 PURE CHAIN: x4 = x4*3 + 1 fuses in place; 3 iters from 2: 14// 7 -> 22 -> 67. 15// Seeds come from mmap'd memory so const-prop cannot fold them. 16// license_tier: ORIGINAL No hw writes (Rule 26). 17import "nx_syscalls_x86_64.nx" 18 19func hf_emit_i64(fd: i64, n: i64) -> i64 { 20 let scratch: *u8 = sys_mmap(32) 21 var v: i64 = n 22 var neg: i64 = 0 23 if v < 0 { neg = 1; v = 0 - v } 24 var k: i64 = 0 25 if v == 0 { scratch[0] = 0x30 as u8; k = 1 } 26 while v > 0 { scratch[k] = (0x30 + (v - (v / 10) * 10)) as u8; v = v / 10; k = k + 1 } 27 let rev: *u8 = sys_mmap(48) 28 var ro: i64 = 0 29 if neg == 1 { rev[0] = 0x2D as u8; ro = 1 } 30 var j: i64 = 0 31 while j < k { rev[ro + j] = scratch[k - 1 - j]; j = j + 1 } 32 rev[ro + k] = 0x0A as u8 33 sys_write(fd, rev, ro + k + 1) 34 return 0 35} 36 37func main() -> i64 { 38 let cfg: *i64 = sys_mmap(64) as *i64 39 cfg[0] = 3 40 cfg[1] = 10 41 cfg[2] = 5 42 cfg[3] = 2 43 let n: i64 = cfg[0] 44 var fails: i64 = 0 45 46 // T1: G10 store-guard. 47 var x: i64 = cfg[1] 48 var b: i64 = 0 49 var i: i64 = 0 50 while i < n { 51 let a: i64 = x 52 x = x + 1 53 b = b + (x - a) 54 i = i + 1 55 } 56 hf_emit_i64(1, b) 57 if b != 3 { fails = fails + 1 } 58 59 // T2: positive coverage. 60 let arr: *i64 = sys_mmap(64) as *i64 61 var f: i64 = 0 62 while f < 8 { arr[f] = (f + 1) * 100; f = f + 1 } 63 var s: i64 = 0 64 var j: i64 = 0 65 while j < n { s = s + arr[j]; j = j + 1 } 66 hf_emit_i64(1, s) 67 if s != 600 { fails = fails + 1 } 68 69 // T3: double-use load never killed. 70 var x2: i64 = cfg[2] 71 var y: i64 = 0 72 var k: i64 = 0 73 while k < n { 74 let t: i64 = x2 75 y = y + t + t 76 x2 = x2 + 1 77 k = k + 1 78 } 79 hf_emit_i64(1, y) 80 if y != 36 { fails = fails + 1 } 81 82 // T4: G11 mid-chain read -- fusion must ABORT (second read of x3 inside 83 // the window). 2 iters from 2: x3 = 3*x3 + 1 + x3 -> 9 -> 37. 84 var x3: i64 = cfg[3] 85 var m: i64 = 0 86 while m < 2 { 87 x3 = x3 * 3 + 1 + x3 88 m = m + 1 89 } 90 hf_emit_i64(1, x3) 91 if x3 != 37 { fails = fails + 1 } 92 93 // T5: G11 pure chain fuses in place. 3 iters from 2: 7 -> 22 -> 67. 94 var x4: i64 = cfg[3] 95 var q: i64 = 0 96 while q < n { 97 x4 = x4 * 3 + 1 98 q = q + 1 99 } 100 hf_emit_i64(1, x4) 101 if x4 != 67 { fails = fails + 1 } 102 103 return fails 104}