diff options
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 156 |
1 files changed, 97 insertions, 59 deletions
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c index fcb48d9e33..8fa78924d2 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.47 2025/05/24 08:25:58 jsing Exp $ */ | 1 | /* $OpenBSD: ecp_methods.c,v 1.48 2026/01/18 10:07:44 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. |
| @@ -283,6 +283,65 @@ ec_point_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | /* | 285 | /* |
| 286 | * Compare a and b under the assumption that exactly one of them is affine. | ||
| 287 | * This avoids needless multiplications by one, which are expensive in the | ||
| 288 | * Montgomery domain. | ||
| 289 | */ | ||
| 290 | |||
| 291 | static int | ||
| 292 | ec_point_cmp_one_affine(const EC_GROUP *group, const EC_POINT *a, | ||
| 293 | const EC_POINT *b, BN_CTX *ctx) | ||
| 294 | { | ||
| 295 | const EC_POINT *tmp; | ||
| 296 | BIGNUM *az, *bn; | ||
| 297 | int ret = -1; | ||
| 298 | |||
| 299 | BN_CTX_start(ctx); | ||
| 300 | |||
| 301 | if (a->Z_is_one == b->Z_is_one) | ||
| 302 | goto err; | ||
| 303 | |||
| 304 | /* Ensure b is the affine point. */ | ||
| 305 | if (a->Z_is_one) { | ||
| 306 | tmp = a; | ||
| 307 | a = b; | ||
| 308 | b = tmp; | ||
| 309 | } | ||
| 310 | |||
| 311 | if ((az = BN_CTX_get(ctx)) == NULL) | ||
| 312 | goto err; | ||
| 313 | if ((bn = BN_CTX_get(ctx)) == NULL) | ||
| 314 | goto err; | ||
| 315 | |||
| 316 | /* a->X == b->X * a->Z^2 ? */ | ||
| 317 | if (!ec_field_sqr(group, az, a->Z, ctx)) | ||
| 318 | goto err; | ||
| 319 | if (!ec_field_mul(group, bn, b->X, az, ctx)) | ||
| 320 | goto err; | ||
| 321 | if (BN_cmp(a->X, bn) != 0) { | ||
| 322 | ret = 1; | ||
| 323 | goto err; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* a->Y == b->Y * a->Z^3 ? */ | ||
| 327 | if (!ec_field_mul(group, az, az, a->Z, ctx)) | ||
| 328 | goto err; | ||
| 329 | if (!ec_field_mul(group, bn, b->Y, az, ctx)) | ||
| 330 | goto err; | ||
| 331 | if (BN_cmp(a->Y, bn) != 0) { | ||
| 332 | ret = 1; | ||
| 333 | goto err; | ||
| 334 | } | ||
| 335 | |||
| 336 | ret = 0; | ||
| 337 | |||
| 338 | err: | ||
| 339 | BN_CTX_end(ctx); | ||
| 340 | |||
| 341 | return ret; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 286 | * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct. | 345 | * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct. |
| 287 | */ | 346 | */ |
| 288 | 347 | ||
| @@ -290,8 +349,7 @@ static int | |||
| 290 | ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, | 349 | ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, |
| 291 | BN_CTX *ctx) | 350 | BN_CTX *ctx) |
| 292 | { | 351 | { |
| 293 | BIGNUM *tmp1, *tmp2, *Za23, *Zb23; | 352 | BIGNUM *az, *bz, *bn1, *bn2; |
| 294 | const BIGNUM *tmp1_, *tmp2_; | ||
| 295 | int ret = -1; | 353 | int ret = -1; |
| 296 | 354 | ||
| 297 | if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b)) | 355 | if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b)) |
| @@ -301,71 +359,51 @@ ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, | |||
| 301 | 359 | ||
| 302 | if (a->Z_is_one && b->Z_is_one) | 360 | if (a->Z_is_one && b->Z_is_one) |
| 303 | return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0; | 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) | ||
| 363 | return ec_point_cmp_one_affine(group, a, b, ctx); | ||
| 304 | 364 | ||
| 305 | BN_CTX_start(ctx); | 365 | BN_CTX_start(ctx); |
| 306 | 366 | ||
| 307 | if ((tmp1 = BN_CTX_get(ctx)) == NULL) | 367 | if ((az = BN_CTX_get(ctx)) == NULL) |
| 308 | goto end; | 368 | goto err; |
| 309 | if ((tmp2 = BN_CTX_get(ctx)) == NULL) | 369 | if ((bz = BN_CTX_get(ctx)) == NULL) |
| 310 | goto end; | 370 | goto err; |
| 311 | if ((Za23 = BN_CTX_get(ctx)) == NULL) | 371 | if ((bn1 = BN_CTX_get(ctx)) == NULL) |
| 312 | goto end; | 372 | goto err; |
| 313 | if ((Zb23 = BN_CTX_get(ctx)) == NULL) | 373 | if ((bn2 = BN_CTX_get(ctx)) == NULL) |
| 314 | goto end; | 374 | goto err; |
| 315 | |||
| 316 | /* | ||
| 317 | * Decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), or | ||
| 318 | * equivalently, (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). | ||
| 319 | */ | ||
| 320 | |||
| 321 | if (!b->Z_is_one) { | ||
| 322 | if (!ec_field_sqr(group, Zb23, b->Z, ctx)) | ||
| 323 | goto end; | ||
| 324 | if (!ec_field_mul(group, tmp1, a->X, Zb23, ctx)) | ||
| 325 | goto end; | ||
| 326 | tmp1_ = tmp1; | ||
| 327 | } else | ||
| 328 | tmp1_ = a->X; | ||
| 329 | if (!a->Z_is_one) { | ||
| 330 | if (!ec_field_sqr(group, Za23, a->Z, ctx)) | ||
| 331 | goto end; | ||
| 332 | if (!ec_field_mul(group, tmp2, b->X, Za23, ctx)) | ||
| 333 | goto end; | ||
| 334 | tmp2_ = tmp2; | ||
| 335 | } else | ||
| 336 | tmp2_ = b->X; | ||
| 337 | 375 | ||
| 338 | /* compare X_a*Z_b^2 with X_b*Z_a^2 */ | 376 | /* a->X * b->Z^2 == b->X * a->Z^2 ? */ |
| 339 | if (BN_cmp(tmp1_, tmp2_) != 0) { | 377 | if (!ec_field_sqr(group, bz, b->Z, ctx)) |
| 340 | ret = 1; /* points differ */ | 378 | goto err; |
| 341 | goto end; | 379 | if (!ec_field_mul(group, bn1, a->X, bz, ctx)) |
| 380 | goto err; | ||
| 381 | if (!ec_field_sqr(group, az, a->Z, ctx)) | ||
| 382 | goto err; | ||
| 383 | if (!ec_field_mul(group, bn2, b->X, az, ctx)) | ||
| 384 | goto err; | ||
| 385 | if (BN_cmp(bn1, bn2) != 0) { | ||
| 386 | ret = 1; | ||
| 387 | goto err; | ||
| 342 | } | 388 | } |
| 343 | if (!b->Z_is_one) { | ||
| 344 | if (!ec_field_mul(group, Zb23, Zb23, b->Z, ctx)) | ||
| 345 | goto end; | ||
| 346 | if (!ec_field_mul(group, tmp1, a->Y, Zb23, ctx)) | ||
| 347 | goto end; | ||
| 348 | /* tmp1_ = tmp1 */ | ||
| 349 | } else | ||
| 350 | tmp1_ = a->Y; | ||
| 351 | if (!a->Z_is_one) { | ||
| 352 | if (!ec_field_mul(group, Za23, Za23, a->Z, ctx)) | ||
| 353 | goto end; | ||
| 354 | if (!ec_field_mul(group, tmp2, b->Y, Za23, ctx)) | ||
| 355 | goto end; | ||
| 356 | /* tmp2_ = tmp2 */ | ||
| 357 | } else | ||
| 358 | tmp2_ = b->Y; | ||
| 359 | 389 | ||
| 360 | /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ | 390 | /* a->Y * b->Z^3 == b->Y * a->Z^3 ? */ |
| 361 | if (BN_cmp(tmp1_, tmp2_) != 0) { | 391 | if (!ec_field_mul(group, bz, bz, b->Z, ctx)) |
| 362 | ret = 1; /* points differ */ | 392 | goto err; |
| 363 | goto end; | 393 | if (!ec_field_mul(group, bn1, a->Y, bz, ctx)) |
| 394 | goto err; | ||
| 395 | if (!ec_field_mul(group, az, az, a->Z, ctx)) | ||
| 396 | goto err; | ||
| 397 | if (!ec_field_mul(group, bn2, b->Y, az, ctx)) | ||
| 398 | goto err; | ||
| 399 | if (BN_cmp(bn1, bn2) != 0) { | ||
| 400 | ret = 1; | ||
| 401 | goto err; | ||
| 364 | } | 402 | } |
| 365 | /* points are equal */ | 403 | |
| 366 | ret = 0; | 404 | ret = 0; |
| 367 | 405 | ||
| 368 | end: | 406 | err: |
| 369 | BN_CTX_end(ctx); | 407 | BN_CTX_end(ctx); |
| 370 | 408 | ||
| 371 | return ret; | 409 | return ret; |
