summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2026-01-18 10:07:44 +0000
committertb <>2026-01-18 10:07:44 +0000
commit72cdd91797afb2b9796ee9f67324a53c5fc6effe (patch)
treef3f6f0ecbb333284d99cb208078cbef547f20cc2
parent8c2e30618ba07e5c076d4f6492f61fe7dea05412 (diff)
downloadopenbsd-72cdd91797afb2b9796ee9f67324a53c5fc6effe.tar.gz
openbsd-72cdd91797afb2b9796ee9f67324a53c5fc6effe.tar.bz2
openbsd-72cdd91797afb2b9796ee9f67324a53c5fc6effe.zip
Rewrite ec_point_cmp()HEADmaster
This removes some complications due to handling the fast path for affine points and general points at the same time. The result is a bit more code but both paths should be much easier to follow. ok jsing kenjiro
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c156
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
291static int
292ec_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
290ec_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 349ec_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;