summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-11 14:48:20 +0000
committertb <>2025-01-11 14:48:20 +0000
commita1c7b99a47688922533665b476a7ba6b6ca0ed74 (patch)
treeac1ac642f1376fd6c880b570c8a968d54fcfe5de
parent77fd8bf0bd07c5d79462d47b742d1d2ee69dc735 (diff)
downloadopenbsd-a1c7b99a47688922533665b476a7ba6b6ca0ed74.tar.gz
openbsd-a1c7b99a47688922533665b476a7ba6b6ca0ed74.tar.bz2
openbsd-a1c7b99a47688922533665b476a7ba6b6ca0ed74.zip
Move ec_points_make_affine() to the right place
discussed with jsing
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c270
1 files changed, 135 insertions, 135 deletions
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index d1895c959f..9ee5da43e1 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.28 2025/01/11 13:58:31 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.29 2025/01/11 14:48:20 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.
@@ -374,6 +374,140 @@ ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
374} 374}
375 375
376static int 376static int
377ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points,
378 BN_CTX *ctx)
379{
380 BIGNUM **prod_Z = NULL;
381 BIGNUM *one, *tmp, *tmp_Z;
382 size_t i;
383 int ret = 0;
384
385 if (num == 0)
386 return 1;
387
388 BN_CTX_start(ctx);
389
390 if ((one = BN_CTX_get(ctx)) == NULL)
391 goto err;
392 if ((tmp = BN_CTX_get(ctx)) == NULL)
393 goto err;
394 if ((tmp_Z = BN_CTX_get(ctx)) == NULL)
395 goto err;
396
397 if (!ec_encode_scalar(group, one, BN_value_one(), ctx))
398 goto err;
399
400 if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL)
401 goto err;
402 for (i = 0; i < num; i++) {
403 if ((prod_Z[i] = BN_CTX_get(ctx)) == NULL)
404 goto err;
405 }
406
407 /*
408 * Set prod_Z[i] to the product of points[0]->Z, ..., points[i]->Z,
409 * skipping any zero-valued inputs (pretend that they're 1).
410 */
411
412 if (!BN_is_zero(points[0]->Z)) {
413 if (!bn_copy(prod_Z[0], points[0]->Z))
414 goto err;
415 } else {
416 if (!bn_copy(prod_Z[0], one))
417 goto err;
418 }
419
420 for (i = 1; i < num; i++) {
421 if (!BN_is_zero(points[i]->Z)) {
422 if (!group->meth->field_mul(group, prod_Z[i],
423 prod_Z[i - 1], points[i]->Z, ctx))
424 goto err;
425 } else {
426 if (!bn_copy(prod_Z[i], prod_Z[i - 1]))
427 goto err;
428 }
429 }
430
431 /*
432 * Now use a single explicit inversion to replace every non-zero
433 * points[i]->Z by its inverse.
434 */
435 if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) {
436 ECerror(ERR_R_BN_LIB);
437 goto err;
438 }
439
440 if (group->meth->field_encode != NULL) {
441 /*
442 * In the Montgomery case we just turned R*H (representing H)
443 * into 1/(R*H), but we need R*(1/H) (representing 1/H); i.e.,
444 * we need to multiply by the Montgomery factor twice.
445 */
446 if (!group->meth->field_encode(group, tmp, tmp, ctx))
447 goto err;
448 if (!group->meth->field_encode(group, tmp, tmp, ctx))
449 goto err;
450 }
451
452 for (i = num - 1; i > 0; i--) {
453 /*
454 * Loop invariant: tmp is the product of the inverses of
455 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped).
456 */
457 if (BN_is_zero(points[i]->Z))
458 continue;
459
460 /* Set tmp_Z to the inverse of points[i]->Z. */
461 if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
462 goto err;
463 /* Adjust tmp to satisfy loop invariant. */
464 if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
465 goto err;
466 /* Replace points[i]->Z by its inverse. */
467 if (!bn_copy(points[i]->Z, tmp_Z))
468 goto err;
469 }
470
471 if (!BN_is_zero(points[0]->Z)) {
472 /* Replace points[0]->Z by its inverse. */
473 if (!bn_copy(points[0]->Z, tmp))
474 goto err;
475 }
476
477 /* Finally, fix up the X and Y coordinates for all points. */
478 for (i = 0; i < num; i++) {
479 EC_POINT *p = points[i];
480
481 if (BN_is_zero(p->Z))
482 continue;
483
484 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
485
486 if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
487 goto err;
488 if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
489 goto err;
490
491 if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
492 goto err;
493 if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
494 goto err;
495
496 if (!bn_copy(p->Z, one))
497 goto err;
498 p->Z_is_one = 1;
499 }
500
501 ret = 1;
502
503 err:
504 BN_CTX_end(ctx);
505 free(prod_Z);
506
507 return ret;
508}
509
510static int
377ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, 511ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b,
378 BN_CTX *ctx) 512 BN_CTX *ctx)
379{ 513{
@@ -892,140 +1026,6 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
892} 1026}
893 1027
894static int 1028static int
895ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT **points,
896 BN_CTX *ctx)
897{
898 BIGNUM **prod_Z = NULL;
899 BIGNUM *one, *tmp, *tmp_Z;
900 size_t i;
901 int ret = 0;
902
903 if (num == 0)
904 return 1;
905
906 BN_CTX_start(ctx);
907
908 if ((one = BN_CTX_get(ctx)) == NULL)
909 goto err;
910 if ((tmp = BN_CTX_get(ctx)) == NULL)
911 goto err;
912 if ((tmp_Z = BN_CTX_get(ctx)) == NULL)
913 goto err;
914
915 if (!ec_encode_scalar(group, one, BN_value_one(), ctx))
916 goto err;
917
918 if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL)
919 goto err;
920 for (i = 0; i < num; i++) {
921 if ((prod_Z[i] = BN_CTX_get(ctx)) == NULL)
922 goto err;
923 }
924
925 /*
926 * Set prod_Z[i] to the product of points[0]->Z, ..., points[i]->Z,
927 * skipping any zero-valued inputs (pretend that they're 1).
928 */
929
930 if (!BN_is_zero(points[0]->Z)) {
931 if (!bn_copy(prod_Z[0], points[0]->Z))
932 goto err;
933 } else {
934 if (!bn_copy(prod_Z[0], one))
935 goto err;
936 }
937
938 for (i = 1; i < num; i++) {
939 if (!BN_is_zero(points[i]->Z)) {
940 if (!group->meth->field_mul(group, prod_Z[i],
941 prod_Z[i - 1], points[i]->Z, ctx))
942 goto err;
943 } else {
944 if (!bn_copy(prod_Z[i], prod_Z[i - 1]))
945 goto err;
946 }
947 }
948
949 /*
950 * Now use a single explicit inversion to replace every non-zero
951 * points[i]->Z by its inverse.
952 */
953 if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) {
954 ECerror(ERR_R_BN_LIB);
955 goto err;
956 }
957
958 if (group->meth->field_encode != NULL) {
959 /*
960 * In the Montgomery case we just turned R*H (representing H)
961 * into 1/(R*H), but we need R*(1/H) (representing 1/H); i.e.,
962 * we need to multiply by the Montgomery factor twice.
963 */
964 if (!group->meth->field_encode(group, tmp, tmp, ctx))
965 goto err;
966 if (!group->meth->field_encode(group, tmp, tmp, ctx))
967 goto err;
968 }
969
970 for (i = num - 1; i > 0; i--) {
971 /*
972 * Loop invariant: tmp is the product of the inverses of
973 * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped).
974 */
975 if (BN_is_zero(points[i]->Z))
976 continue;
977
978 /* Set tmp_Z to the inverse of points[i]->Z. */
979 if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
980 goto err;
981 /* Adjust tmp to satisfy loop invariant. */
982 if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
983 goto err;
984 /* Replace points[i]->Z by its inverse. */
985 if (!bn_copy(points[i]->Z, tmp_Z))
986 goto err;
987 }
988
989 if (!BN_is_zero(points[0]->Z)) {
990 /* Replace points[0]->Z by its inverse. */
991 if (!bn_copy(points[0]->Z, tmp))
992 goto err;
993 }
994
995 /* Finally, fix up the X and Y coordinates for all points. */
996 for (i = 0; i < num; i++) {
997 EC_POINT *p = points[i];
998
999 if (BN_is_zero(p->Z))
1000 continue;
1001
1002 /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
1003
1004 if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
1005 goto err;
1006 if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
1007 goto err;
1008
1009 if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
1010 goto err;
1011 if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
1012 goto err;
1013
1014 if (!bn_copy(p->Z, one))
1015 goto err;
1016 p->Z_is_one = 1;
1017 }
1018
1019 ret = 1;
1020
1021 err:
1022 BN_CTX_end(ctx);
1023 free(prod_Z);
1024
1025 return ret;
1026}
1027
1028static int
1029ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 1029ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
1030 BN_CTX *ctx) 1030 BN_CTX *ctx)
1031{ 1031{