code wiki / (root) / nx_p256_point_add_test.nx

nx_p256_point_add_test.nx source

↩ module page · 121 lines · 4502 B

1// nx_p256_point_add_test.nx -- KAT for P-256 Jacobian point addition. 2// 3// Verifies: 4// - G + O = G (infinity identity) 5// - O + G = G (commutative identity) 6// - O + O = O (infinity-only) 7// - G + G = 2G (matches point_double(G)) 8// - G + (-G) = O (additive inverse) 9// - G + 2G is on curve, != G, != 2G, != O 10// - (G + 2G) + G = 4G (cross-check: 4G also = double(2G)) 11// - 2G + G = G + 2G (commutativity) 12// - (G + 2G) + G = G + (2G + G) (associativity spot-check) 13// - aliasing: out aliases p1, out aliases p2, all aliases 14// 15// expect_exit: 0 16// license_tier: ORIGINAL 17 18import "nx_syscalls.nx" 19import "nx_u256.nx" 20import "nx_p256_field.nx" 21import "nx_p256_field_mul.nx" 22import "nx_p256_point.nx" 23import "nx_p256_point_add.nx" 24 25func main() -> i64 { 26 let G: *P256Point = p256_point_alloc() 27 p256_point_load_g(G) 28 let O: *P256Point = p256_point_alloc() 29 p256_point_zero(O) 30 31 // ---- Test A: G + O = G ---- 32 let r: *P256Point = p256_point_alloc() 33 p256_point_add(r, G, O) 34 if p256_point_eq(r, G) != 1 { return 1 } 35 36 // ---- Test B: O + G = G ---- 37 p256_point_add(r, O, G) 38 if p256_point_eq(r, G) != 1 { return 2 } 39 40 // ---- Test C: O + O = O ---- 41 p256_point_add(r, O, O) 42 if p256_point_is_infinity(r) != 1 { return 3 } 43 44 // ---- Test D: G + G = 2G (matches double) ---- 45 let two_G_dbl: *P256Point = p256_point_alloc() 46 p256_point_double(two_G_dbl, G) 47 let two_G_add: *P256Point = p256_point_alloc() 48 p256_point_add(two_G_add, G, G) 49 if p256_point_eq(two_G_add, two_G_dbl) != 1 { return 4 } 50 51 // ---- Test E: G + (-G) = O ---- 52 // -G has same x, y_neg = p - Gy. 53 let neg_G: *P256Point = p256_point_alloc() 54 let neg_Gy: *i64 = u256_alloc() 55 p256_field_neg(neg_Gy, G.y) 56 p256_point_set_affine(neg_G, G.x, neg_Gy) 57 p256_point_add(r, G, neg_G) 58 if p256_point_is_infinity(r) != 1 { return 5 } 59 60 // ---- Test F: G + 2G = 3G is on curve, != G, != 2G, != O ---- 61 let three_G: *P256Point = p256_point_alloc() 62 p256_point_add(three_G, G, two_G_add) 63 if p256_point_is_infinity(three_G) == 1 { return 6 } 64 p256_point_to_affine(three_G) 65 if p256_point_on_curve(three_G) != 1 { return 7 } 66 if p256_point_eq(three_G, G) == 1 { return 8 } 67 if p256_point_eq(three_G, two_G_add) == 1 { return 9 } 68 69 // ---- Test G: 4G via two paths ---- 70 // path 1: double(2G) 71 let four_G_dbl: *P256Point = p256_point_alloc() 72 p256_point_double(four_G_dbl, two_G_add) 73 // path 2: (G + 2G) + G = 3G + G 74 let four_G_add: *P256Point = p256_point_alloc() 75 p256_point_add(four_G_add, three_G, G) 76 if p256_point_eq(four_G_add, four_G_dbl) != 1 { return 10 } 77 78 // ---- Test H: commutativity 2G + G = G + 2G ---- 79 let comm1: *P256Point = p256_point_alloc() 80 let comm2: *P256Point = p256_point_alloc() 81 p256_point_add(comm1, two_G_add, G) 82 p256_point_add(comm2, G, two_G_add) 83 if p256_point_eq(comm1, comm2) != 1 { return 11 } 84 85 // ---- Test I: associativity (G + 2G) + G == G + (2G + G) ---- 86 let assoc1: *P256Point = p256_point_alloc() 87 let assoc2: *P256Point = p256_point_alloc() 88 let g_plus_2g: *P256Point = p256_point_alloc() 89 p256_point_add(g_plus_2g, G, two_G_add) 90 p256_point_add(assoc1, g_plus_2g, G) // (G + 2G) + G 91 let two_g_plus_g: *P256Point = p256_point_alloc() 92 p256_point_add(two_g_plus_g, two_G_add, G) 93 p256_point_add(assoc2, G, two_g_plus_g) // G + (2G + G) 94 if p256_point_eq(assoc1, assoc2) != 1 { return 12 } 95 96 // ---- Test J: aliasing -- out aliases p1 ---- 97 let p: *P256Point = p256_point_alloc() 98 let q: *P256Point = p256_point_alloc() 99 p256_point_copy(p, G) 100 p256_point_copy(q, two_G_add) 101 p256_point_add(p, p, q) // p := p + q 102 if p256_point_eq(p, three_G) != 1 { return 13 } 103 104 // ---- Test K: aliasing -- out aliases p2 ---- 105 p256_point_copy(p, G) 106 p256_point_copy(q, two_G_add) 107 p256_point_add(q, p, q) // q := p + q 108 if p256_point_eq(q, three_G) != 1 { return 14 } 109 110 // ---- Test L: 8G via 4G + 4G ---- 111 let eight_G: *P256Point = p256_point_alloc() 112 p256_point_add(eight_G, four_G_dbl, four_G_dbl) 113 p256_point_to_affine(eight_G) 114 if p256_point_on_curve(eight_G) != 1 { return 15 } 115 // Cross-check: 8G via double(double(2G)) 116 let eight_G_dbl: *P256Point = p256_point_alloc() 117 p256_point_double(eight_G_dbl, four_G_dbl) 118 if p256_point_eq(eight_G, eight_G_dbl) != 1 { return 16 } 119 120 return 0 121}