code wiki / (root) / nx_p256_scalar_mul_test.nx

nx_p256_scalar_mul_test.nx source

↩ module page · 120 lines · 4156 B

1// nx_p256_scalar_mul_test.nx -- KAT for P-256 scalar multiplication. 2// 3// Verifies for small k values: 4// - 0 * G = O 5// - 1 * G = G 6// - 2 * G = double(G) 7// - 3 * G = G + 2G 8// - 4 * G = double(2G) = via scalar_mul(4, G) 9// - 256 * G = 8 doublings of G 10// - aliasing: out aliases p in scalar_mul 11// - 0 * O = O, k * O = O for various k 12// 13// Larger k values are exercised indirectly via the ECDSA verify 14// KAT (queued for piece 4) -- 256-bit scalars take ~2-3s each in 15// the slow form and would push smoke runtime past budget. 16// 17// expect_exit: 0 18// license_tier: ORIGINAL 19 20import "nx_syscalls.nx" 21import "nx_u256.nx" 22import "nx_p256_field.nx" 23import "nx_p256_point.nx" 24import "nx_p256_point_add.nx" 25import "nx_p256_scalar_mul.nx" 26 27func main() -> i64 { 28 let G: *P256Point = p256_point_alloc() 29 p256_point_load_g(G) 30 let O: *P256Point = p256_point_alloc() 31 p256_point_zero(O) 32 33 let k: *i64 = u256_alloc() 34 let r: *P256Point = p256_point_alloc() 35 36 // ---- Test A: 0 * G = O ---- 37 u256_zero(k) 38 p256_scalar_mul(r, k, G) 39 if p256_point_is_infinity(r) != 1 { return 1 } 40 41 // ---- Test B: 1 * G = G ---- 42 u256_zero(k); k[0] = 1 43 p256_scalar_mul(r, k, G) 44 if p256_point_eq(r, G) != 1 { return 2 } 45 46 // ---- Test C: 2 * G via scalar_mul matches double(G) ---- 47 let two_G_dbl: *P256Point = p256_point_alloc() 48 p256_point_double(two_G_dbl, G) 49 u256_zero(k); k[0] = 2 50 p256_scalar_mul(r, k, G) 51 if p256_point_eq(r, two_G_dbl) != 1 { return 3 } 52 53 // ---- Test D: 3 * G via scalar_mul matches G + 2G ---- 54 let three_G_add: *P256Point = p256_point_alloc() 55 p256_point_add(three_G_add, G, two_G_dbl) 56 u256_zero(k); k[0] = 3 57 p256_scalar_mul(r, k, G) 58 if p256_point_eq(r, three_G_add) != 1 { return 4 } 59 60 // ---- Test E: 4 * G via scalar_mul matches double(2G) ---- 61 let four_G_dbl: *P256Point = p256_point_alloc() 62 p256_point_double(four_G_dbl, two_G_dbl) 63 u256_zero(k); k[0] = 4 64 p256_scalar_mul(r, k, G) 65 if p256_point_eq(r, four_G_dbl) != 1 { return 5 } 66 67 // ---- Test F: 8 * G via scalar_mul matches double(4G) ---- 68 let eight_G_dbl: *P256Point = p256_point_alloc() 69 p256_point_double(eight_G_dbl, four_G_dbl) 70 u256_zero(k); k[0] = 8 71 p256_scalar_mul(r, k, G) 72 if p256_point_eq(r, eight_G_dbl) != 1 { return 6 } 73 74 // ---- Test G: 256 * G via scalar_mul matches 8 successive doubles ---- 75 let p2: *P256Point = p256_point_alloc() 76 p256_point_double(p2, G) // 2G 77 p256_point_double(p2, p2) // 4G 78 p256_point_double(p2, p2) // 8G 79 p256_point_double(p2, p2) // 16G 80 p256_point_double(p2, p2) // 32G 81 p256_point_double(p2, p2) // 64G 82 p256_point_double(p2, p2) // 128G 83 p256_point_double(p2, p2) // 256G 84 u256_zero(k); k[0] = 256 85 p256_scalar_mul(r, k, G) 86 if p256_point_eq(r, p2) != 1 { return 7 } 87 88 // ---- Test H: k * O = O for various k ---- 89 u256_zero(k); k[0] = 5 90 p256_scalar_mul(r, k, O) 91 if p256_point_is_infinity(r) != 1 { return 10 } 92 u256_zero(k); k[7] = 0x12345678 93 p256_scalar_mul(r, k, O) 94 if p256_point_is_infinity(r) != 1 { return 11 } 95 96 // ---- Test I: aliasing -- out aliases p ---- 97 let aliased: *P256Point = p256_point_alloc() 98 p256_point_copy(aliased, G) 99 u256_zero(k); k[0] = 3 100 p256_scalar_mul(aliased, k, aliased) // aliased := 3 * aliased 101 if p256_point_eq(aliased, three_G_add) != 1 { return 20 } 102 103 // ---- Test J: distributivity-via-add (k1+k2)*P = k1*P + k2*P 104 // for small k1, k2 ---- 105 // (k1, k2) = (3, 4) -> 7*G should equal 3G + 4G 106 u256_zero(k); k[0] = 3 107 let three_G: *P256Point = p256_point_alloc() 108 p256_scalar_mul(three_G, k, G) 109 u256_zero(k); k[0] = 4 110 let four_G: *P256Point = p256_point_alloc() 111 p256_scalar_mul(four_G, k, G) 112 let seven_G_add: *P256Point = p256_point_alloc() 113 p256_point_add(seven_G_add, three_G, four_G) 114 u256_zero(k); k[0] = 7 115 let seven_G_mul: *P256Point = p256_point_alloc() 116 p256_scalar_mul(seven_G_mul, k, G) 117 if p256_point_eq(seven_G_mul, seven_G_add) != 1 { return 30 } 118 119 return 0 120}