diff options
| author | tb <> | 2025-01-05 16:07:08 +0000 |
|---|---|---|
| committer | tb <> | 2025-01-05 16:07:08 +0000 |
| commit | 26c9248a10bd0d95f47397e21bc2f056e53e19c8 (patch) | |
| tree | 01052cd554006bd8d0b366164df08e22b7dd6d57 /src | |
| parent | 7d80fee84377d3dd9365558712de411fc7f8356b (diff) | |
| download | openbsd-26c9248a10bd0d95f47397e21bc2f056e53e19c8.tar.gz openbsd-26c9248a10bd0d95f47397e21bc2f056e53e19c8.tar.bz2 openbsd-26c9248a10bd0d95f47397e21bc2f056e53e19c8.zip | |
Move BIGNUMs in EC_GROUP and EC_POINT to the heap
The only way to get an EC_GROUP or an EC_POINT is by calling the relevant
_new() function and to get rid of it, something must call _free(). Thus we
can establish the invariant that every group has Weierstrass coefficients
p, a, b as well as order and cofactor hanging off it. Similarly, Every
point has allocated BIGNUMs for its Jacobian projective coordinates.
Unfortunately, a group has the generator as an optional component in
addition to seed and montgomery context/one (where optionality makes
more sense).
This is a mostly mechanical diff and only drops a few silly comments and
a couple of unnecessary NULL checks since in our part of the wrold the
word invariant has a meaning.
This should also appease Coverity who likes to throw fits at calling
BN_free() for BIGNUM on the stack (yes, this is actually a thing).
ok jsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/ec/ec_convert.c | 12 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_lib.c | 97 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 23 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_pmeth.c | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_methods.c | 266 |
5 files changed, 208 insertions, 194 deletions
diff --git a/src/lib/libcrypto/ec/ec_convert.c b/src/lib/libcrypto/ec/ec_convert.c index b48fc85315..a18bc49132 100644 --- a/src/lib/libcrypto/ec/ec_convert.c +++ b/src/lib/libcrypto/ec/ec_convert.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_convert.c,v 1.13 2024/12/16 06:11:26 tb Exp $ */ | 1 | /* $OpenBSD: ec_convert.c,v 1.14 2025/01/05 16:07:08 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 | */ |
| @@ -157,11 +157,11 @@ ec_encoded_length(const EC_GROUP *group, uint8_t form, size_t *out_len) | |||
| 157 | *out_len = 1; | 157 | *out_len = 1; |
| 158 | return 1; | 158 | return 1; |
| 159 | case EC_POINT_COMPRESSED: | 159 | case EC_POINT_COMPRESSED: |
| 160 | *out_len = 1 + BN_num_bytes(&group->p); | 160 | *out_len = 1 + BN_num_bytes(group->p); |
| 161 | return 1; | 161 | return 1; |
| 162 | case EC_POINT_UNCOMPRESSED: | 162 | case EC_POINT_UNCOMPRESSED: |
| 163 | case EC_POINT_HYBRID: | 163 | case EC_POINT_HYBRID: |
| 164 | *out_len = 1 + 2 * BN_num_bytes(&group->p); | 164 | *out_len = 1 + 2 * BN_num_bytes(group->p); |
| 165 | return 1; | 165 | return 1; |
| 166 | default: | 166 | default: |
| 167 | return 0; | 167 | return 0; |
| @@ -172,14 +172,14 @@ static int | |||
| 172 | ec_field_element_is_valid(const EC_GROUP *group, const BIGNUM *bn) | 172 | ec_field_element_is_valid(const EC_GROUP *group, const BIGNUM *bn) |
| 173 | { | 173 | { |
| 174 | /* Ensure bn is in the range [0, p). */ | 174 | /* Ensure bn is in the range [0, p). */ |
| 175 | return !BN_is_negative(bn) && BN_cmp(&group->p, bn) > 0; | 175 | return !BN_is_negative(bn) && BN_cmp(group->p, bn) > 0; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static int | 178 | static int |
| 179 | ec_add_field_element_cbb(CBB *cbb, const EC_GROUP *group, const BIGNUM *bn) | 179 | ec_add_field_element_cbb(CBB *cbb, const EC_GROUP *group, const BIGNUM *bn) |
| 180 | { | 180 | { |
| 181 | uint8_t *buf = NULL; | 181 | uint8_t *buf = NULL; |
| 182 | int buf_len = BN_num_bytes(&group->p); | 182 | int buf_len = BN_num_bytes(group->p); |
| 183 | 183 | ||
| 184 | if (!ec_field_element_is_valid(group, bn)) { | 184 | if (!ec_field_element_is_valid(group, bn)) { |
| 185 | ECerror(EC_R_BIGNUM_OUT_OF_RANGE); | 185 | ECerror(EC_R_BIGNUM_OUT_OF_RANGE); |
| @@ -202,7 +202,7 @@ ec_get_field_element_cbs(CBS *cbs, const EC_GROUP *group, BIGNUM *bn) | |||
| 202 | { | 202 | { |
| 203 | CBS field_element; | 203 | CBS field_element; |
| 204 | 204 | ||
| 205 | if (!CBS_get_bytes(cbs, &field_element, BN_num_bytes(&group->p))) { | 205 | if (!CBS_get_bytes(cbs, &field_element, BN_num_bytes(group->p))) { |
| 206 | ECerror(EC_R_INVALID_ENCODING); | 206 | ECerror(EC_R_INVALID_ENCODING); |
| 207 | return 0; | 207 | return 0; |
| 208 | } | 208 | } |
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c index 89d26e1177..d961ad0ee4 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.93 2025/01/01 10:01:31 tb Exp $ */ | 1 | /* $OpenBSD: ec_lib.c,v 1.94 2025/01/05 16:07:08 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 | */ |
| @@ -94,6 +94,23 @@ EC_GROUP_new(const EC_METHOD *meth) | |||
| 94 | group->asn1_flag = OPENSSL_EC_NAMED_CURVE; | 94 | group->asn1_flag = OPENSSL_EC_NAMED_CURVE; |
| 95 | group->asn1_form = POINT_CONVERSION_UNCOMPRESSED; | 95 | group->asn1_form = POINT_CONVERSION_UNCOMPRESSED; |
| 96 | 96 | ||
| 97 | if ((group->p = BN_new()) == NULL) | ||
| 98 | goto err; | ||
| 99 | if ((group->a = BN_new()) == NULL) | ||
| 100 | goto err; | ||
| 101 | if ((group->b = BN_new()) == NULL) | ||
| 102 | goto err; | ||
| 103 | |||
| 104 | if ((group->order = BN_new()) == NULL) | ||
| 105 | goto err; | ||
| 106 | if ((group->cofactor = BN_new()) == NULL) | ||
| 107 | goto err; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * generator and seed are optional. mont_ctx, mont_one are only for | ||
| 111 | * curves using EC_GFp_mont_method() | ||
| 112 | */ | ||
| 113 | |||
| 97 | return group; | 114 | return group; |
| 98 | 115 | ||
| 99 | err: | 116 | err: |
| @@ -109,16 +126,16 @@ EC_GROUP_free(EC_GROUP *group) | |||
| 109 | if (group == NULL) | 126 | if (group == NULL) |
| 110 | return; | 127 | return; |
| 111 | 128 | ||
| 112 | BN_free(&group->p); | 129 | BN_free(group->p); |
| 113 | BN_free(&group->a); | 130 | BN_free(group->a); |
| 114 | BN_free(&group->b); | 131 | BN_free(group->b); |
| 115 | 132 | ||
| 116 | BN_MONT_CTX_free(group->mont_ctx); | 133 | BN_MONT_CTX_free(group->mont_ctx); |
| 117 | BN_free(group->mont_one); | 134 | BN_free(group->mont_one); |
| 118 | 135 | ||
| 119 | EC_POINT_free(group->generator); | 136 | EC_POINT_free(group->generator); |
| 120 | BN_free(&group->order); | 137 | BN_free(group->order); |
| 121 | BN_free(&group->cofactor); | 138 | BN_free(group->cofactor); |
| 122 | 139 | ||
| 123 | freezero(group->seed, group->seed_len); | 140 | freezero(group->seed, group->seed_len); |
| 124 | freezero(group, sizeof *group); | 141 | freezero(group, sizeof *group); |
| @@ -152,14 +169,14 @@ EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) | |||
| 152 | EC_POINT_free(dest->generator); | 169 | EC_POINT_free(dest->generator); |
| 153 | dest->generator = NULL; | 170 | dest->generator = NULL; |
| 154 | if (src->generator != NULL) { | 171 | if (src->generator != NULL) { |
| 155 | if (!EC_GROUP_set_generator(dest, src->generator, &src->order, | 172 | if (!EC_GROUP_set_generator(dest, src->generator, src->order, |
| 156 | &src->cofactor)) | 173 | src->cofactor)) |
| 157 | return 0; | 174 | return 0; |
| 158 | } else { | 175 | } else { |
| 159 | /* XXX - should do the sanity checks as in set_generator() */ | 176 | /* XXX - should do the sanity checks as in set_generator() */ |
| 160 | if (!bn_copy(&dest->order, &src->order)) | 177 | if (!bn_copy(dest->order, src->order)) |
| 161 | return 0; | 178 | return 0; |
| 162 | if (!bn_copy(&dest->cofactor, &src->cofactor)) | 179 | if (!bn_copy(dest->cofactor, src->cofactor)) |
| 163 | return 0; | 180 | return 0; |
| 164 | } | 181 | } |
| 165 | 182 | ||
| @@ -241,7 +258,7 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor) | |||
| 241 | BIGNUM *cofactor; | 258 | BIGNUM *cofactor; |
| 242 | int ret = 0; | 259 | int ret = 0; |
| 243 | 260 | ||
| 244 | BN_zero(&group->cofactor); | 261 | BN_zero(group->cofactor); |
| 245 | 262 | ||
| 246 | if ((ctx = BN_CTX_new()) == NULL) | 263 | if ((ctx = BN_CTX_new()) == NULL) |
| 247 | goto err; | 264 | goto err; |
| @@ -269,7 +286,7 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor) | |||
| 269 | * If the cofactor is too large, we cannot guess it and default to zero. | 286 | * If the cofactor is too large, we cannot guess it and default to zero. |
| 270 | * The RHS of below is a strict overestimate of log(4 * sqrt(p)). | 287 | * The RHS of below is a strict overestimate of log(4 * sqrt(p)). |
| 271 | */ | 288 | */ |
| 272 | if (BN_num_bits(&group->order) <= (BN_num_bits(&group->p) + 1) / 2 + 3) | 289 | if (BN_num_bits(group->order) <= (BN_num_bits(group->p) + 1) / 2 + 3) |
| 273 | goto done; | 290 | goto done; |
| 274 | 291 | ||
| 275 | /* | 292 | /* |
| @@ -278,26 +295,26 @@ ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor) | |||
| 278 | */ | 295 | */ |
| 279 | 296 | ||
| 280 | /* h = n/2 */ | 297 | /* h = n/2 */ |
| 281 | if (!BN_rshift1(cofactor, &group->order)) | 298 | if (!BN_rshift1(cofactor, group->order)) |
| 282 | goto err; | 299 | goto err; |
| 283 | /* h = 1 + n/2 */ | 300 | /* h = 1 + n/2 */ |
| 284 | if (!BN_add_word(cofactor, 1)) | 301 | if (!BN_add_word(cofactor, 1)) |
| 285 | goto err; | 302 | goto err; |
| 286 | /* h = p + 1 + n/2 */ | 303 | /* h = p + 1 + n/2 */ |
| 287 | if (!BN_add(cofactor, cofactor, &group->p)) | 304 | if (!BN_add(cofactor, cofactor, group->p)) |
| 288 | goto err; | 305 | goto err; |
| 289 | /* h = (p + 1 + n/2) / n */ | 306 | /* h = (p + 1 + n/2) / n */ |
| 290 | if (!BN_div_ct(cofactor, NULL, cofactor, &group->order, ctx)) | 307 | if (!BN_div_ct(cofactor, NULL, cofactor, group->order, ctx)) |
| 291 | goto err; | 308 | goto err; |
| 292 | 309 | ||
| 293 | done: | 310 | done: |
| 294 | /* Use Hasse's theorem to bound the cofactor. */ | 311 | /* Use Hasse's theorem to bound the cofactor. */ |
| 295 | if (BN_num_bits(cofactor) > BN_num_bits(&group->p) + 1) { | 312 | if (BN_num_bits(cofactor) > BN_num_bits(group->p) + 1) { |
| 296 | ECerror(EC_R_INVALID_GROUP_ORDER); | 313 | ECerror(EC_R_INVALID_GROUP_ORDER); |
| 297 | goto err; | 314 | goto err; |
| 298 | } | 315 | } |
| 299 | 316 | ||
| 300 | if (!bn_copy(&group->cofactor, cofactor)) | 317 | if (!bn_copy(group->cofactor, cofactor)) |
| 301 | goto err; | 318 | goto err; |
| 302 | 319 | ||
| 303 | ret = 1; | 320 | ret = 1; |
| @@ -319,7 +336,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | |||
| 319 | } | 336 | } |
| 320 | 337 | ||
| 321 | /* Require p >= 1. */ | 338 | /* Require p >= 1. */ |
| 322 | if (BN_is_zero(&group->p) || BN_is_negative(&group->p)) { | 339 | if (BN_is_zero(group->p) || BN_is_negative(group->p)) { |
| 323 | ECerror(EC_R_INVALID_FIELD); | 340 | ECerror(EC_R_INVALID_FIELD); |
| 324 | return 0; | 341 | return 0; |
| 325 | } | 342 | } |
| @@ -329,7 +346,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | |||
| 329 | * than the field cardinality due to Hasse's theorem. | 346 | * than the field cardinality due to Hasse's theorem. |
| 330 | */ | 347 | */ |
| 331 | if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 || | 348 | if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 || |
| 332 | BN_num_bits(order) > BN_num_bits(&group->p) + 1) { | 349 | BN_num_bits(order) > BN_num_bits(group->p) + 1) { |
| 333 | ECerror(EC_R_INVALID_GROUP_ORDER); | 350 | ECerror(EC_R_INVALID_GROUP_ORDER); |
| 334 | return 0; | 351 | return 0; |
| 335 | } | 352 | } |
| @@ -342,7 +359,7 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, | |||
| 342 | if (!EC_POINT_copy(group->generator, generator)) | 359 | if (!EC_POINT_copy(group->generator, generator)) |
| 343 | return 0; | 360 | return 0; |
| 344 | 361 | ||
| 345 | if (!bn_copy(&group->order, order)) | 362 | if (!bn_copy(group->order, order)) |
| 346 | return 0; | 363 | return 0; |
| 347 | 364 | ||
| 348 | if (!ec_set_cofactor(group, cofactor)) | 365 | if (!ec_set_cofactor(group, cofactor)) |
| @@ -362,7 +379,7 @@ LCRYPTO_ALIAS(EC_GROUP_get0_generator); | |||
| 362 | int | 379 | int |
| 363 | EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) | 380 | EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) |
| 364 | { | 381 | { |
| 365 | if (!bn_copy(order, &group->order)) | 382 | if (!bn_copy(order, group->order)) |
| 366 | return 0; | 383 | return 0; |
| 367 | 384 | ||
| 368 | return !BN_is_zero(order); | 385 | return !BN_is_zero(order); |
| @@ -372,7 +389,7 @@ LCRYPTO_ALIAS(EC_GROUP_get_order); | |||
| 372 | const BIGNUM * | 389 | const BIGNUM * |
| 373 | EC_GROUP_get0_order(const EC_GROUP *group) | 390 | EC_GROUP_get0_order(const EC_GROUP *group) |
| 374 | { | 391 | { |
| 375 | return &group->order; | 392 | return group->order; |
| 376 | } | 393 | } |
| 377 | 394 | ||
| 378 | int | 395 | int |
| @@ -385,17 +402,17 @@ LCRYPTO_ALIAS(EC_GROUP_order_bits); | |||
| 385 | int | 402 | int |
| 386 | EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) | 403 | EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) |
| 387 | { | 404 | { |
| 388 | if (!bn_copy(cofactor, &group->cofactor)) | 405 | if (!bn_copy(cofactor, group->cofactor)) |
| 389 | return 0; | 406 | return 0; |
| 390 | 407 | ||
| 391 | return !BN_is_zero(&group->cofactor); | 408 | return !BN_is_zero(group->cofactor); |
| 392 | } | 409 | } |
| 393 | LCRYPTO_ALIAS(EC_GROUP_get_cofactor); | 410 | LCRYPTO_ALIAS(EC_GROUP_get_cofactor); |
| 394 | 411 | ||
| 395 | const BIGNUM * | 412 | const BIGNUM * |
| 396 | EC_GROUP_get0_cofactor(const EC_GROUP *group) | 413 | EC_GROUP_get0_cofactor(const EC_GROUP *group) |
| 397 | { | 414 | { |
| 398 | return &group->cofactor; | 415 | return group->cofactor; |
| 399 | } | 416 | } |
| 400 | 417 | ||
| 401 | void | 418 | void |
| @@ -784,6 +801,13 @@ EC_POINT_new(const EC_GROUP *group) | |||
| 784 | goto err; | 801 | goto err; |
| 785 | } | 802 | } |
| 786 | 803 | ||
| 804 | if ((point->X = BN_new()) == NULL) | ||
| 805 | goto err; | ||
| 806 | if ((point->Y = BN_new()) == NULL) | ||
| 807 | goto err; | ||
| 808 | if ((point->Z = BN_new()) == NULL) | ||
| 809 | goto err; | ||
| 810 | |||
| 787 | point->meth = group->meth; | 811 | point->meth = group->meth; |
| 788 | 812 | ||
| 789 | return point; | 813 | return point; |
| @@ -801,9 +825,9 @@ EC_POINT_free(EC_POINT *point) | |||
| 801 | if (point == NULL) | 825 | if (point == NULL) |
| 802 | return; | 826 | return; |
| 803 | 827 | ||
| 804 | BN_free(&point->X); | 828 | BN_free(point->X); |
| 805 | BN_free(&point->Y); | 829 | BN_free(point->Y); |
| 806 | BN_free(&point->Z); | 830 | BN_free(point->Z); |
| 807 | 831 | ||
| 808 | freezero(point, sizeof *point); | 832 | freezero(point, sizeof *point); |
| 809 | } | 833 | } |
| @@ -826,11 +850,11 @@ EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) | |||
| 826 | if (dest == src) | 850 | if (dest == src) |
| 827 | return 1; | 851 | return 1; |
| 828 | 852 | ||
| 829 | if (!bn_copy(&dest->X, &src->X)) | 853 | if (!bn_copy(dest->X, src->X)) |
| 830 | return 0; | 854 | return 0; |
| 831 | if (!bn_copy(&dest->Y, &src->Y)) | 855 | if (!bn_copy(dest->Y, src->Y)) |
| 832 | return 0; | 856 | return 0; |
| 833 | if (!bn_copy(&dest->Z, &src->Z)) | 857 | if (!bn_copy(dest->Z, src->Z)) |
| 834 | return 0; | 858 | return 0; |
| 835 | dest->Z_is_one = src->Z_is_one; | 859 | dest->Z_is_one = src->Z_is_one; |
| 836 | 860 | ||
| @@ -876,7 +900,7 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) | |||
| 876 | return 0; | 900 | return 0; |
| 877 | } | 901 | } |
| 878 | 902 | ||
| 879 | BN_zero(&point->Z); | 903 | BN_zero(point->Z); |
| 880 | point->Z_is_one = 0; | 904 | point->Z_is_one = 0; |
| 881 | 905 | ||
| 882 | return 1; | 906 | return 1; |
| @@ -1193,7 +1217,7 @@ EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) | |||
| 1193 | return 0; | 1217 | return 0; |
| 1194 | } | 1218 | } |
| 1195 | 1219 | ||
| 1196 | return BN_is_zero(&point->Z); | 1220 | return BN_is_zero(point->Z); |
| 1197 | } | 1221 | } |
| 1198 | LCRYPTO_ALIAS(EC_POINT_is_at_infinity); | 1222 | LCRYPTO_ALIAS(EC_POINT_is_at_infinity); |
| 1199 | 1223 | ||
| @@ -1440,10 +1464,5 @@ LCRYPTO_ALIAS(EC_GROUP_have_precompute_mult); | |||
| 1440 | int | 1464 | int |
| 1441 | ec_group_simple_order_bits(const EC_GROUP *group) | 1465 | ec_group_simple_order_bits(const EC_GROUP *group) |
| 1442 | { | 1466 | { |
| 1443 | /* XXX change group->order to a pointer? */ | 1467 | return BN_num_bits(group->order); |
| 1444 | #if 0 | ||
| 1445 | if (group->order == NULL) | ||
| 1446 | return 0; | ||
| 1447 | #endif | ||
| 1448 | return BN_num_bits(&group->order); | ||
| 1449 | } | 1468 | } |
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h index cc918b38fd..0d734351de 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.45 2025/01/01 10:01:31 tb Exp $ */ | 1 | /* $OpenBSD: ec_local.h,v 1.46 2025/01/05 16:07:08 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 | */ |
| @@ -160,8 +160,8 @@ struct ec_group_st { | |||
| 160 | const EC_METHOD *meth; | 160 | const EC_METHOD *meth; |
| 161 | 161 | ||
| 162 | EC_POINT *generator; /* Optional */ | 162 | EC_POINT *generator; /* Optional */ |
| 163 | BIGNUM order; | 163 | BIGNUM *order; |
| 164 | BIGNUM cofactor; | 164 | BIGNUM *cofactor; |
| 165 | 165 | ||
| 166 | int nid; /* Optional NID for named curve. */ | 166 | int nid; /* Optional NID for named curve. */ |
| 167 | 167 | ||
| @@ -181,9 +181,9 @@ struct ec_group_st { | |||
| 181 | /* | 181 | /* |
| 182 | * Coefficients of the Weierstrass equation y^2 = x^3 + a*x + b (mod p). | 182 | * Coefficients of the Weierstrass equation y^2 = x^3 + a*x + b (mod p). |
| 183 | */ | 183 | */ |
| 184 | BIGNUM p; | 184 | BIGNUM *p; |
| 185 | BIGNUM a; | 185 | BIGNUM *a; |
| 186 | BIGNUM b; | 186 | BIGNUM *b; |
| 187 | 187 | ||
| 188 | /* Enables optimized point arithmetics for special case. */ | 188 | /* Enables optimized point arithmetics for special case. */ |
| 189 | int a_is_minus3; | 189 | int a_is_minus3; |
| @@ -216,17 +216,12 @@ struct ec_point_st { | |||
| 216 | const EC_METHOD *meth; | 216 | const EC_METHOD *meth; |
| 217 | 217 | ||
| 218 | /* | 218 | /* |
| 219 | * All members except 'meth' are handled by the method functions, | ||
| 220 | * even if they appear generic. | ||
| 221 | */ | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3) | 219 | * Jacobian projective coordinates: (X, Y, Z) represents (X/Z^2, Y/Z^3) |
| 225 | * if Z != 0 | 220 | * if Z != 0 |
| 226 | */ | 221 | */ |
| 227 | BIGNUM X; | 222 | BIGNUM *X; |
| 228 | BIGNUM Y; | 223 | BIGNUM *Y; |
| 229 | BIGNUM Z; | 224 | BIGNUM *Z; |
| 230 | int Z_is_one; /* enable optimized point arithmetics for special case */ | 225 | int Z_is_one; /* enable optimized point arithmetics for special case */ |
| 231 | } /* EC_POINT */; | 226 | } /* EC_POINT */; |
| 232 | 227 | ||
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c index 424d1896b2..6d74a7f8a4 100644 --- a/src/lib/libcrypto/ec/ec_pmeth.c +++ b/src/lib/libcrypto/ec/ec_pmeth.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_pmeth.c,v 1.23 2024/10/19 14:41:03 tb Exp $ */ | 1 | /* $OpenBSD: ec_pmeth.c,v 1.24 2025/01/05 16:07:08 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -323,7 +323,7 @@ pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | |||
| 323 | if (!ec_key->group) | 323 | if (!ec_key->group) |
| 324 | return -2; | 324 | return -2; |
| 325 | /* If cofactor is 1 cofactor mode does nothing */ | 325 | /* If cofactor is 1 cofactor mode does nothing */ |
| 326 | if (BN_is_one(&ec_key->group->cofactor)) | 326 | if (BN_is_one(ec_key->group->cofactor)) |
| 327 | return 1; | 327 | return 1; |
| 328 | if (!dctx->co_key) { | 328 | if (!dctx->co_key) { |
| 329 | dctx->co_key = EC_KEY_dup(ec_key); | 329 | dctx->co_key = EC_KEY_dup(ec_key); |
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c index af19addab4..b2ecc7e17a 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.17 2025/01/01 10:01:31 tb Exp $ */ | 1 | /* $OpenBSD: ecp_methods.c,v 1.18 2025/01/05 16:07:08 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. |
| @@ -87,11 +87,11 @@ | |||
| 87 | static int | 87 | static int |
| 88 | ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) | 88 | ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) |
| 89 | { | 89 | { |
| 90 | if (!bn_copy(&dest->p, &src->p)) | 90 | if (!bn_copy(dest->p, src->p)) |
| 91 | return 0; | 91 | return 0; |
| 92 | if (!bn_copy(&dest->a, &src->a)) | 92 | if (!bn_copy(dest->a, src->a)) |
| 93 | return 0; | 93 | return 0; |
| 94 | if (!bn_copy(&dest->b, &src->b)) | 94 | if (!bn_copy(dest->b, src->b)) |
| 95 | return 0; | 95 | return 0; |
| 96 | 96 | ||
| 97 | dest->a_is_minus3 = src->a_is_minus3; | 97 | dest->a_is_minus3 = src->a_is_minus3; |
| @@ -114,7 +114,7 @@ ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx | |||
| 114 | static int | 114 | static int |
| 115 | ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) | 115 | ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) |
| 116 | { | 116 | { |
| 117 | if (!BN_nnmod(bn, x, &group->p, ctx)) | 117 | if (!BN_nnmod(bn, x, group->p, ctx)) |
| 118 | return 0; | 118 | return 0; |
| 119 | 119 | ||
| 120 | if (group->meth->field_encode != NULL) | 120 | if (group->meth->field_encode != NULL) |
| @@ -127,7 +127,7 @@ static int | |||
| 127 | ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one, | 127 | ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one, |
| 128 | const BIGNUM *z, BN_CTX *ctx) | 128 | const BIGNUM *z, BN_CTX *ctx) |
| 129 | { | 129 | { |
| 130 | if (!BN_nnmod(bn, z, &group->p, ctx)) | 130 | if (!BN_nnmod(bn, z, group->p, ctx)) |
| 131 | return 0; | 131 | return 0; |
| 132 | 132 | ||
| 133 | *is_one = BN_is_one(bn); | 133 | *is_one = BN_is_one(bn); |
| @@ -158,18 +158,18 @@ ec_group_set_curve(EC_GROUP *group, | |||
| 158 | if ((a_plus_3 = BN_CTX_get(ctx)) == NULL) | 158 | if ((a_plus_3 = BN_CTX_get(ctx)) == NULL) |
| 159 | goto err; | 159 | goto err; |
| 160 | 160 | ||
| 161 | if (!bn_copy(&group->p, p)) | 161 | if (!bn_copy(group->p, p)) |
| 162 | goto err; | 162 | goto err; |
| 163 | BN_set_negative(&group->p, 0); | 163 | BN_set_negative(group->p, 0); |
| 164 | 164 | ||
| 165 | if (!ec_encode_scalar(group, &group->a, a, ctx)) | 165 | if (!ec_encode_scalar(group, group->a, a, ctx)) |
| 166 | goto err; | 166 | goto err; |
| 167 | if (!ec_encode_scalar(group, &group->b, b, ctx)) | 167 | if (!ec_encode_scalar(group, group->b, b, ctx)) |
| 168 | goto err; | 168 | goto err; |
| 169 | 169 | ||
| 170 | if (!BN_set_word(a_plus_3, 3)) | 170 | if (!BN_set_word(a_plus_3, 3)) |
| 171 | goto err; | 171 | goto err; |
| 172 | if (!BN_mod_add(a_plus_3, a_plus_3, a, &group->p, ctx)) | 172 | if (!BN_mod_add(a_plus_3, a_plus_3, a, group->p, ctx)) |
| 173 | goto err; | 173 | goto err; |
| 174 | 174 | ||
| 175 | group->a_is_minus3 = BN_is_zero(a_plus_3); | 175 | group->a_is_minus3 = BN_is_zero(a_plus_3); |
| @@ -187,12 +187,12 @@ ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, | |||
| 187 | BN_CTX *ctx) | 187 | BN_CTX *ctx) |
| 188 | { | 188 | { |
| 189 | if (p != NULL) { | 189 | if (p != NULL) { |
| 190 | if (!bn_copy(p, &group->p)) | 190 | if (!bn_copy(p, group->p)) |
| 191 | return 0; | 191 | return 0; |
| 192 | } | 192 | } |
| 193 | if (!ec_decode_scalar(group, a, &group->a, ctx)) | 193 | if (!ec_decode_scalar(group, a, group->a, ctx)) |
| 194 | return 0; | 194 | return 0; |
| 195 | if (!ec_decode_scalar(group, b, &group->b, ctx)) | 195 | if (!ec_decode_scalar(group, b, group->b, ctx)) |
| 196 | return 0; | 196 | return 0; |
| 197 | 197 | ||
| 198 | return 1; | 198 | return 1; |
| @@ -201,7 +201,7 @@ ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, | |||
| 201 | static int | 201 | static int |
| 202 | ec_group_get_degree(const EC_GROUP *group) | 202 | ec_group_get_degree(const EC_GROUP *group) |
| 203 | { | 203 | { |
| 204 | return BN_num_bits(&group->p); | 204 | return BN_num_bits(group->p); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static int | 207 | static int |
| @@ -273,15 +273,15 @@ ec_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, | |||
| 273 | */ | 273 | */ |
| 274 | 274 | ||
| 275 | if (x != NULL) { | 275 | if (x != NULL) { |
| 276 | if (!ec_encode_scalar(group, &point->X, x, ctx)) | 276 | if (!ec_encode_scalar(group, point->X, x, ctx)) |
| 277 | goto err; | 277 | goto err; |
| 278 | } | 278 | } |
| 279 | if (y != NULL) { | 279 | if (y != NULL) { |
| 280 | if (!ec_encode_scalar(group, &point->Y, y, ctx)) | 280 | if (!ec_encode_scalar(group, point->Y, y, ctx)) |
| 281 | goto err; | 281 | goto err; |
| 282 | } | 282 | } |
| 283 | if (z != NULL) { | 283 | if (z != NULL) { |
| 284 | if (!ec_encode_z_coordinate(group, &point->Z, &point->Z_is_one, | 284 | if (!ec_encode_z_coordinate(group, point->Z, &point->Z_is_one, |
| 285 | z, ctx)) | 285 | z, ctx)) |
| 286 | goto err; | 286 | goto err; |
| 287 | } | 287 | } |
| @@ -298,11 +298,11 @@ ec_get_Jprojective_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 298 | { | 298 | { |
| 299 | int ret = 0; | 299 | int ret = 0; |
| 300 | 300 | ||
| 301 | if (!ec_decode_scalar(group, x, &point->X, ctx)) | 301 | if (!ec_decode_scalar(group, x, point->X, ctx)) |
| 302 | goto err; | 302 | goto err; |
| 303 | if (!ec_decode_scalar(group, y, &point->Y, ctx)) | 303 | if (!ec_decode_scalar(group, y, point->Y, ctx)) |
| 304 | goto err; | 304 | goto err; |
| 305 | if (!ec_decode_scalar(group, z, &point->Z, ctx)) | 305 | if (!ec_decode_scalar(group, z, point->Z, ctx)) |
| 306 | goto err; | 306 | goto err; |
| 307 | 307 | ||
| 308 | ret = 1; | 308 | ret = 1; |
| @@ -346,18 +346,18 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 346 | 346 | ||
| 347 | /* Convert from projective coordinates (X, Y, Z) into (X/Z^2, Y/Z^3). */ | 347 | /* Convert from projective coordinates (X, Y, Z) into (X/Z^2, Y/Z^3). */ |
| 348 | 348 | ||
| 349 | if (!ec_decode_scalar(group, z, &point->Z, ctx)) | 349 | if (!ec_decode_scalar(group, z, point->Z, ctx)) |
| 350 | goto err; | 350 | goto err; |
| 351 | 351 | ||
| 352 | if (BN_is_one(z)) { | 352 | if (BN_is_one(z)) { |
| 353 | if (!ec_decode_scalar(group, x, &point->X, ctx)) | 353 | if (!ec_decode_scalar(group, x, point->X, ctx)) |
| 354 | goto err; | 354 | goto err; |
| 355 | if (!ec_decode_scalar(group, y, &point->Y, ctx)) | 355 | if (!ec_decode_scalar(group, y, point->Y, ctx)) |
| 356 | goto err; | 356 | goto err; |
| 357 | goto done; | 357 | goto done; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | if (BN_mod_inverse_ct(Z_1, z, &group->p, ctx) == NULL) { | 360 | if (BN_mod_inverse_ct(Z_1, z, group->p, ctx) == NULL) { |
| 361 | ECerror(ERR_R_BN_LIB); | 361 | ECerror(ERR_R_BN_LIB); |
| 362 | goto err; | 362 | goto err; |
| 363 | } | 363 | } |
| @@ -366,7 +366,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 366 | if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) | 366 | if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) |
| 367 | goto err; | 367 | goto err; |
| 368 | } else { | 368 | } else { |
| 369 | if (!BN_mod_sqr(Z_2, Z_1, &group->p, ctx)) | 369 | if (!BN_mod_sqr(Z_2, Z_1, group->p, ctx)) |
| 370 | goto err; | 370 | goto err; |
| 371 | } | 371 | } |
| 372 | 372 | ||
| @@ -375,7 +375,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 375 | * in the Montgomery case, field_mul will cancel out | 375 | * in the Montgomery case, field_mul will cancel out |
| 376 | * Montgomery factor in X: | 376 | * Montgomery factor in X: |
| 377 | */ | 377 | */ |
| 378 | if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) | 378 | if (!group->meth->field_mul(group, x, point->X, Z_2, ctx)) |
| 379 | goto err; | 379 | goto err; |
| 380 | } | 380 | } |
| 381 | if (y != NULL) { | 381 | if (y != NULL) { |
| @@ -384,7 +384,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 384 | if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) | 384 | if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) |
| 385 | goto err; | 385 | goto err; |
| 386 | } else { | 386 | } else { |
| 387 | if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->p, ctx)) | 387 | if (!BN_mod_mul(Z_3, Z_2, Z_1, group->p, ctx)) |
| 388 | goto err; | 388 | goto err; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| @@ -392,7 +392,7 @@ ec_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | |||
| 392 | * in the Montgomery case, field_mul will cancel out | 392 | * in the Montgomery case, field_mul will cancel out |
| 393 | * Montgomery factor in Y: | 393 | * Montgomery factor in Y: |
| 394 | */ | 394 | */ |
| 395 | if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) | 395 | if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx)) |
| 396 | goto err; | 396 | goto err; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| @@ -409,7 +409,7 @@ static int | |||
| 409 | ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, | 409 | ec_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, |
| 410 | const BIGNUM *in_x, int y_bit, BN_CTX *ctx) | 410 | const BIGNUM *in_x, int y_bit, BN_CTX *ctx) |
| 411 | { | 411 | { |
| 412 | const BIGNUM *p = &group->p, *a = &group->a, *b = &group->b; | 412 | const BIGNUM *p = group->p, *a = group->a, *b = group->b; |
| 413 | BIGNUM *w, *x, *y; | 413 | BIGNUM *w, *x, *y; |
| 414 | int ret = 0; | 414 | int ret = 0; |
| 415 | 415 | ||
| @@ -522,7 +522,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 522 | 522 | ||
| 523 | field_mul = group->meth->field_mul; | 523 | field_mul = group->meth->field_mul; |
| 524 | field_sqr = group->meth->field_sqr; | 524 | field_sqr = group->meth->field_sqr; |
| 525 | p = &group->p; | 525 | p = group->p; |
| 526 | 526 | ||
| 527 | BN_CTX_start(ctx); | 527 | BN_CTX_start(ctx); |
| 528 | 528 | ||
| @@ -549,44 +549,44 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 549 | 549 | ||
| 550 | /* n1, n2 */ | 550 | /* n1, n2 */ |
| 551 | if (b->Z_is_one) { | 551 | if (b->Z_is_one) { |
| 552 | if (!bn_copy(n1, &a->X)) | 552 | if (!bn_copy(n1, a->X)) |
| 553 | goto end; | 553 | goto end; |
| 554 | if (!bn_copy(n2, &a->Y)) | 554 | if (!bn_copy(n2, a->Y)) |
| 555 | goto end; | 555 | goto end; |
| 556 | /* n1 = X_a */ | 556 | /* n1 = X_a */ |
| 557 | /* n2 = Y_a */ | 557 | /* n2 = Y_a */ |
| 558 | } else { | 558 | } else { |
| 559 | if (!field_sqr(group, n0, &b->Z, ctx)) | 559 | if (!field_sqr(group, n0, b->Z, ctx)) |
| 560 | goto end; | 560 | goto end; |
| 561 | if (!field_mul(group, n1, &a->X, n0, ctx)) | 561 | if (!field_mul(group, n1, a->X, n0, ctx)) |
| 562 | goto end; | 562 | goto end; |
| 563 | /* n1 = X_a * Z_b^2 */ | 563 | /* n1 = X_a * Z_b^2 */ |
| 564 | 564 | ||
| 565 | if (!field_mul(group, n0, n0, &b->Z, ctx)) | 565 | if (!field_mul(group, n0, n0, b->Z, ctx)) |
| 566 | goto end; | 566 | goto end; |
| 567 | if (!field_mul(group, n2, &a->Y, n0, ctx)) | 567 | if (!field_mul(group, n2, a->Y, n0, ctx)) |
| 568 | goto end; | 568 | goto end; |
| 569 | /* n2 = Y_a * Z_b^3 */ | 569 | /* n2 = Y_a * Z_b^3 */ |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | /* n3, n4 */ | 572 | /* n3, n4 */ |
| 573 | if (a->Z_is_one) { | 573 | if (a->Z_is_one) { |
| 574 | if (!bn_copy(n3, &b->X)) | 574 | if (!bn_copy(n3, b->X)) |
| 575 | goto end; | 575 | goto end; |
| 576 | if (!bn_copy(n4, &b->Y)) | 576 | if (!bn_copy(n4, b->Y)) |
| 577 | goto end; | 577 | goto end; |
| 578 | /* n3 = X_b */ | 578 | /* n3 = X_b */ |
| 579 | /* n4 = Y_b */ | 579 | /* n4 = Y_b */ |
| 580 | } else { | 580 | } else { |
| 581 | if (!field_sqr(group, n0, &a->Z, ctx)) | 581 | if (!field_sqr(group, n0, a->Z, ctx)) |
| 582 | goto end; | 582 | goto end; |
| 583 | if (!field_mul(group, n3, &b->X, n0, ctx)) | 583 | if (!field_mul(group, n3, b->X, n0, ctx)) |
| 584 | goto end; | 584 | goto end; |
| 585 | /* n3 = X_b * Z_a^2 */ | 585 | /* n3 = X_b * Z_a^2 */ |
| 586 | 586 | ||
| 587 | if (!field_mul(group, n0, n0, &a->Z, ctx)) | 587 | if (!field_mul(group, n0, n0, a->Z, ctx)) |
| 588 | goto end; | 588 | goto end; |
| 589 | if (!field_mul(group, n4, &b->Y, n0, ctx)) | 589 | if (!field_mul(group, n4, b->Y, n0, ctx)) |
| 590 | goto end; | 590 | goto end; |
| 591 | /* n4 = Y_b * Z_a^3 */ | 591 | /* n4 = Y_b * Z_a^3 */ |
| 592 | } | 592 | } |
| @@ -608,7 +608,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 608 | goto end; | 608 | goto end; |
| 609 | } else { | 609 | } else { |
| 610 | /* a is the inverse of b */ | 610 | /* a is the inverse of b */ |
| 611 | BN_zero(&r->Z); | 611 | BN_zero(r->Z); |
| 612 | r->Z_is_one = 0; | 612 | r->Z_is_one = 0; |
| 613 | ret = 1; | 613 | ret = 1; |
| 614 | goto end; | 614 | goto end; |
| @@ -624,20 +624,20 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 624 | 624 | ||
| 625 | /* Z_r */ | 625 | /* Z_r */ |
| 626 | if (a->Z_is_one && b->Z_is_one) { | 626 | if (a->Z_is_one && b->Z_is_one) { |
| 627 | if (!bn_copy(&r->Z, n5)) | 627 | if (!bn_copy(r->Z, n5)) |
| 628 | goto end; | 628 | goto end; |
| 629 | } else { | 629 | } else { |
| 630 | if (a->Z_is_one) { | 630 | if (a->Z_is_one) { |
| 631 | if (!bn_copy(n0, &b->Z)) | 631 | if (!bn_copy(n0, b->Z)) |
| 632 | goto end; | 632 | goto end; |
| 633 | } else if (b->Z_is_one) { | 633 | } else if (b->Z_is_one) { |
| 634 | if (!bn_copy(n0, &a->Z)) | 634 | if (!bn_copy(n0, a->Z)) |
| 635 | goto end; | 635 | goto end; |
| 636 | } else { | 636 | } else { |
| 637 | if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) | 637 | if (!field_mul(group, n0, a->Z, b->Z, ctx)) |
| 638 | goto end; | 638 | goto end; |
| 639 | } | 639 | } |
| 640 | if (!field_mul(group, &r->Z, n0, n5, ctx)) | 640 | if (!field_mul(group, r->Z, n0, n5, ctx)) |
| 641 | goto end; | 641 | goto end; |
| 642 | } | 642 | } |
| 643 | r->Z_is_one = 0; | 643 | r->Z_is_one = 0; |
| @@ -650,12 +650,12 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 650 | goto end; | 650 | goto end; |
| 651 | if (!field_mul(group, n3, n1, n4, ctx)) | 651 | if (!field_mul(group, n3, n1, n4, ctx)) |
| 652 | goto end; | 652 | goto end; |
| 653 | if (!BN_mod_sub_quick(&r->X, n0, n3, p)) | 653 | if (!BN_mod_sub_quick(r->X, n0, n3, p)) |
| 654 | goto end; | 654 | goto end; |
| 655 | /* X_r = n6^2 - n5^2 * 'n7' */ | 655 | /* X_r = n6^2 - n5^2 * 'n7' */ |
| 656 | 656 | ||
| 657 | /* 'n9' */ | 657 | /* 'n9' */ |
| 658 | if (!BN_mod_lshift1_quick(n0, &r->X, p)) | 658 | if (!BN_mod_lshift1_quick(n0, r->X, p)) |
| 659 | goto end; | 659 | goto end; |
| 660 | if (!BN_mod_sub_quick(n0, n3, n0, p)) | 660 | if (!BN_mod_sub_quick(n0, n3, n0, p)) |
| 661 | goto end; | 661 | goto end; |
| @@ -674,7 +674,7 @@ ec_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, | |||
| 674 | if (!BN_add(n0, n0, p)) | 674 | if (!BN_add(n0, n0, p)) |
| 675 | goto end; | 675 | goto end; |
| 676 | /* now 0 <= n0 < 2*p, and n0 is even */ | 676 | /* now 0 <= n0 < 2*p, and n0 is even */ |
| 677 | if (!BN_rshift1(&r->Y, n0)) | 677 | if (!BN_rshift1(r->Y, n0)) |
| 678 | goto end; | 678 | goto end; |
| 679 | /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ | 679 | /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ |
| 680 | 680 | ||
| @@ -700,7 +700,7 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 700 | 700 | ||
| 701 | field_mul = group->meth->field_mul; | 701 | field_mul = group->meth->field_mul; |
| 702 | field_sqr = group->meth->field_sqr; | 702 | field_sqr = group->meth->field_sqr; |
| 703 | p = &group->p; | 703 | p = group->p; |
| 704 | 704 | ||
| 705 | BN_CTX_start(ctx); | 705 | BN_CTX_start(ctx); |
| 706 | 706 | ||
| @@ -721,21 +721,21 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 721 | 721 | ||
| 722 | /* n1 */ | 722 | /* n1 */ |
| 723 | if (a->Z_is_one) { | 723 | if (a->Z_is_one) { |
| 724 | if (!field_sqr(group, n0, &a->X, ctx)) | 724 | if (!field_sqr(group, n0, a->X, ctx)) |
| 725 | goto err; | 725 | goto err; |
| 726 | if (!BN_mod_lshift1_quick(n1, n0, p)) | 726 | if (!BN_mod_lshift1_quick(n1, n0, p)) |
| 727 | goto err; | 727 | goto err; |
| 728 | if (!BN_mod_add_quick(n0, n0, n1, p)) | 728 | if (!BN_mod_add_quick(n0, n0, n1, p)) |
| 729 | goto err; | 729 | goto err; |
| 730 | if (!BN_mod_add_quick(n1, n0, &group->a, p)) | 730 | if (!BN_mod_add_quick(n1, n0, group->a, p)) |
| 731 | goto err; | 731 | goto err; |
| 732 | /* n1 = 3 * X_a^2 + a_curve */ | 732 | /* n1 = 3 * X_a^2 + a_curve */ |
| 733 | } else if (group->a_is_minus3) { | 733 | } else if (group->a_is_minus3) { |
| 734 | if (!field_sqr(group, n1, &a->Z, ctx)) | 734 | if (!field_sqr(group, n1, a->Z, ctx)) |
| 735 | goto err; | 735 | goto err; |
| 736 | if (!BN_mod_add_quick(n0, &a->X, n1, p)) | 736 | if (!BN_mod_add_quick(n0, a->X, n1, p)) |
| 737 | goto err; | 737 | goto err; |
| 738 | if (!BN_mod_sub_quick(n2, &a->X, n1, p)) | 738 | if (!BN_mod_sub_quick(n2, a->X, n1, p)) |
| 739 | goto err; | 739 | goto err; |
| 740 | if (!field_mul(group, n1, n0, n2, ctx)) | 740 | if (!field_mul(group, n1, n0, n2, ctx)) |
| 741 | goto err; | 741 | goto err; |
| @@ -748,17 +748,17 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 748 | * Z_a^4 | 748 | * Z_a^4 |
| 749 | */ | 749 | */ |
| 750 | } else { | 750 | } else { |
| 751 | if (!field_sqr(group, n0, &a->X, ctx)) | 751 | if (!field_sqr(group, n0, a->X, ctx)) |
| 752 | goto err; | 752 | goto err; |
| 753 | if (!BN_mod_lshift1_quick(n1, n0, p)) | 753 | if (!BN_mod_lshift1_quick(n1, n0, p)) |
| 754 | goto err; | 754 | goto err; |
| 755 | if (!BN_mod_add_quick(n0, n0, n1, p)) | 755 | if (!BN_mod_add_quick(n0, n0, n1, p)) |
| 756 | goto err; | 756 | goto err; |
| 757 | if (!field_sqr(group, n1, &a->Z, ctx)) | 757 | if (!field_sqr(group, n1, a->Z, ctx)) |
| 758 | goto err; | 758 | goto err; |
| 759 | if (!field_sqr(group, n1, n1, ctx)) | 759 | if (!field_sqr(group, n1, n1, ctx)) |
| 760 | goto err; | 760 | goto err; |
| 761 | if (!field_mul(group, n1, n1, &group->a, ctx)) | 761 | if (!field_mul(group, n1, n1, group->a, ctx)) |
| 762 | goto err; | 762 | goto err; |
| 763 | if (!BN_mod_add_quick(n1, n1, n0, p)) | 763 | if (!BN_mod_add_quick(n1, n1, n0, p)) |
| 764 | goto err; | 764 | goto err; |
| @@ -767,21 +767,21 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 767 | 767 | ||
| 768 | /* Z_r */ | 768 | /* Z_r */ |
| 769 | if (a->Z_is_one) { | 769 | if (a->Z_is_one) { |
| 770 | if (!bn_copy(n0, &a->Y)) | 770 | if (!bn_copy(n0, a->Y)) |
| 771 | goto err; | 771 | goto err; |
| 772 | } else { | 772 | } else { |
| 773 | if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) | 773 | if (!field_mul(group, n0, a->Y, a->Z, ctx)) |
| 774 | goto err; | 774 | goto err; |
| 775 | } | 775 | } |
| 776 | if (!BN_mod_lshift1_quick(&r->Z, n0, p)) | 776 | if (!BN_mod_lshift1_quick(r->Z, n0, p)) |
| 777 | goto err; | 777 | goto err; |
| 778 | r->Z_is_one = 0; | 778 | r->Z_is_one = 0; |
| 779 | /* Z_r = 2 * Y_a * Z_a */ | 779 | /* Z_r = 2 * Y_a * Z_a */ |
| 780 | 780 | ||
| 781 | /* n2 */ | 781 | /* n2 */ |
| 782 | if (!field_sqr(group, n3, &a->Y, ctx)) | 782 | if (!field_sqr(group, n3, a->Y, ctx)) |
| 783 | goto err; | 783 | goto err; |
| 784 | if (!field_mul(group, n2, &a->X, n3, ctx)) | 784 | if (!field_mul(group, n2, a->X, n3, ctx)) |
| 785 | goto err; | 785 | goto err; |
| 786 | if (!BN_mod_lshift_quick(n2, n2, 2, p)) | 786 | if (!BN_mod_lshift_quick(n2, n2, 2, p)) |
| 787 | goto err; | 787 | goto err; |
| @@ -790,9 +790,9 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 790 | /* X_r */ | 790 | /* X_r */ |
| 791 | if (!BN_mod_lshift1_quick(n0, n2, p)) | 791 | if (!BN_mod_lshift1_quick(n0, n2, p)) |
| 792 | goto err; | 792 | goto err; |
| 793 | if (!field_sqr(group, &r->X, n1, ctx)) | 793 | if (!field_sqr(group, r->X, n1, ctx)) |
| 794 | goto err; | 794 | goto err; |
| 795 | if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) | 795 | if (!BN_mod_sub_quick(r->X, r->X, n0, p)) |
| 796 | goto err; | 796 | goto err; |
| 797 | /* X_r = n1^2 - 2 * n2 */ | 797 | /* X_r = n1^2 - 2 * n2 */ |
| 798 | 798 | ||
| @@ -804,11 +804,11 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 804 | /* n3 = 8 * Y_a^4 */ | 804 | /* n3 = 8 * Y_a^4 */ |
| 805 | 805 | ||
| 806 | /* Y_r */ | 806 | /* Y_r */ |
| 807 | if (!BN_mod_sub_quick(n0, n2, &r->X, p)) | 807 | if (!BN_mod_sub_quick(n0, n2, r->X, p)) |
| 808 | goto err; | 808 | goto err; |
| 809 | if (!field_mul(group, n0, n1, n0, ctx)) | 809 | if (!field_mul(group, n0, n1, n0, ctx)) |
| 810 | goto err; | 810 | goto err; |
| 811 | if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) | 811 | if (!BN_mod_sub_quick(r->Y, n0, n3, p)) |
| 812 | goto err; | 812 | goto err; |
| 813 | /* Y_r = n1 * (n2 - X_r) - n3 */ | 813 | /* Y_r = n1 * (n2 - X_r) - n3 */ |
| 814 | 814 | ||
| @@ -823,11 +823,11 @@ ec_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | |||
| 823 | static int | 823 | static int |
| 824 | ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | 824 | ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) |
| 825 | { | 825 | { |
| 826 | if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) | 826 | if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y)) |
| 827 | /* point is its own inverse */ | 827 | /* point is its own inverse */ |
| 828 | return 1; | 828 | return 1; |
| 829 | 829 | ||
| 830 | return BN_usub(&point->Y, &group->p, &point->Y); | 830 | return BN_usub(point->Y, group->p, point->Y); |
| 831 | } | 831 | } |
| 832 | 832 | ||
| 833 | static int | 833 | static int |
| @@ -844,7 +844,7 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | |||
| 844 | 844 | ||
| 845 | field_mul = group->meth->field_mul; | 845 | field_mul = group->meth->field_mul; |
| 846 | field_sqr = group->meth->field_sqr; | 846 | field_sqr = group->meth->field_sqr; |
| 847 | p = &group->p; | 847 | p = group->p; |
| 848 | 848 | ||
| 849 | BN_CTX_start(ctx); | 849 | BN_CTX_start(ctx); |
| 850 | 850 | ||
| @@ -867,11 +867,11 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | |||
| 867 | */ | 867 | */ |
| 868 | 868 | ||
| 869 | /* rh := X^2 */ | 869 | /* rh := X^2 */ |
| 870 | if (!field_sqr(group, rh, &point->X, ctx)) | 870 | if (!field_sqr(group, rh, point->X, ctx)) |
| 871 | goto err; | 871 | goto err; |
| 872 | 872 | ||
| 873 | if (!point->Z_is_one) { | 873 | if (!point->Z_is_one) { |
| 874 | if (!field_sqr(group, tmp, &point->Z, ctx)) | 874 | if (!field_sqr(group, tmp, point->Z, ctx)) |
| 875 | goto err; | 875 | goto err; |
| 876 | if (!field_sqr(group, Z4, tmp, ctx)) | 876 | if (!field_sqr(group, Z4, tmp, ctx)) |
| 877 | goto err; | 877 | goto err; |
| @@ -886,19 +886,19 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | |||
| 886 | goto err; | 886 | goto err; |
| 887 | if (!BN_mod_sub_quick(rh, rh, tmp, p)) | 887 | if (!BN_mod_sub_quick(rh, rh, tmp, p)) |
| 888 | goto err; | 888 | goto err; |
| 889 | if (!field_mul(group, rh, rh, &point->X, ctx)) | 889 | if (!field_mul(group, rh, rh, point->X, ctx)) |
| 890 | goto err; | 890 | goto err; |
| 891 | } else { | 891 | } else { |
| 892 | if (!field_mul(group, tmp, Z4, &group->a, ctx)) | 892 | if (!field_mul(group, tmp, Z4, group->a, ctx)) |
| 893 | goto err; | 893 | goto err; |
| 894 | if (!BN_mod_add_quick(rh, rh, tmp, p)) | 894 | if (!BN_mod_add_quick(rh, rh, tmp, p)) |
| 895 | goto err; | 895 | goto err; |
| 896 | if (!field_mul(group, rh, rh, &point->X, ctx)) | 896 | if (!field_mul(group, rh, rh, point->X, ctx)) |
| 897 | goto err; | 897 | goto err; |
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | /* rh := rh + b*Z^6 */ | 900 | /* rh := rh + b*Z^6 */ |
| 901 | if (!field_mul(group, tmp, &group->b, Z6, ctx)) | 901 | if (!field_mul(group, tmp, group->b, Z6, ctx)) |
| 902 | goto err; | 902 | goto err; |
| 903 | if (!BN_mod_add_quick(rh, rh, tmp, p)) | 903 | if (!BN_mod_add_quick(rh, rh, tmp, p)) |
| 904 | goto err; | 904 | goto err; |
| @@ -906,17 +906,17 @@ ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | |||
| 906 | /* point->Z_is_one */ | 906 | /* point->Z_is_one */ |
| 907 | 907 | ||
| 908 | /* rh := (rh + a)*X */ | 908 | /* rh := (rh + a)*X */ |
| 909 | if (!BN_mod_add_quick(rh, rh, &group->a, p)) | 909 | if (!BN_mod_add_quick(rh, rh, group->a, p)) |
| 910 | goto err; | 910 | goto err; |
| 911 | if (!field_mul(group, rh, rh, &point->X, ctx)) | 911 | if (!field_mul(group, rh, rh, point->X, ctx)) |
| 912 | goto err; | 912 | goto err; |
| 913 | /* rh := rh + b */ | 913 | /* rh := rh + b */ |
| 914 | if (!BN_mod_add_quick(rh, rh, &group->b, p)) | 914 | if (!BN_mod_add_quick(rh, rh, group->b, p)) |
| 915 | goto err; | 915 | goto err; |
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | /* 'lh' := Y^2 */ | 918 | /* 'lh' := Y^2 */ |
| 919 | if (!field_sqr(group, tmp, &point->Y, ctx)) | 919 | if (!field_sqr(group, tmp, point->Y, ctx)) |
| 920 | goto err; | 920 | goto err; |
| 921 | 921 | ||
| 922 | ret = (0 == BN_ucmp(tmp, rh)); | 922 | ret = (0 == BN_ucmp(tmp, rh)); |
| @@ -946,7 +946,7 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | |||
| 946 | return 1; | 946 | return 1; |
| 947 | 947 | ||
| 948 | if (a->Z_is_one && b->Z_is_one) | 948 | if (a->Z_is_one && b->Z_is_one) |
| 949 | return BN_cmp(&a->X, &b->X) != 0 || BN_cmp(&a->Y, &b->Y) != 0; | 949 | return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0; |
| 950 | 950 | ||
| 951 | field_mul = group->meth->field_mul; | 951 | field_mul = group->meth->field_mul; |
| 952 | field_sqr = group->meth->field_sqr; | 952 | field_sqr = group->meth->field_sqr; |
| @@ -969,21 +969,21 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | |||
| 969 | */ | 969 | */ |
| 970 | 970 | ||
| 971 | if (!b->Z_is_one) { | 971 | if (!b->Z_is_one) { |
| 972 | if (!field_sqr(group, Zb23, &b->Z, ctx)) | 972 | if (!field_sqr(group, Zb23, b->Z, ctx)) |
| 973 | goto end; | 973 | goto end; |
| 974 | if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) | 974 | if (!field_mul(group, tmp1, a->X, Zb23, ctx)) |
| 975 | goto end; | 975 | goto end; |
| 976 | tmp1_ = tmp1; | 976 | tmp1_ = tmp1; |
| 977 | } else | 977 | } else |
| 978 | tmp1_ = &a->X; | 978 | tmp1_ = a->X; |
| 979 | if (!a->Z_is_one) { | 979 | if (!a->Z_is_one) { |
| 980 | if (!field_sqr(group, Za23, &a->Z, ctx)) | 980 | if (!field_sqr(group, Za23, a->Z, ctx)) |
| 981 | goto end; | 981 | goto end; |
| 982 | if (!field_mul(group, tmp2, &b->X, Za23, ctx)) | 982 | if (!field_mul(group, tmp2, b->X, Za23, ctx)) |
| 983 | goto end; | 983 | goto end; |
| 984 | tmp2_ = tmp2; | 984 | tmp2_ = tmp2; |
| 985 | } else | 985 | } else |
| 986 | tmp2_ = &b->X; | 986 | tmp2_ = b->X; |
| 987 | 987 | ||
| 988 | /* compare X_a*Z_b^2 with X_b*Z_a^2 */ | 988 | /* compare X_a*Z_b^2 with X_b*Z_a^2 */ |
| 989 | if (BN_cmp(tmp1_, tmp2_) != 0) { | 989 | if (BN_cmp(tmp1_, tmp2_) != 0) { |
| @@ -991,21 +991,21 @@ ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | |||
| 991 | goto end; | 991 | goto end; |
| 992 | } | 992 | } |
| 993 | if (!b->Z_is_one) { | 993 | if (!b->Z_is_one) { |
| 994 | if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) | 994 | if (!field_mul(group, Zb23, Zb23, b->Z, ctx)) |
| 995 | goto end; | 995 | goto end; |
| 996 | if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) | 996 | if (!field_mul(group, tmp1, a->Y, Zb23, ctx)) |
| 997 | goto end; | 997 | goto end; |
| 998 | /* tmp1_ = tmp1 */ | 998 | /* tmp1_ = tmp1 */ |
| 999 | } else | 999 | } else |
| 1000 | tmp1_ = &a->Y; | 1000 | tmp1_ = a->Y; |
| 1001 | if (!a->Z_is_one) { | 1001 | if (!a->Z_is_one) { |
| 1002 | if (!field_mul(group, Za23, Za23, &a->Z, ctx)) | 1002 | if (!field_mul(group, Za23, Za23, a->Z, ctx)) |
| 1003 | goto end; | 1003 | goto end; |
| 1004 | if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) | 1004 | if (!field_mul(group, tmp2, b->Y, Za23, ctx)) |
| 1005 | goto end; | 1005 | goto end; |
| 1006 | /* tmp2_ = tmp2 */ | 1006 | /* tmp2_ = tmp2 */ |
| 1007 | } else | 1007 | } else |
| 1008 | tmp2_ = &b->Y; | 1008 | tmp2_ = b->Y; |
| 1009 | 1009 | ||
| 1010 | /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ | 1010 | /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ |
| 1011 | if (BN_cmp(tmp1_, tmp2_) != 0) { | 1011 | if (BN_cmp(tmp1_, tmp2_) != 0) { |
| @@ -1084,8 +1084,8 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 1084 | * skipping any zero-valued inputs (pretend that they're 1). | 1084 | * skipping any zero-valued inputs (pretend that they're 1). |
| 1085 | */ | 1085 | */ |
| 1086 | 1086 | ||
| 1087 | if (!BN_is_zero(&points[0]->Z)) { | 1087 | if (!BN_is_zero(points[0]->Z)) { |
| 1088 | if (!bn_copy(prod_Z[0], &points[0]->Z)) | 1088 | if (!bn_copy(prod_Z[0], points[0]->Z)) |
| 1089 | goto err; | 1089 | goto err; |
| 1090 | } else { | 1090 | } else { |
| 1091 | if (group->meth->field_set_to_one != NULL) { | 1091 | if (group->meth->field_set_to_one != NULL) { |
| @@ -1098,9 +1098,9 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 1098 | } | 1098 | } |
| 1099 | 1099 | ||
| 1100 | for (i = 1; i < num; i++) { | 1100 | for (i = 1; i < num; i++) { |
| 1101 | if (!BN_is_zero(&points[i]->Z)) { | 1101 | if (!BN_is_zero(points[i]->Z)) { |
| 1102 | if (!group->meth->field_mul(group, prod_Z[i], | 1102 | if (!group->meth->field_mul(group, prod_Z[i], |
| 1103 | prod_Z[i - 1], &points[i]->Z, ctx)) | 1103 | prod_Z[i - 1], points[i]->Z, ctx)) |
| 1104 | goto err; | 1104 | goto err; |
| 1105 | } else { | 1105 | } else { |
| 1106 | if (!bn_copy(prod_Z[i], prod_Z[i - 1])) | 1106 | if (!bn_copy(prod_Z[i], prod_Z[i - 1])) |
| @@ -1112,7 +1112,7 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 1112 | * Now use a single explicit inversion to replace every non-zero | 1112 | * Now use a single explicit inversion to replace every non-zero |
| 1113 | * points[i]->Z by its inverse. | 1113 | * points[i]->Z by its inverse. |
| 1114 | */ | 1114 | */ |
| 1115 | if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], &group->p, ctx)) { | 1115 | if (!BN_mod_inverse_nonct(tmp, prod_Z[num - 1], group->p, ctx)) { |
| 1116 | ECerror(ERR_R_BN_LIB); | 1116 | ECerror(ERR_R_BN_LIB); |
| 1117 | goto err; | 1117 | goto err; |
| 1118 | } | 1118 | } |
| @@ -1134,23 +1134,23 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 1134 | * Loop invariant: tmp is the product of the inverses of | 1134 | * Loop invariant: tmp is the product of the inverses of |
| 1135 | * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped). | 1135 | * points[0]->Z, ..., points[i]->Z (zero-valued inputs skipped). |
| 1136 | */ | 1136 | */ |
| 1137 | if (BN_is_zero(&points[i]->Z)) | 1137 | if (BN_is_zero(points[i]->Z)) |
| 1138 | continue; | 1138 | continue; |
| 1139 | 1139 | ||
| 1140 | /* Set tmp_Z to the inverse of points[i]->Z. */ | 1140 | /* Set tmp_Z to the inverse of points[i]->Z. */ |
| 1141 | if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) | 1141 | if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) |
| 1142 | goto err; | 1142 | goto err; |
| 1143 | /* Adjust tmp to satisfy loop invariant. */ | 1143 | /* Adjust tmp to satisfy loop invariant. */ |
| 1144 | if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) | 1144 | if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx)) |
| 1145 | goto err; | 1145 | goto err; |
| 1146 | /* Replace points[i]->Z by its inverse. */ | 1146 | /* Replace points[i]->Z by its inverse. */ |
| 1147 | if (!bn_copy(&points[i]->Z, tmp_Z)) | 1147 | if (!bn_copy(points[i]->Z, tmp_Z)) |
| 1148 | goto err; | 1148 | goto err; |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | if (!BN_is_zero(&points[0]->Z)) { | 1151 | if (!BN_is_zero(points[0]->Z)) { |
| 1152 | /* Replace points[0]->Z by its inverse. */ | 1152 | /* Replace points[0]->Z by its inverse. */ |
| 1153 | if (!bn_copy(&points[0]->Z, tmp)) | 1153 | if (!bn_copy(points[0]->Z, tmp)) |
| 1154 | goto err; | 1154 | goto err; |
| 1155 | } | 1155 | } |
| 1156 | 1156 | ||
| @@ -1158,26 +1158,26 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 1158 | for (i = 0; i < num; i++) { | 1158 | for (i = 0; i < num; i++) { |
| 1159 | EC_POINT *p = points[i]; | 1159 | EC_POINT *p = points[i]; |
| 1160 | 1160 | ||
| 1161 | if (BN_is_zero(&p->Z)) | 1161 | if (BN_is_zero(p->Z)) |
| 1162 | continue; | 1162 | continue; |
| 1163 | 1163 | ||
| 1164 | /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ | 1164 | /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ |
| 1165 | 1165 | ||
| 1166 | if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) | 1166 | if (!group->meth->field_sqr(group, tmp, p->Z, ctx)) |
| 1167 | goto err; | 1167 | goto err; |
| 1168 | if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) | 1168 | if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx)) |
| 1169 | goto err; | 1169 | goto err; |
| 1170 | 1170 | ||
| 1171 | if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) | 1171 | if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx)) |
| 1172 | goto err; | 1172 | goto err; |
| 1173 | if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) | 1173 | if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx)) |
| 1174 | goto err; | 1174 | goto err; |
| 1175 | 1175 | ||
| 1176 | if (group->meth->field_set_to_one != NULL) { | 1176 | if (group->meth->field_set_to_one != NULL) { |
| 1177 | if (!group->meth->field_set_to_one(group, &p->Z, ctx)) | 1177 | if (!group->meth->field_set_to_one(group, p->Z, ctx)) |
| 1178 | goto err; | 1178 | goto err; |
| 1179 | } else { | 1179 | } else { |
| 1180 | if (!BN_one(&p->Z)) | 1180 | if (!BN_one(p->Z)) |
| 1181 | goto err; | 1181 | goto err; |
| 1182 | } | 1182 | } |
| 1183 | p->Z_is_one = 1; | 1183 | p->Z_is_one = 1; |
| @@ -1196,13 +1196,13 @@ static int | |||
| 1196 | ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, | 1196 | ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, |
| 1197 | BN_CTX *ctx) | 1197 | BN_CTX *ctx) |
| 1198 | { | 1198 | { |
| 1199 | return BN_mod_mul(r, a, b, &group->p, ctx); | 1199 | return BN_mod_mul(r, a, b, group->p, ctx); |
| 1200 | } | 1200 | } |
| 1201 | 1201 | ||
| 1202 | static int | 1202 | static int |
| 1203 | ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | 1203 | ec_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) |
| 1204 | { | 1204 | { |
| 1205 | return BN_mod_sqr(r, a, &group->p, ctx); | 1205 | return BN_mod_sqr(r, a, group->p, ctx); |
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | /* | 1208 | /* |
| @@ -1226,7 +1226,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) | |||
| 1226 | goto err; | 1226 | goto err; |
| 1227 | 1227 | ||
| 1228 | /* Generate lambda in [1, p). */ | 1228 | /* Generate lambda in [1, p). */ |
| 1229 | if (!bn_rand_interval(lambda, 1, &group->p)) | 1229 | if (!bn_rand_interval(lambda, 1, group->p)) |
| 1230 | goto err; | 1230 | goto err; |
| 1231 | 1231 | ||
| 1232 | if (group->meth->field_encode != NULL && | 1232 | if (group->meth->field_encode != NULL && |
| @@ -1234,7 +1234,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) | |||
| 1234 | goto err; | 1234 | goto err; |
| 1235 | 1235 | ||
| 1236 | /* Z = lambda * Z */ | 1236 | /* Z = lambda * Z */ |
| 1237 | if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx)) | 1237 | if (!group->meth->field_mul(group, p->Z, lambda, p->Z, ctx)) |
| 1238 | goto err; | 1238 | goto err; |
| 1239 | 1239 | ||
| 1240 | /* tmp = lambda^2 */ | 1240 | /* tmp = lambda^2 */ |
| @@ -1242,7 +1242,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) | |||
| 1242 | goto err; | 1242 | goto err; |
| 1243 | 1243 | ||
| 1244 | /* X = lambda^2 * X */ | 1244 | /* X = lambda^2 * X */ |
| 1245 | if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx)) | 1245 | if (!group->meth->field_mul(group, p->X, tmp, p->X, ctx)) |
| 1246 | goto err; | 1246 | goto err; |
| 1247 | 1247 | ||
| 1248 | /* tmp = lambda^3 */ | 1248 | /* tmp = lambda^3 */ |
| @@ -1250,7 +1250,7 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) | |||
| 1250 | goto err; | 1250 | goto err; |
| 1251 | 1251 | ||
| 1252 | /* Y = lambda^3 * Y */ | 1252 | /* Y = lambda^3 * Y */ |
| 1253 | if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx)) | 1253 | if (!group->meth->field_mul(group, p->Y, tmp, p->Y, ctx)) |
| 1254 | goto err; | 1254 | goto err; |
| 1255 | 1255 | ||
| 1256 | /* Disable optimized arithmetics after replacing Z by lambda * Z. */ | 1256 | /* Disable optimized arithmetics after replacing Z by lambda * Z. */ |
| @@ -1264,15 +1264,15 @@ ec_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) | |||
| 1264 | } | 1264 | } |
| 1265 | 1265 | ||
| 1266 | #define EC_POINT_BN_set_flags(P, flags) do { \ | 1266 | #define EC_POINT_BN_set_flags(P, flags) do { \ |
| 1267 | BN_set_flags(&(P)->X, (flags)); \ | 1267 | BN_set_flags((P)->X, (flags)); \ |
| 1268 | BN_set_flags(&(P)->Y, (flags)); \ | 1268 | BN_set_flags((P)->Y, (flags)); \ |
| 1269 | BN_set_flags(&(P)->Z, (flags)); \ | 1269 | BN_set_flags((P)->Z, (flags)); \ |
| 1270 | } while(0) | 1270 | } while(0) |
| 1271 | 1271 | ||
| 1272 | #define EC_POINT_CSWAP(c, a, b, w, t) do { \ | 1272 | #define EC_POINT_CSWAP(c, a, b, w, t) do { \ |
| 1273 | if (!BN_swap_ct(c, &(a)->X, &(b)->X, w) || \ | 1273 | if (!BN_swap_ct(c, (a)->X, (b)->X, w) || \ |
| 1274 | !BN_swap_ct(c, &(a)->Y, &(b)->Y, w) || \ | 1274 | !BN_swap_ct(c, (a)->Y, (b)->Y, w) || \ |
| 1275 | !BN_swap_ct(c, &(a)->Z, &(b)->Z, w)) \ | 1275 | !BN_swap_ct(c, (a)->Z, (b)->Z, w)) \ |
| 1276 | goto err; \ | 1276 | goto err; \ |
| 1277 | t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ | 1277 | t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ |
| 1278 | (a)->Z_is_one ^= (t); \ | 1278 | (a)->Z_is_one ^= (t); \ |
| @@ -1332,7 +1332,7 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | |||
| 1332 | goto err; | 1332 | goto err; |
| 1333 | if ((k = BN_CTX_get(ctx)) == NULL) | 1333 | if ((k = BN_CTX_get(ctx)) == NULL) |
| 1334 | goto err; | 1334 | goto err; |
| 1335 | if (!BN_mul(cardinality, &group->order, &group->cofactor, ctx)) | 1335 | if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) |
| 1336 | goto err; | 1336 | goto err; |
| 1337 | 1337 | ||
| 1338 | /* | 1338 | /* |
| @@ -1374,13 +1374,13 @@ ec_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | |||
| 1374 | if (!BN_swap_ct(kbit, k, lambda, group_top + 2)) | 1374 | if (!BN_swap_ct(kbit, k, lambda, group_top + 2)) |
| 1375 | goto err; | 1375 | goto err; |
| 1376 | 1376 | ||
| 1377 | group_top = group->p.top; | 1377 | group_top = group->p->top; |
| 1378 | if (!bn_wexpand(&s->X, group_top) || | 1378 | if (!bn_wexpand(s->X, group_top) || |
| 1379 | !bn_wexpand(&s->Y, group_top) || | 1379 | !bn_wexpand(s->Y, group_top) || |
| 1380 | !bn_wexpand(&s->Z, group_top) || | 1380 | !bn_wexpand(s->Z, group_top) || |
| 1381 | !bn_wexpand(&r->X, group_top) || | 1381 | !bn_wexpand(r->X, group_top) || |
| 1382 | !bn_wexpand(&r->Y, group_top) || | 1382 | !bn_wexpand(r->Y, group_top) || |
| 1383 | !bn_wexpand(&r->Z, group_top)) | 1383 | !bn_wexpand(r->Z, group_top)) |
| 1384 | goto err; | 1384 | goto err; |
| 1385 | 1385 | ||
| 1386 | /* | 1386 | /* |
