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}