code wiki / (root) / nx_rsa2048_mont_gate.nx

nx_rsa2048_mont_gate.nx source

↩ module page · 82 lines · 2732 B

1// nx_rsa2048_mont_gate.nx -- correctness gate: Montgomery modexp MUST equal the 2// trusted bit-by-bit modexp for the same (s, e, n). Pins rsa2048_mod_exp_mont 3// before it replaces the slow path in TLS cert verification. 4// 5// expect_exit: 0 6 7import "nx_syscalls.nx" 8import "nx_u2048.nx" 9import "nx_u2048_mul.nx" 10import "nx_rsa2048_mod.nx" 11import "nx_rsa2048_mod_exp.nx" 12import "nx_rsa2048_mont.nx" 13 14func g_ps(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 } 15func g_pn(v: i64) -> i64 { 16 let b: *u8 = sys_mmap(24) 17 var x: i64 = v 18 if x < 0 { x = 0 - x } 19 var i: i64 = 22 20 if x == 0 { b[i] = 0x30 as u8; i = i - 1 } 21 else { while x > 0 { b[i] = (0x30 + (x - (x/10)*10)) as u8; x = x / 10; i = i - 1 } } 22 sys_write(1, ((b as i64) + i + 1) as *u8, 22 - i) 23 return 0 24} 25 26// Build a 2048-bit odd modulus with the top bit set, from a seed. 27func mk_n(n: *i64, seed: i64) -> i64 { 28 var i: i64 = 0 29 while i < NX_U2048_LIMBS { 30 n[i] = ((seed + i * 2654435761) * 40503 + 12345) & NX_U2048_LIMB_MASK 31 i = i + 1 32 } 33 n[NX_U2048_LIMBS - 1] = (n[NX_U2048_LIMBS - 1] | 0x80000000) & NX_U2048_LIMB_MASK // top bit 34 n[0] = (n[0] | 1) & NX_U2048_LIMB_MASK // odd 35 return 0 36} 37 38// Build s with top bit clear so s < 2^2047 <= n (guarantees s < n). 39func mk_s(s: *i64, seed: i64) -> i64 { 40 var i: i64 = 0 41 while i < NX_U2048_LIMBS { 42 s[i] = ((seed * 7 + i * 1013904223) * 22695477 + 1) & NX_U2048_LIMB_MASK 43 i = i + 1 44 } 45 s[NX_U2048_LIMBS - 1] = s[NX_U2048_LIMBS - 1] & 0x7FFFFFFF 46 return 0 47} 48 49func one_case(seed: i64, e: i64) -> i64 { 50 let n: *i64 = u2048_alloc(); mk_n(n, seed) 51 let s: *i64 = u2048_alloc(); mk_s(s, seed) 52 let r1: *i64 = u2048_alloc() 53 let r2: *i64 = u2048_alloc() 54 rsa2048_mod_exp(r1, s, e, n) 55 rsa2048_mod_exp_mont(r2, s, e, n) 56 if u2048_cmp(r1, r2) == 0 { return 1 } 57 g_ps(" MISMATCH seed=" as *u8, 14); g_pn(seed); g_ps(" e=" as *u8, 3); g_pn(e); g_ps("\n" as *u8, 1) 58 return 0 59} 60 61func main() -> i64 { 62 var pass: i64 = 0 63 var total: i64 = 0 64 let seeds: *i64 = sys_mmap(64) as *i64 65 seeds[0]=11; seeds[1]=1009; seeds[2]=70001; seeds[3]=305419896 66 let exps: *i64 = sys_mmap(64) as *i64 67 exps[0]=3; exps[1]=17; exps[2]=65537 68 var si: i64 = 0 69 while si < 4 { 70 var ei: i64 = 0 71 while ei < 3 { 72 total = total + 1 73 pass = pass + one_case(seeds[si], exps[ei]) 74 ei = ei + 1 75 } 76 si = si + 1 77 } 78 g_ps("rsa2048-mont gate: " as *u8, 19); g_pn(pass); g_ps("/" as *u8, 1); g_pn(total); g_ps(" match\n" as *u8, 7) 79 if pass == total { sys_exit(0); return 0 } 80 sys_exit(1) 81 return 1 82}