code wiki / (root) / nx_u4096_test.nx

nx_u4096_test.nx source

↩ module page · 131 lines · 4032 B

1// nx_u4096_test.nx -- KAT for the 4096-bit big-int primitives. 2// Mirrors nx_u384_test / nx_u256_test, scaled to 128 limbs / 512 bytes. 3// 4// expect_exit: 0 5// license_tier: ORIGINAL 6 7import "nx_syscalls.nx" 8import "nx_u4096.nx" 9 10func main() -> i64 { 11 // ---- Test A: zero / one ---- 12 let z: *i64 = u4096_alloc() 13 u4096_zero(z) 14 if u4096_is_zero(z) != 1 { return 1 } 15 u4096_one(z) 16 if z[0] != 1 { return 2 } 17 if u4096_is_zero(z) != 0 { return 3 } 18 var i: i64 = 1 19 while i < NX_U4096_LIMBS { 20 if z[i] != 0 { return 4 } 21 i = i + 1 22 } 23 24 // ---- Test B: load_be / store_be round-trip ---- 25 let pat: *u8 = sys_mmap(NX_U4096_BYTES) 26 i = 0 27 while i < NX_U4096_BYTES { 28 pat[i] = (i + 1) as u8 // 0x01..0x200 (wraps at 256 mod 256) 29 i = i + 1 30 } 31 let a: *i64 = u4096_alloc() 32 u4096_load_be(a, pat) 33 // High limb (index 127) should hold bytes 0..3 BE = 0x01020304 34 if a[127] != 0x01020304 { return 10 } 35 // Low limb (index 0) should hold bytes 508..511 BE. 36 // pat[508] = (508+1)&0xff = 509 & 0xff = 253 = 0xFD 37 // pat[509] = 510 & 0xff = 254 = 0xFE 38 // pat[510] = 511 & 0xff = 255 = 0xFF 39 // pat[511] = 512 & 0xff = 0 = 0x00 40 if a[0] != 0xFDFEFF00 { return 11 } 41 42 let pat2: *u8 = sys_mmap(NX_U4096_BYTES) 43 u4096_store_be(pat2, a) 44 i = 0 45 while i < NX_U4096_BYTES { 46 if (pat2[i] & 0xff) != (pat[i] & 0xff) { return 20 } 47 i = i + 1 48 } 49 50 // ---- Test C: add / sub round-trip ---- 51 // c = a + 1; d = c - 1; d == a 52 let one_v: *i64 = u4096_alloc() 53 u4096_one(one_v) 54 let c: *i64 = u4096_alloc() 55 let carry: i64 = u4096_add_with_carry(c, a, one_v) 56 if carry != 0 { return 50 } 57 let d: *i64 = u4096_alloc() 58 let borrow: i64 = u4096_sub_with_borrow(d, c, one_v) 59 if borrow != 0 { return 51 } 60 if u4096_eq(d, a) != 1 { return 52 } 61 62 // ---- Test D: carry propagation across all 128 limbs ---- 63 // 0xFF..FF + 1 = 0 with carry-out 1 64 let all_ones: *i64 = u4096_alloc() 65 i = 0 66 while i < NX_U4096_LIMBS { 67 all_ones[i] = NX_U4096_LIMB_MASK 68 i = i + 1 69 } 70 let e: *i64 = u4096_alloc() 71 let carry2: i64 = u4096_add_with_carry(e, all_ones, one_v) 72 if carry2 != 1 { return 60 } 73 if u4096_is_zero(e) != 1 { return 61 } 74 75 // 0 - 1 = 0xFF..FF with borrow-out 1 76 let f: *i64 = u4096_alloc() 77 let z2: *i64 = u4096_alloc() 78 let borrow2: i64 = u4096_sub_with_borrow(f, z2, one_v) 79 if borrow2 != 1 { return 70 } 80 if u4096_eq(f, all_ones) != 1 { return 71 } 81 82 // ---- Test E: cmp ---- 83 if u4096_cmp(z2, one_v) != 0 - 1 { return 80 } 84 if u4096_cmp(one_v, z2) != 1 { return 81 } 85 if u4096_cmp(one_v, one_v) != 0 { return 82 } 86 87 // ---- Test F: shl1 / shr1 round-trip with carry across all limbs ---- 88 // Start with 1 in low bit; shl1 four times -> 16 at low bit. 89 let g: *i64 = u4096_alloc() 90 u4096_one(g) 91 u4096_shl1(g) 92 u4096_shl1(g) 93 u4096_shl1(g) 94 u4096_shl1(g) 95 if g[0] != 16 { return 90 } 96 u4096_shr1(g) 97 u4096_shr1(g) 98 u4096_shr1(g) 99 u4096_shr1(g) 100 if g[0] != 1 { return 91 } 101 var k: i64 = 1 102 while k < NX_U4096_LIMBS { 103 if g[k] != 0 { return 92 } 104 k = k + 1 105 } 106 107 // ---- Test G: shl1 carry from limb 0 into limb 1 ---- 108 let h: *i64 = u4096_alloc() 109 u4096_zero(h) 110 h[0] = 0x80000000 // high bit of limb 0 111 u4096_shl1(h) 112 if h[0] != 0 { return 100 } 113 if h[1] != 1 { return 101 } 114 115 // ---- Test H: get_bit ---- 116 let j: *i64 = u4096_alloc() 117 u4096_zero(j) 118 j[0] = 0x5 // bits 0 and 2 set 119 j[3] = 0x80000000 // bit 32*3+31 = 127 set 120 if u4096_get_bit(j, 0) != 1 { return 110 } 121 if u4096_get_bit(j, 1) != 0 { return 111 } 122 if u4096_get_bit(j, 2) != 1 { return 112 } 123 if u4096_get_bit(j, 127) != 1 { return 113 } 124 if u4096_get_bit(j, 128) != 0 { return 114 } 125 126 // "PASS\n" 127 let ok: *u8 = sys_mmap(8) 128 ok[0]=80; ok[1]=65; ok[2]=83; ok[3]=83; ok[4]=10 129 sys_write(1, ok, 5) 130 return 0 131}