summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-06 11:59:02 +0000
committertb <>2025-01-06 11:59:02 +0000
commit52f13317baa428db8efa6305c98bcca1c8d6b93e (patch)
tree0ee2fc6379d14a64692dcf7f36e8c5180d72a607
parent1d5dc8af4f29575850958ce2ca4c6ffcc27dece5 (diff)
downloadopenbsd-52f13317baa428db8efa6305c98bcca1c8d6b93e.tar.gz
openbsd-52f13317baa428db8efa6305c98bcca1c8d6b93e.tar.bz2
openbsd-52f13317baa428db8efa6305c98bcca1c8d6b93e.zip
Stop caching one in the Montgomery domain
This is only used by ec_points_make_affine(), which is only used by the wNAF multiplication, which is only used by ECDSA. We can afford computing that one once per ECDSA verification given the cost of the rest of this. Thus, the field_set_to_one() member disappears from the EC_METHOD and the mont_one member disappears from EC_GROUP and with it all the complications when setting/copying/freeing the group. ok jsing
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c6
-rw-r--r--src/lib/libcrypto/ec/ec_local.h6
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c60
3 files changed, 16 insertions, 56 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 03c6f3aa90..170bdedc57 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lib.c,v 1.95 2025/01/06 10:56:46 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.96 2025/01/06 11:59:02 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -107,8 +107,7 @@ EC_GROUP_new(const EC_METHOD *meth)
107 goto err; 107 goto err;
108 108
109 /* 109 /*
110 * generator and seed are optional. mont_ctx, mont_one are only for 110 * generator, seed and mont_ctx are optional.
111 * curves using EC_GFp_mont_method()
112 */ 111 */
113 112
114 return group; 113 return group;
@@ -131,7 +130,6 @@ EC_GROUP_free(EC_GROUP *group)
131 BN_free(group->b); 130 BN_free(group->b);
132 131
133 BN_MONT_CTX_free(group->mont_ctx); 132 BN_MONT_CTX_free(group->mont_ctx);
134 BN_free(group->mont_one);
135 133
136 EC_POINT_free(group->generator); 134 EC_POINT_free(group->generator);
137 BN_free(group->order); 135 BN_free(group->order);
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 2bddaddd8a..1b7ca5b645 100644
--- a/src/lib/libcrypto/ec/ec_local.h
+++ b/src/lib/libcrypto/ec/ec_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_local.h,v 1.47 2025/01/06 10:56:46 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.48 2025/01/06 11:59:02 tb Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -143,7 +143,6 @@ struct ec_method_st {
143 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, 143 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
144 BN_CTX *); 144 BN_CTX *);
145 145
146 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
147 int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, 146 int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p,
148 BN_CTX *ctx); 147 BN_CTX *ctx);
149} /* EC_METHOD */; 148} /* EC_METHOD */;
@@ -184,9 +183,8 @@ struct ec_group_st {
184 /* Enables optimized point arithmetics for special case. */ 183 /* Enables optimized point arithmetics for special case. */
185 int a_is_minus3; 184 int a_is_minus3;
186 185
187 /* Montgomery context and values used by EC_GFp_mont_method. */ 186 /* Montgomery context used by EC_GFp_mont_method. */
188 BN_MONT_CTX *mont_ctx; 187 BN_MONT_CTX *mont_ctx;
189 BIGNUM *mont_one;
190} /* EC_GROUP */; 188} /* EC_GROUP */;
191 189
192struct ec_key_st { 190struct ec_key_st {
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 7bdeb351da..2297b07175 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.19 2025/01/06 10:56:46 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.20 2025/01/06 11:59:02 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.
@@ -1003,7 +1003,7 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1003 BN_CTX *ctx) 1003 BN_CTX *ctx)
1004{ 1004{
1005 BIGNUM **prod_Z = NULL; 1005 BIGNUM **prod_Z = NULL;
1006 BIGNUM *tmp, *tmp_Z; 1006 BIGNUM *one, *tmp, *tmp_Z;
1007 size_t i; 1007 size_t i;
1008 int ret = 0; 1008 int ret = 0;
1009 1009
@@ -1012,11 +1012,16 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1012 1012
1013 BN_CTX_start(ctx); 1013 BN_CTX_start(ctx);
1014 1014
1015 if ((one = BN_CTX_get(ctx)) == NULL)
1016 goto err;
1015 if ((tmp = BN_CTX_get(ctx)) == NULL) 1017 if ((tmp = BN_CTX_get(ctx)) == NULL)
1016 goto err; 1018 goto err;
1017 if ((tmp_Z = BN_CTX_get(ctx)) == NULL) 1019 if ((tmp_Z = BN_CTX_get(ctx)) == NULL)
1018 goto err; 1020 goto err;
1019 1021
1022 if (!ec_encode_scalar(group, one, BN_value_one(), ctx))
1023 goto err;
1024
1020 if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL) 1025 if ((prod_Z = calloc(num, sizeof *prod_Z)) == NULL)
1021 goto err; 1026 goto err;
1022 for (i = 0; i < num; i++) { 1027 for (i = 0; i < num; i++) {
@@ -1033,13 +1038,8 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1033 if (!bn_copy(prod_Z[0], points[0]->Z)) 1038 if (!bn_copy(prod_Z[0], points[0]->Z))
1034 goto err; 1039 goto err;
1035 } else { 1040 } else {
1036 if (group->meth->field_set_to_one != NULL) { 1041 if (!bn_copy(prod_Z[0], one))
1037 if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) 1042 goto err;
1038 goto err;
1039 } else {
1040 if (!BN_one(prod_Z[0]))
1041 goto err;
1042 }
1043 } 1043 }
1044 1044
1045 for (i = 1; i < num; i++) { 1045 for (i = 1; i < num; i++) {
@@ -1118,13 +1118,8 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1118 if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx)) 1118 if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
1119 goto err; 1119 goto err;
1120 1120
1121 if (group->meth->field_set_to_one != NULL) { 1121 if (!bn_copy(p->Z, one))
1122 if (!group->meth->field_set_to_one(group, p->Z, ctx)) 1122 goto err;
1123 goto err;
1124 } else {
1125 if (!BN_one(p->Z))
1126 goto err;
1127 }
1128 p->Z_is_one = 1; 1123 p->Z_is_one = 1;
1129 } 1124 }
1130 1125
@@ -1458,9 +1453,6 @@ ec_mont_group_clear(EC_GROUP *group)
1458{ 1453{
1459 BN_MONT_CTX_free(group->mont_ctx); 1454 BN_MONT_CTX_free(group->mont_ctx);
1460 group->mont_ctx = NULL; 1455 group->mont_ctx = NULL;
1461
1462 BN_free(group->mont_one);
1463 group->mont_one = NULL;
1464} 1456}
1465 1457
1466static int 1458static int
@@ -1478,11 +1470,7 @@ ec_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
1478 if (!BN_MONT_CTX_copy(dest->mont_ctx, src->mont_ctx)) 1470 if (!BN_MONT_CTX_copy(dest->mont_ctx, src->mont_ctx))
1479 goto err; 1471 goto err;
1480 } 1472 }
1481 if (src->mont_one != NULL) { 1473
1482 dest->mont_one = BN_dup(src->mont_one);
1483 if (dest->mont_one == NULL)
1484 goto err;
1485 }
1486 return 1; 1474 return 1;
1487 1475
1488 err: 1476 err:
@@ -1498,7 +1486,6 @@ ec_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1498 const BIGNUM *b, BN_CTX *ctx) 1486 const BIGNUM *b, BN_CTX *ctx)
1499{ 1487{
1500 BN_MONT_CTX *mont = NULL; 1488 BN_MONT_CTX *mont = NULL;
1501 BIGNUM *one = NULL;
1502 int ret = 0; 1489 int ret = 0;
1503 1490
1504 ec_mont_group_clear(group); 1491 ec_mont_group_clear(group);
@@ -1510,16 +1497,8 @@ ec_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1510 ECerror(ERR_R_BN_LIB); 1497 ECerror(ERR_R_BN_LIB);
1511 goto err; 1498 goto err;
1512 } 1499 }
1513 one = BN_new();
1514 if (one == NULL)
1515 goto err;
1516 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
1517 goto err;
1518
1519 group->mont_ctx = mont; 1500 group->mont_ctx = mont;
1520 mont = NULL; 1501 mont = NULL;
1521 group->mont_one = one;
1522 one = NULL;
1523 1502
1524 ret = ec_group_set_curve(group, p, a, b, ctx); 1503 ret = ec_group_set_curve(group, p, a, b, ctx);
1525 if (!ret) 1504 if (!ret)
@@ -1527,7 +1506,6 @@ ec_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1527 1506
1528 err: 1507 err:
1529 BN_MONT_CTX_free(mont); 1508 BN_MONT_CTX_free(mont);
1530 BN_free(one);
1531 1509
1532 return ret; 1510 return ret;
1533} 1511}
@@ -1576,19 +1554,6 @@ ec_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1576 return BN_from_montgomery(r, a, group->mont_ctx, ctx); 1554 return BN_from_montgomery(r, a, group->mont_ctx, ctx);
1577} 1555}
1578 1556
1579static int
1580ec_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
1581{
1582 if (group->mont_one == NULL) {
1583 ECerror(EC_R_NOT_INITIALIZED);
1584 return 0;
1585 }
1586 if (!bn_copy(r, group->mont_one))
1587 return 0;
1588
1589 return 1;
1590}
1591
1592static const EC_METHOD ec_GFp_simple_method = { 1557static const EC_METHOD ec_GFp_simple_method = {
1593 .field_type = NID_X9_62_prime_field, 1558 .field_type = NID_X9_62_prime_field,
1594 .group_copy = ec_group_copy, 1559 .group_copy = ec_group_copy,
@@ -1647,7 +1612,6 @@ static const EC_METHOD ec_GFp_mont_method = {
1647 .field_sqr = ec_mont_field_sqr, 1612 .field_sqr = ec_mont_field_sqr,
1648 .field_encode = ec_mont_field_encode, 1613 .field_encode = ec_mont_field_encode,
1649 .field_decode = ec_mont_field_decode, 1614 .field_decode = ec_mont_field_decode,
1650 .field_set_to_one = ec_mont_field_set_to_one,
1651 .blind_coordinates = ec_blind_coordinates, 1615 .blind_coordinates = ec_blind_coordinates,
1652}; 1616};
1653 1617