diff options
| author | tb <> | 2023-07-26 12:24:28 +0000 |
|---|---|---|
| committer | tb <> | 2023-07-26 12:24:28 +0000 |
| commit | d532e9694d3555ade9ab916e9b71cfc075ca6ccc (patch) | |
| tree | f9770131766b05408b2bc149fdd1f6af7f20a0c6 /src | |
| parent | 076e388cece872bf7c1f674b4d0ee8beae919c8b (diff) | |
| download | openbsd-d532e9694d3555ade9ab916e9b71cfc075ca6ccc.tar.gz openbsd-d532e9694d3555ade9ab916e9b71cfc075ca6ccc.tar.bz2 openbsd-d532e9694d3555ade9ab916e9b71cfc075ca6ccc.zip | |
Introduce and use ec_encode_scalar()
This introduces two "inverses" of the ec_decode_scalar() function that take
a BIGNUM, reduce it modulo p and then encodes it into the curve's field
representation. For setting projective coordinates, we need a specialized
helper that deals with the Z_is_one optimization that is used to optimize
for calculations in standard affine coordinates of the projective plane.
This is used for simplifying EC_POINT_set_Jprojective_coordinates() and
for cleaning up and streamlining EC_GROUP_set_curve().
ok jsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_smpl.c | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c index 0fd751a2a3..add1348372 100644 --- a/src/lib/libcrypto/ec/ecp_smpl.c +++ b/src/lib/libcrypto/ec/ecp_smpl.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ecp_smpl.c,v 1.52 2023/07/26 12:16:55 tb Exp $ */ | 1 | /* $OpenBSD: ecp_smpl.c,v 1.53 2023/07/26 12:24:28 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. |
| @@ -126,11 +126,40 @@ ec_decode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx | |||
| 126 | return bn_copy(bn, x); | 126 | return bn_copy(bn, x); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static int | ||
| 130 | ec_encode_scalar(const EC_GROUP *group, BIGNUM *bn, const BIGNUM *x, BN_CTX *ctx) | ||
| 131 | { | ||
| 132 | if (!BN_nnmod(bn, x, &group->field, ctx)) | ||
| 133 | return 0; | ||
| 134 | |||
| 135 | if (group->meth->field_encode != NULL) | ||
| 136 | return group->meth->field_encode(group, bn, bn, ctx); | ||
| 137 | |||
| 138 | return 1; | ||
| 139 | } | ||
| 140 | |||
| 141 | static int | ||
| 142 | ec_encode_z_coordinate(const EC_GROUP *group, BIGNUM *bn, int *is_one, | ||
| 143 | const BIGNUM *z, BN_CTX *ctx) | ||
| 144 | { | ||
| 145 | if (!BN_nnmod(bn, z, &group->field, ctx)) | ||
| 146 | return 0; | ||
| 147 | |||
| 148 | *is_one = BN_is_one(bn); | ||
| 149 | if (*is_one && group->meth->field_set_to_one != NULL) | ||
| 150 | return group->meth->field_set_to_one(group, bn, ctx); | ||
| 151 | |||
| 152 | if (group->meth->field_encode != NULL) | ||
| 153 | return group->meth->field_encode(group, bn, bn, ctx); | ||
| 154 | |||
| 155 | return 1; | ||
| 156 | } | ||
| 157 | |||
| 129 | int | 158 | int |
| 130 | ec_GFp_simple_group_set_curve(EC_GROUP *group, | 159 | ec_GFp_simple_group_set_curve(EC_GROUP *group, |
| 131 | const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | 160 | const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) |
| 132 | { | 161 | { |
| 133 | BIGNUM *tmp_a; | 162 | BIGNUM *a_plus_3; |
| 134 | int ret = 0; | 163 | int ret = 0; |
| 135 | 164 | ||
| 136 | /* p must be a prime > 3 */ | 165 | /* p must be a prime > 3 */ |
| @@ -141,34 +170,24 @@ ec_GFp_simple_group_set_curve(EC_GROUP *group, | |||
| 141 | 170 | ||
| 142 | BN_CTX_start(ctx); | 171 | BN_CTX_start(ctx); |
| 143 | 172 | ||
| 144 | if ((tmp_a = BN_CTX_get(ctx)) == NULL) | 173 | if ((a_plus_3 = BN_CTX_get(ctx)) == NULL) |
| 145 | goto err; | 174 | goto err; |
| 146 | 175 | ||
| 147 | /* group->field */ | ||
| 148 | if (!bn_copy(&group->field, p)) | 176 | if (!bn_copy(&group->field, p)) |
| 149 | goto err; | 177 | goto err; |
| 150 | BN_set_negative(&group->field, 0); | 178 | BN_set_negative(&group->field, 0); |
| 151 | 179 | ||
| 152 | /* group->a */ | 180 | if (!ec_encode_scalar(group, &group->a, a, ctx)) |
| 153 | if (!BN_nnmod(tmp_a, a, p, ctx)) | ||
| 154 | goto err; | 181 | goto err; |
| 155 | if (group->meth->field_encode != NULL) { | 182 | if (!ec_encode_scalar(group, &group->b, b, ctx)) |
| 156 | if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) | ||
| 157 | goto err; | ||
| 158 | } else if (!bn_copy(&group->a, tmp_a)) | ||
| 159 | goto err; | 183 | goto err; |
| 160 | 184 | ||
| 161 | /* group->b */ | 185 | if (!BN_set_word(a_plus_3, 3)) |
| 162 | if (!BN_nnmod(&group->b, b, p, ctx)) | ||
| 163 | goto err; | 186 | goto err; |
| 164 | if (group->meth->field_encode != NULL) | 187 | if (!BN_mod_add(a_plus_3, a_plus_3, a, &group->field, ctx)) |
| 165 | if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) | ||
| 166 | goto err; | ||
| 167 | |||
| 168 | /* group->a_is_minus3 */ | ||
| 169 | if (!BN_add_word(tmp_a, 3)) | ||
| 170 | goto err; | 188 | goto err; |
| 171 | group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); | 189 | |
| 190 | group->a_is_minus3 = BN_is_zero(a_plus_3); | ||
| 172 | 191 | ||
| 173 | ret = 1; | 192 | ret = 1; |
| 174 | 193 | ||
| @@ -306,39 +325,25 @@ ec_GFp_simple_set_Jprojective_coordinates(const EC_GROUP *group, | |||
| 306 | { | 325 | { |
| 307 | int ret = 0; | 326 | int ret = 0; |
| 308 | 327 | ||
| 328 | /* | ||
| 329 | * Setting individual coordinates allows the creation of bad points. | ||
| 330 | * EC_POINT_set_Jprojective_coordinates() checks at the API boundary. | ||
| 331 | */ | ||
| 332 | |||
| 309 | if (x != NULL) { | 333 | if (x != NULL) { |
| 310 | if (!BN_nnmod(&point->X, x, &group->field, ctx)) | 334 | if (!ec_encode_scalar(group, &point->X, x, ctx)) |
| 311 | goto err; | 335 | goto err; |
| 312 | if (group->meth->field_encode != NULL) { | ||
| 313 | if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) | ||
| 314 | goto err; | ||
| 315 | } | ||
| 316 | } | 336 | } |
| 317 | if (y != NULL) { | 337 | if (y != NULL) { |
| 318 | if (!BN_nnmod(&point->Y, y, &group->field, ctx)) | 338 | if (!ec_encode_scalar(group, &point->Y, y, ctx)) |
| 319 | goto err; | 339 | goto err; |
| 320 | if (group->meth->field_encode != NULL) { | ||
| 321 | if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) | ||
| 322 | goto err; | ||
| 323 | } | ||
| 324 | } | 340 | } |
| 325 | if (z != NULL) { | 341 | if (z != NULL) { |
| 326 | int Z_is_one; | 342 | if (!ec_encode_z_coordinate(group, &point->Z, &point->Z_is_one, |
| 327 | 343 | z, ctx)) | |
| 328 | if (!BN_nnmod(&point->Z, z, &group->field, ctx)) | ||
| 329 | goto err; | 344 | goto err; |
| 330 | Z_is_one = BN_is_one(&point->Z); | ||
| 331 | if (group->meth->field_encode != NULL) { | ||
| 332 | if (Z_is_one && (group->meth->field_set_to_one != NULL)) { | ||
| 333 | if (!group->meth->field_set_to_one(group, &point->Z, ctx)) | ||
| 334 | goto err; | ||
| 335 | } else { | ||
| 336 | if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) | ||
| 337 | goto err; | ||
| 338 | } | ||
| 339 | } | ||
| 340 | point->Z_is_one = Z_is_one; | ||
| 341 | } | 345 | } |
| 346 | |||
| 342 | ret = 1; | 347 | ret = 1; |
| 343 | 348 | ||
| 344 | err: | 349 | err: |
