summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2023-07-26 12:24:28 +0000
committertb <>2023-07-26 12:24:28 +0000
commit51094273f9913bba740b53ddcc63a0b674702656 (patch)
treef9770131766b05408b2bc149fdd1f6af7f20a0c6
parent7ddfedb8239257acd9515c7a6b28b9dbbbde2cc6 (diff)
downloadopenbsd-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.c91
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
129static int
130ec_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
141static int
142ec_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
129int 158int
130ec_GFp_simple_group_set_curve(EC_GROUP *group, 159ec_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: