@@ -1146,11 +1146,79 @@ void test_ge(void) {
1146
1146
free (zinv );
1147
1147
}
1148
1148
1149
+ void test_add_neg_y_diff_x (void ) {
1150
+ /* The point of this test is to check that we can add two points
1151
+ * whose y-coordinates are negatives of each other but whose x
1152
+ * coordinates differ. If the x-coordinates were the same, these
1153
+ * points would be negatives of each other and their sum is
1154
+ * infinity. This is cool because it "covers up" any degeneracy
1155
+ * in the addition algorithm that would cause the xy coordinates
1156
+ * of the sum to be wrong (since infinity has no xy coordinates).
1157
+ * HOWEVER, if the x-coordinates are different, infinity is the
1158
+ * wrong answer, and such degeneracies are exposed. This is the
1159
+ * root of https://github.com/bitcoin/secp256k1/issues/257 which
1160
+ * this test is a regression test for.
1161
+ *
1162
+ * These points were generated in sage as
1163
+ * # secp256k1 params
1164
+ * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
1165
+ * C = EllipticCurve ([F (0), F (7)])
1166
+ * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
1167
+ * N = FiniteField(G.order())
1168
+ *
1169
+ * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F)
1170
+ * x = polygen(N)
1171
+ * lam = (1 - x^3).roots()[1][0]
1172
+ *
1173
+ * # random "bad pair"
1174
+ * P = C.random_element()
1175
+ * Q = -int(lam) * P
1176
+ * print " P: %x %x" % P.xy()
1177
+ * print " Q: %x %x" % Q.xy()
1178
+ * print "P + Q: %x %x" % (P + Q).xy()
1179
+ */
1180
+ secp256k1_gej_t aj = SECP256K1_GEJ_CONST (
1181
+ 0x8d24cd95 , 0x0a355af1 , 0x3c543505 , 0x44238d30 ,
1182
+ 0x0643d79f , 0x05a59614 , 0x2f8ec030 , 0xd58977cb ,
1183
+ 0x001e337a , 0x38093dcd , 0x6c0f386d , 0x0b1293a8 ,
1184
+ 0x4d72c879 , 0xd7681924 , 0x44e6d2f3 , 0x9190117d
1185
+ );
1186
+ secp256k1_gej_t bj = SECP256K1_GEJ_CONST (
1187
+ 0xc7b74206 , 0x1f788cd9 , 0xabd0937d , 0x164a0d86 ,
1188
+ 0x95f6ff75 , 0xf19a4ce9 , 0xd013bd7b , 0xbf92d2a7 ,
1189
+ 0xffe1cc85 , 0xc7f6c232 , 0x93f0c792 , 0xf4ed6c57 ,
1190
+ 0xb28d3786 , 0x2897e6db , 0xbb192d0b , 0x6e6feab2
1191
+ );
1192
+ secp256k1_gej_t sumj = SECP256K1_GEJ_CONST (
1193
+ 0x671a63c0 , 0x3efdad4c , 0x389a7798 , 0x24356027 ,
1194
+ 0xb3d69010 , 0x278625c3 , 0x5c86d390 , 0x184a8f7a ,
1195
+ 0x5f6409c2 , 0x2ce01f2b , 0x511fd375 , 0x25071d08 ,
1196
+ 0xda651801 , 0x70e95caf , 0x8f0d893c , 0xbed8fbbe
1197
+ );
1198
+ secp256k1_ge_t b ;
1199
+ secp256k1_gej_t resj ;
1200
+ secp256k1_ge_t res ;
1201
+ secp256k1_ge_set_gej (& b , & bj );
1202
+
1203
+ secp256k1_gej_add_var (& resj , & aj , & bj , NULL );
1204
+ secp256k1_ge_set_gej (& res , & resj );
1205
+ ge_equals_gej (& res , & sumj );
1206
+
1207
+ secp256k1_gej_add_ge (& resj , & aj , & b );
1208
+ secp256k1_ge_set_gej (& res , & resj );
1209
+ ge_equals_gej (& res , & sumj );
1210
+
1211
+ secp256k1_gej_add_ge_var (& resj , & aj , & b , NULL );
1212
+ secp256k1_ge_set_gej (& res , & resj );
1213
+ ge_equals_gej (& res , & sumj );
1214
+ }
1215
+
1149
1216
void run_ge (void ) {
1150
1217
int i ;
1151
1218
for (i = 0 ; i < count * 32 ; i ++ ) {
1152
1219
test_ge ();
1153
1220
}
1221
+ test_add_neg_y_diff_x ();
1154
1222
}
1155
1223
1156
1224
/***** ECMULT TESTS *****/
0 commit comments