code wiki / (root) / nx_p384_field_mul_fast_gate.nx

nx_p384_field_mul_fast_gate.nx source

↩ module page · 75 lines · 2646 B

1// nx_p384_field_mul_fast_gate.nx -- pin p384_field_mul_fast: it MUST equal the 2// trusted bit-by-bit p384_field_mul for the same a*b mod p, across edge + random 3// inputs, before it replaces the slow path in ECDSA-P384 cert verification. 4// 5// expect_exit: 0 6 7import "nx_syscalls.nx" 8import "nx_u384.nx" 9import "nx_u384_mul.nx" 10import "nx_p384_field.nx" 11import "nx_p384_field_mul.nx" 12import "nx_p384_field_mul_fast.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// pseudo-random 12-word value (full 384-bit range incl. top word). 27func mk(x: *i64, seed: i64) -> i64 { 28 var i: i64 = 0 29 while i < NX_U384_LIMBS { 30 x[i] = ((seed + i * 2654435761) * 1103515245 + 12345) & NX_U384_LIMB_MASK 31 i = i + 1 32 } 33 return 0 34} 35 36func cmp_case(a: *i64, b: *i64, tag: i64) -> i64 { 37 let r1: *i64 = u384_alloc() 38 let r2: *i64 = u384_alloc() 39 p384_field_mul_bitwise(r1, a, b) // bit-by-bit reference 40 p384_field_mul_fast(r2, a, b) // fast fold 41 if u384_eq(r1, r2) == 1 { return 1 } 42 g_ps(" MISMATCH tag=" as *u8, 13); g_pn(tag); g_ps("\n" as *u8, 1) 43 return 0 44} 45 46func main() -> i64 { 47 var pass: i64 = 0 48 var total: i64 = 0 49 let a: *i64 = u384_alloc() 50 let b: *i64 = u384_alloc() 51 let p: *i64 = u384_alloc() 52 p384_field_load_p(p) 53 54 // edge cases 55 u384_zero(a); u384_zero(b); total = total + 1; pass = pass + cmp_case(a, b, 1) // 0*0 56 u384_one(a); u384_copy(b, p); b[0] = (b[0] - 1) & NX_U384_LIMB_MASK 57 total = total + 1; pass = pass + cmp_case(a, b, 2) // 1*(p-1) 58 u384_copy(a, p); a[0] = (a[0] - 1) & NX_U384_LIMB_MASK; u384_copy(b, a) 59 total = total + 1; pass = pass + cmp_case(a, b, 3) // (p-1)^2 60 61 // random cases (full-range a,b) 62 var s: i64 = 1 63 while s <= 24 { 64 mk(a, s); mk(b, s * 7 + 3) 65 total = total + 1; pass = pass + cmp_case(a, b, 100 + s) 66 mk(a, s * 131 + 5) 67 total = total + 1; pass = pass + cmp_case(a, a, 200 + s) // square 68 s = s + 1 69 } 70 71 g_ps("p384-field-mul-fast gate: " as *u8, 26); g_pn(pass); g_ps("/" as *u8, 1); g_pn(total); g_ps(" match\n" as *u8, 7) 72 if pass == total { sys_exit(0); return 0 } 73 sys_exit(1) 74 return 1 75}