code wiki / _hdl_build / nx_simd_sse_rot_gate.nx
nx_simd_sse_rot_gate.nx source
↩ module page · 124 lines · 5323 B
1// nx_simd_sse_rot_gate.nx -- SOVEREIGN 128-bit SSE2 packed-shift/bitwise run-KAT
2// (rung R1 of the sovereign VECTOR backend). Proves the packed ROTATE primitive
3// -- the inner loop of every ARX cipher (ChaCha/BLAKE/Salsa) -- on REAL x86
4// silicon, NO gcc/qemu/binutils. AUTHOR=ORGAN, no-false-green.
5//
6// rotl32(x,n) = (pslld x,n) OR (psrld x,32-n). With x=0x80000001, n=1:
7// pslld $1 -> 0x00000002 (top bit shifted out of the 32-bit lane)
8// psrld $31 -> 0x00000001 (top bit becomes bit 0)
9// por -> 0x00000003 (both halves load-bearing => por is real)
10// POS exit = 3.
11// NEG swaps por->pand: 0x2 & 0x1 = 0 -> exit 0 (distinct => real silicon read).
12// GREEN iff pos==3 AND neg==0 AND pos!=neg. Run-proves: pslld, psrld, por (POS),
13// pand (NEG), movdqa reg-reg copy, + movdqu load/store again. The padd{b,w,q}/
14// psub{b,w,d,q} twins share the proven x86_sse_rr path (different opcode byte only).
15// Appends knowledge/status/simd_vec_kat.log. license_tier: ORIGINAL
16import "nx_syscalls.nx"
17import "nx_gate_verdict.nx"
18
19const ASM_TOOL: *u8 = "_offc/nxasm_x86_main.elf"
20const SV_LOG: *u8 = "knowledge/status/simd_vec_kat.log"
21
22func gw(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
23func gwn(fd: i64, v: i64) -> i64 {
24 let bb: *u8 = sys_mmap(28); var m: i64 = v
25 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
26 let t: *u8 = sys_mmap(28); var k: i64 = 0
27 if m == 0 { t[0] = 48; k = 1 }
28 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
29 var i: i64 = 0
30 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
31 sys_write(fd, bb, k); return 0
32}
33
34func g_run(path: *u8, argv: *i64) -> i64 {
35 let envp: *i64 = sys_mmap(8 * 4) as *i64
36 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64
37 envp[1] = 0
38 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4)
39 let pid: i64 = sys_fork()
40 if pid == 0 {
41 if dn >= 0 { sys_dup3(dn, 1, 0) }
42 if dn >= 0 { sys_dup3(dn, 2, 0) }
43 sys_execve(path, argv, envp)
44 sys_exit(127)
45 }
46 let st: *i64 = sys_mmap(16) as *i64
47 sys_wait4(pid, st, 0)
48 if dn >= 0 { sys_close(dn) }
49 let sig: i64 = st[0] & 0x7f
50 if sig != 0 { return 128 + sig }
51 return (st[0] >> 8) & 0xff
52}
53
54func asm_and_run(spath: *u8, elfpath: *u8) -> i64 {
55 let aa: *i64 = sys_mmap(8 * 4) as *i64
56 aa[0] = ASM_TOOL as i64
57 aa[1] = spath as i64
58 aa[2] = elfpath as i64
59 aa[3] = 0
60 let rc_a: i64 = g_run(ASM_TOOL, aa)
61 if rc_a != 0 { return 0 - 200 - rc_a }
62 let rr: *i64 = sys_mmap(8 * 4) as *i64
63 rr[0] = elfpath as i64
64 rr[1] = 0
65 return g_run(elfpath, rr)
66}
67
68// use_and==1 swaps the final por for pand (the NEG variant).
69func write_rot_s(path: *u8, use_and: i64) -> i64 {
70 let fd: i64 = sys_openat_wr(path, 0x1a4)
71 if fd < 0 { return 0 - 1 }
72 gw(fd, ".text\n" as *u8)
73 gw(fd, "_start:\n" as *u8)
74 gw(fd, "leaq vecR(%rip), %rdi\n" as *u8)
75 gw(fd, "movdqu (%rdi), %xmm0\n" as *u8)
76 gw(fd, "movdqa %xmm0, %xmm1\n" as *u8)
77 gw(fd, "pslld $1, %xmm0\n" as *u8)
78 gw(fd, "psrld $31, %xmm1\n" as *u8)
79 if use_and == 1 { gw(fd, "pand %xmm1, %xmm0\n" as *u8) } else { gw(fd, "por %xmm1, %xmm0\n" as *u8) }
80 gw(fd, "leaq outbuf(%rip), %rdx\n" as *u8)
81 gw(fd, "movdqu %xmm0, (%rdx)\n" as *u8)
82 gw(fd, "movl (%rdx), %edi\n" as *u8)
83 gw(fd, "movabsq $60, %rax\n" as *u8)
84 gw(fd, "syscall\n" as *u8)
85 gw(fd, ".section .rodata\n" as *u8)
86 gw(fd, "vecR:\n" as *u8)
87 gw(fd, ".byte 1,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0\n" as *u8)
88 gw(fd, ".lcomm outbuf, 16\n" as *u8)
89 sys_close(fd)
90 return 0
91}
92
93func g_emit(fd: i64, pos: i64, neg: i64, ok: i64) -> i64 {
94 gw(fd, "SIMD_VEC_KAT rung=R1-sse128-alu authored=organ width=128 reg=xmm forms=pslld+psrld+por+pand(+padd/psub{b,w,d,q}) sovereign(nx_cc->nxasm_x86,no-gcc/qemu/binutils) silicon=real rotl32(0x80000001,1)=3 pos3=" as *u8); gwn(fd, pos)
95 gw(fd, " neg0=" as *u8); gwn(fd, neg)
96 gw(fd, " distinct=" as *u8); if pos != neg { gwn(fd, 1) } else { gwn(fd, 0) }
97 if ok == 1 { gw(fd, " verdict=GREEN\n" as *u8) } else { gw(fd, " verdict=RED reason=exit-mismatch-or-encode-gap\n" as *u8) }
98 return 0
99}
100
101func main() -> i64 {
102 write_rot_s("/tmp/_sse_rot_pos.s" as *u8, 0)
103 let pos: i64 = asm_and_run("/tmp/_sse_rot_pos.s" as *u8, "/tmp/_sse_rot_pos.elf" as *u8)
104 write_rot_s("/tmp/_sse_rot_neg.s" as *u8, 1)
105 let neg: i64 = asm_and_run("/tmp/_sse_rot_neg.s" as *u8, "/tmp/_sse_rot_neg.elf" as *u8)
106
107 var ok: i64 = 1
108 if pos != 3 { ok = 0 }
109 if neg != 0 { ok = 0 }
110 if pos == neg { ok = 0 }
111
112 g_emit(1, pos, neg, ok)
113 let lf: i64 = sys_openat_append(SV_LOG, 420)
114 if lf >= 0 { g_emit(lf, pos, neg, ok); sys_close(lf) }
115 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
116 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
117 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
118 let ctr__dry: *i64 = gv_ctr()
119 ctr__dry[0] = ok
120 ctr__dry[1] = 1
121 let rc__dry: i64 = gv_verdict("SIMD-SSE-ROT-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
122 sys_exit(rc__dry)
123 return rc__dry
124}