summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2026-02-08 12:34:05 +0000
committertb <>2026-02-08 12:34:05 +0000
commitdcddb3ef0e5583a374e829f3039cf629c80e71d1 (patch)
tree8957958d40ed5a95e644ca89957105ef34f26aac /src
parent50933fb9bc6bf2281489d17ee48416a43163d847 (diff)
downloadopenbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.tar.gz
openbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.tar.bz2
openbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.zip
More ec_point_cmp() turd polishingHEADmaster
jsing prefers doing all computations first and comparing at the end. This means we do more work when we fail and no longer (ab)use err as an out label. Also split out one more helper. ok jsing
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c91
1 files changed, 46 insertions, 45 deletions
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 8fa78924d2..aefef28917 100644
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ b/src/lib/libcrypto/ec/ecp_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_methods.c,v 1.48 2026/01/18 10:07:44 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.49 2026/02/08 12:34:05 tb Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
@@ -293,7 +293,7 @@ ec_point_cmp_one_affine(const EC_GROUP *group, const EC_POINT *a,
293 const EC_POINT *b, BN_CTX *ctx) 293 const EC_POINT *b, BN_CTX *ctx)
294{ 294{
295 const EC_POINT *tmp; 295 const EC_POINT *tmp;
296 BIGNUM *az, *bn; 296 BIGNUM *az, *bxaz2, *byaz3;
297 int ret = -1; 297 int ret = -1;
298 298
299 BN_CTX_start(ctx); 299 BN_CTX_start(ctx);
@@ -310,30 +310,24 @@ ec_point_cmp_one_affine(const EC_GROUP *group, const EC_POINT *a,
310 310
311 if ((az = BN_CTX_get(ctx)) == NULL) 311 if ((az = BN_CTX_get(ctx)) == NULL)
312 goto err; 312 goto err;
313 if ((bn = BN_CTX_get(ctx)) == NULL) 313 if ((bxaz2 = BN_CTX_get(ctx)) == NULL)
314 goto err;
315 if ((byaz3 = BN_CTX_get(ctx)) == NULL)
314 goto err; 316 goto err;
315 317
316 /* a->X == b->X * a->Z^2 ? */ 318 /* a->X == b->X * a->Z^2 ? */
317 if (!ec_field_sqr(group, az, a->Z, ctx)) 319 if (!ec_field_sqr(group, az, a->Z, ctx))
318 goto err; 320 goto err;
319 if (!ec_field_mul(group, bn, b->X, az, ctx)) 321 if (!ec_field_mul(group, bxaz2, b->X, az, ctx))
320 goto err;
321 if (BN_cmp(a->X, bn) != 0) {
322 ret = 1;
323 goto err; 322 goto err;
324 }
325 323
326 /* a->Y == b->Y * a->Z^3 ? */ 324 /* a->Y == b->Y * a->Z^3 ? */
327 if (!ec_field_mul(group, az, az, a->Z, ctx)) 325 if (!ec_field_mul(group, az, az, a->Z, ctx))
328 goto err; 326 goto err;
329 if (!ec_field_mul(group, bn, b->Y, az, ctx)) 327 if (!ec_field_mul(group, byaz3, b->Y, az, ctx))
330 goto err;
331 if (BN_cmp(a->Y, bn) != 0) {
332 ret = 1;
333 goto err; 328 goto err;
334 }
335 329
336 ret = 0; 330 ret = BN_cmp(a->X, bxaz2) != 0 || BN_cmp(a->Y, byaz3) != 0;
337 331
338 err: 332 err:
339 BN_CTX_end(ctx); 333 BN_CTX_end(ctx);
@@ -341,67 +335,53 @@ ec_point_cmp_one_affine(const EC_GROUP *group, const EC_POINT *a,
341 return ret; 335 return ret;
342} 336}
343 337
344/*
345 * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
346 */
347
348static int 338static int
349ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 339ec_point_cmp_none_affine(const EC_GROUP *group, const EC_POINT *a,
350 BN_CTX *ctx) 340 const EC_POINT *b, BN_CTX *ctx)
351{ 341{
352 BIGNUM *az, *bz, *bn1, *bn2; 342 BIGNUM *az, *bz, *axbz2, *aybz3, *bxaz2, *byaz3;
353 int ret = -1; 343 int ret = -1;
354 344
355 if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b)) 345 BN_CTX_start(ctx);
356 return 0;
357 if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
358 return 1;
359 346
360 if (a->Z_is_one && b->Z_is_one) 347 /* The computation below works, but we should have taken a fast path. */
361 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
362 if (a->Z_is_one || b->Z_is_one) 348 if (a->Z_is_one || b->Z_is_one)
363 return ec_point_cmp_one_affine(group, a, b, ctx); 349 goto err;
364
365 BN_CTX_start(ctx);
366 350
367 if ((az = BN_CTX_get(ctx)) == NULL) 351 if ((az = BN_CTX_get(ctx)) == NULL)
368 goto err; 352 goto err;
369 if ((bz = BN_CTX_get(ctx)) == NULL) 353 if ((bz = BN_CTX_get(ctx)) == NULL)
370 goto err; 354 goto err;
371 if ((bn1 = BN_CTX_get(ctx)) == NULL) 355 if ((axbz2 = BN_CTX_get(ctx)) == NULL)
356 goto err;
357 if ((aybz3 = BN_CTX_get(ctx)) == NULL)
358 goto err;
359 if ((bxaz2 = BN_CTX_get(ctx)) == NULL)
372 goto err; 360 goto err;
373 if ((bn2 = BN_CTX_get(ctx)) == NULL) 361 if ((byaz3 = BN_CTX_get(ctx)) == NULL)
374 goto err; 362 goto err;
375 363
376 /* a->X * b->Z^2 == b->X * a->Z^2 ? */ 364 /* a->X * b->Z^2 == b->X * a->Z^2 ? */
377 if (!ec_field_sqr(group, bz, b->Z, ctx)) 365 if (!ec_field_sqr(group, bz, b->Z, ctx))
378 goto err; 366 goto err;
379 if (!ec_field_mul(group, bn1, a->X, bz, ctx)) 367 if (!ec_field_mul(group, axbz2, a->X, bz, ctx))
380 goto err; 368 goto err;
381 if (!ec_field_sqr(group, az, a->Z, ctx)) 369 if (!ec_field_sqr(group, az, a->Z, ctx))
382 goto err; 370 goto err;
383 if (!ec_field_mul(group, bn2, b->X, az, ctx)) 371 if (!ec_field_mul(group, bxaz2, b->X, az, ctx))
384 goto err; 372 goto err;
385 if (BN_cmp(bn1, bn2) != 0) {
386 ret = 1;
387 goto err;
388 }
389 373
390 /* a->Y * b->Z^3 == b->Y * a->Z^3 ? */ 374 /* a->Y * b->Z^3 == b->Y * a->Z^3 ? */
391 if (!ec_field_mul(group, bz, bz, b->Z, ctx)) 375 if (!ec_field_mul(group, bz, bz, b->Z, ctx))
392 goto err; 376 goto err;
393 if (!ec_field_mul(group, bn1, a->Y, bz, ctx)) 377 if (!ec_field_mul(group, aybz3, a->Y, bz, ctx))
394 goto err; 378 goto err;
395 if (!ec_field_mul(group, az, az, a->Z, ctx)) 379 if (!ec_field_mul(group, az, az, a->Z, ctx))
396 goto err; 380 goto err;
397 if (!ec_field_mul(group, bn2, b->Y, az, ctx)) 381 if (!ec_field_mul(group, byaz3, b->Y, az, ctx))
398 goto err;
399 if (BN_cmp(bn1, bn2) != 0) {
400 ret = 1;
401 goto err; 382 goto err;
402 }
403 383
404 ret = 0; 384 ret = BN_cmp(axbz2, bxaz2) != 0 || BN_cmp(aybz3, byaz3) != 0;
405 385
406 err: 386 err:
407 BN_CTX_end(ctx); 387 BN_CTX_end(ctx);
@@ -409,6 +389,27 @@ ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
409 return ret; 389 return ret;
410} 390}
411 391
392/*
393 * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
394 */
395
396static int
397ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
398 BN_CTX *ctx)
399{
400 if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b))
401 return 0;
402 if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
403 return 1;
404
405 if (a->Z_is_one && b->Z_is_one)
406 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
407 if (a->Z_is_one || b->Z_is_one)
408 return ec_point_cmp_one_affine(group, a, b, ctx);
409
410 return ec_point_cmp_none_affine(group, a, b, ctx);
411}
412
412static int 413static int
413ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 414ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
414 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 415 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)