diff options
| author | tb <> | 2026-02-08 12:34:05 +0000 |
|---|---|---|
| committer | tb <> | 2026-02-08 12:34:05 +0000 |
| commit | dcddb3ef0e5583a374e829f3039cf629c80e71d1 (patch) | |
| tree | 8957958d40ed5a95e644ca89957105ef34f26aac | |
| parent | 50933fb9bc6bf2281489d17ee48416a43163d847 (diff) | |
| download | openbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.tar.gz openbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.tar.bz2 openbsd-dcddb3ef0e5583a374e829f3039cf629c80e71d1.zip | |
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
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 91 |
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 | |||
| 348 | static int | 338 | static int |
| 349 | ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, | 339 | ec_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 | |||
| 396 | static int | ||
| 397 | ec_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 | |||
| 412 | static int | 413 | static int |
| 413 | ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, | 414 | ec_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) |
