diff options
author | tb <> | 2023-07-26 12:24:28 +0000 |
---|---|---|
committer | tb <> | 2023-07-26 12:24:28 +0000 |
commit | 51094273f9913bba740b53ddcc63a0b674702656 (patch) | |
tree | f9770131766b05408b2bc149fdd1f6af7f20a0c6 | |
parent | 7ddfedb8239257acd9515c7a6b28b9dbbbde2cc6 (diff) | |
download | openbsd-51094273f9913bba740b53ddcc63a0b674702656.tar.gz openbsd-51094273f9913bba740b53ddcc63a0b674702656.tar.bz2 openbsd-51094273f9913bba740b53ddcc63a0b674702656.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
-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: |