summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2025-01-11 15:20:23 +0000
committertb <>2025-01-11 15:20:23 +0000
commit278e0b465548a0a6ec9f52855fc196e28cb7513b (patch)
tree8ed22a01f40bb509a22ccb7ce7d7c3e3b77e5b18
parent8bbda20016e5c5fe4b795ed53292cc98a0c9232f (diff)
downloadopenbsd-278e0b465548a0a6ec9f52855fc196e28cb7513b.tar.gz
openbsd-278e0b465548a0a6ec9f52855fc196e28cb7513b.tar.bz2
openbsd-278e0b465548a0a6ec9f52855fc196e28cb7513b.zip
Move is_on_curve() and (point) cmp() up
These were in the middle of the methods responsible for curve operations, which makes little sense.
-rw-r--r--src/lib/libcrypto/ec/ec_local.h10
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c392
2 files changed, 201 insertions, 201 deletions
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 674023050c..66ff15a4f8 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.57 2025/01/11 15:02:42 tb Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.58 2025/01/11 15:20:23 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 */
@@ -87,6 +87,10 @@ struct ec_method_st {
87 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, 87 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
88 BIGNUM *b, BN_CTX *); 88 BIGNUM *b, BN_CTX *);
89 89
90 int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
91 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
92 BN_CTX *);
93
90 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *, 94 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
91 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 95 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
92 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, 96 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
@@ -101,10 +105,6 @@ struct ec_method_st {
101 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); 105 int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
102 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *); 106 int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
103 107
104 int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
105 int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
106 BN_CTX *);
107
108 int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r, 108 int (*mul_generator_ct)(const EC_GROUP *, EC_POINT *r,
109 const BIGNUM *scalar, BN_CTX *); 109 const BIGNUM *scalar, BN_CTX *);
110 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r, 110 int (*mul_single_ct)(const EC_GROUP *group, EC_POINT *r,
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 66bde292a8..8477fa547f 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.31 2025/01/11 15:02:42 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.32 2025/01/11 15:20:23 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.
@@ -167,6 +167,197 @@ ec_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
167} 167}
168 168
169static int 169static int
170ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
171{
172 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
173 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
174 const BIGNUM *p;
175 BIGNUM *rh, *tmp, *Z4, *Z6;
176 int ret = -1;
177
178 if (EC_POINT_is_at_infinity(group, point))
179 return 1;
180
181 field_mul = group->meth->field_mul;
182 field_sqr = group->meth->field_sqr;
183 p = group->p;
184
185 BN_CTX_start(ctx);
186
187 if ((rh = BN_CTX_get(ctx)) == NULL)
188 goto err;
189 if ((tmp = BN_CTX_get(ctx)) == NULL)
190 goto err;
191 if ((Z4 = BN_CTX_get(ctx)) == NULL)
192 goto err;
193 if ((Z6 = BN_CTX_get(ctx)) == NULL)
194 goto err;
195
196 /*
197 * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x
198 * + b. The point to consider is given in Jacobian projective
199 * coordinates where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
200 * Substituting this and multiplying by Z^6 transforms the above
201 * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up
202 * the right-hand side in 'rh'.
203 */
204
205 /* rh := X^2 */
206 if (!field_sqr(group, rh, point->X, ctx))
207 goto err;
208
209 if (!point->Z_is_one) {
210 if (!field_sqr(group, tmp, point->Z, ctx))
211 goto err;
212 if (!field_sqr(group, Z4, tmp, ctx))
213 goto err;
214 if (!field_mul(group, Z6, Z4, tmp, ctx))
215 goto err;
216
217 /* rh := (rh + a*Z^4)*X */
218 if (group->a_is_minus3) {
219 if (!BN_mod_lshift1_quick(tmp, Z4, p))
220 goto err;
221 if (!BN_mod_add_quick(tmp, tmp, Z4, p))
222 goto err;
223 if (!BN_mod_sub_quick(rh, rh, tmp, p))
224 goto err;
225 if (!field_mul(group, rh, rh, point->X, ctx))
226 goto err;
227 } else {
228 if (!field_mul(group, tmp, Z4, group->a, ctx))
229 goto err;
230 if (!BN_mod_add_quick(rh, rh, tmp, p))
231 goto err;
232 if (!field_mul(group, rh, rh, point->X, ctx))
233 goto err;
234 }
235
236 /* rh := rh + b*Z^6 */
237 if (!field_mul(group, tmp, group->b, Z6, ctx))
238 goto err;
239 if (!BN_mod_add_quick(rh, rh, tmp, p))
240 goto err;
241 } else {
242 /* point->Z_is_one */
243
244 /* rh := (rh + a)*X */
245 if (!BN_mod_add_quick(rh, rh, group->a, p))
246 goto err;
247 if (!field_mul(group, rh, rh, point->X, ctx))
248 goto err;
249 /* rh := rh + b */
250 if (!BN_mod_add_quick(rh, rh, group->b, p))
251 goto err;
252 }
253
254 /* 'lh' := Y^2 */
255 if (!field_sqr(group, tmp, point->Y, ctx))
256 goto err;
257
258 ret = (0 == BN_ucmp(tmp, rh));
259
260 err:
261 BN_CTX_end(ctx);
262
263 return ret;
264}
265
266/*
267 * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
268 */
269
270static int
271ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
272{
273 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
274 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
275 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
276 const BIGNUM *tmp1_, *tmp2_;
277 int ret = -1;
278
279 if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b))
280 return 0;
281 if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
282 return 1;
283
284 if (a->Z_is_one && b->Z_is_one)
285 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
286
287 field_mul = group->meth->field_mul;
288 field_sqr = group->meth->field_sqr;
289
290 BN_CTX_start(ctx);
291
292 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
293 goto end;
294 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
295 goto end;
296 if ((Za23 = BN_CTX_get(ctx)) == NULL)
297 goto end;
298 if ((Zb23 = BN_CTX_get(ctx)) == NULL)
299 goto end;
300
301 /*
302 * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2,
303 * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) =
304 * (X_b*Z_a^2, Y_b*Z_a^3).
305 */
306
307 if (!b->Z_is_one) {
308 if (!field_sqr(group, Zb23, b->Z, ctx))
309 goto end;
310 if (!field_mul(group, tmp1, a->X, Zb23, ctx))
311 goto end;
312 tmp1_ = tmp1;
313 } else
314 tmp1_ = a->X;
315 if (!a->Z_is_one) {
316 if (!field_sqr(group, Za23, a->Z, ctx))
317 goto end;
318 if (!field_mul(group, tmp2, b->X, Za23, ctx))
319 goto end;
320 tmp2_ = tmp2;
321 } else
322 tmp2_ = b->X;
323
324 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
325 if (BN_cmp(tmp1_, tmp2_) != 0) {
326 ret = 1; /* points differ */
327 goto end;
328 }
329 if (!b->Z_is_one) {
330 if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
331 goto end;
332 if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
333 goto end;
334 /* tmp1_ = tmp1 */
335 } else
336 tmp1_ = a->Y;
337 if (!a->Z_is_one) {
338 if (!field_mul(group, Za23, Za23, a->Z, ctx))
339 goto end;
340 if (!field_mul(group, tmp2, b->Y, Za23, ctx))
341 goto end;
342 /* tmp2_ = tmp2 */
343 } else
344 tmp2_ = b->Y;
345
346 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
347 if (BN_cmp(tmp1_, tmp2_) != 0) {
348 ret = 1; /* points differ */
349 goto end;
350 }
351 /* points are equal */
352 ret = 0;
353
354 end:
355 BN_CTX_end(ctx);
356
357 return ret;
358}
359
360static int
170ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 361ec_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
171 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 362 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
172{ 363{
@@ -737,197 +928,6 @@ ec_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
737} 928}
738 929
739static int 930static int
740ec_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
741{
742 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
743 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
744 const BIGNUM *p;
745 BIGNUM *rh, *tmp, *Z4, *Z6;
746 int ret = -1;
747
748 if (EC_POINT_is_at_infinity(group, point))
749 return 1;
750
751 field_mul = group->meth->field_mul;
752 field_sqr = group->meth->field_sqr;
753 p = group->p;
754
755 BN_CTX_start(ctx);
756
757 if ((rh = BN_CTX_get(ctx)) == NULL)
758 goto err;
759 if ((tmp = BN_CTX_get(ctx)) == NULL)
760 goto err;
761 if ((Z4 = BN_CTX_get(ctx)) == NULL)
762 goto err;
763 if ((Z6 = BN_CTX_get(ctx)) == NULL)
764 goto err;
765
766 /*
767 * We have a curve defined by a Weierstrass equation y^2 = x^3 + a*x
768 * + b. The point to consider is given in Jacobian projective
769 * coordinates where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
770 * Substituting this and multiplying by Z^6 transforms the above
771 * equation into Y^2 = X^3 + a*X*Z^4 + b*Z^6. To test this, we add up
772 * the right-hand side in 'rh'.
773 */
774
775 /* rh := X^2 */
776 if (!field_sqr(group, rh, point->X, ctx))
777 goto err;
778
779 if (!point->Z_is_one) {
780 if (!field_sqr(group, tmp, point->Z, ctx))
781 goto err;
782 if (!field_sqr(group, Z4, tmp, ctx))
783 goto err;
784 if (!field_mul(group, Z6, Z4, tmp, ctx))
785 goto err;
786
787 /* rh := (rh + a*Z^4)*X */
788 if (group->a_is_minus3) {
789 if (!BN_mod_lshift1_quick(tmp, Z4, p))
790 goto err;
791 if (!BN_mod_add_quick(tmp, tmp, Z4, p))
792 goto err;
793 if (!BN_mod_sub_quick(rh, rh, tmp, p))
794 goto err;
795 if (!field_mul(group, rh, rh, point->X, ctx))
796 goto err;
797 } else {
798 if (!field_mul(group, tmp, Z4, group->a, ctx))
799 goto err;
800 if (!BN_mod_add_quick(rh, rh, tmp, p))
801 goto err;
802 if (!field_mul(group, rh, rh, point->X, ctx))
803 goto err;
804 }
805
806 /* rh := rh + b*Z^6 */
807 if (!field_mul(group, tmp, group->b, Z6, ctx))
808 goto err;
809 if (!BN_mod_add_quick(rh, rh, tmp, p))
810 goto err;
811 } else {
812 /* point->Z_is_one */
813
814 /* rh := (rh + a)*X */
815 if (!BN_mod_add_quick(rh, rh, group->a, p))
816 goto err;
817 if (!field_mul(group, rh, rh, point->X, ctx))
818 goto err;
819 /* rh := rh + b */
820 if (!BN_mod_add_quick(rh, rh, group->b, p))
821 goto err;
822 }
823
824 /* 'lh' := Y^2 */
825 if (!field_sqr(group, tmp, point->Y, ctx))
826 goto err;
827
828 ret = (0 == BN_ucmp(tmp, rh));
829
830 err:
831 BN_CTX_end(ctx);
832
833 return ret;
834}
835
836/*
837 * Returns -1 on error, 0 if the points are equal, 1 if the points are distinct.
838 */
839
840static int
841ec_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
842{
843 int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
844 int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
845 BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
846 const BIGNUM *tmp1_, *tmp2_;
847 int ret = -1;
848
849 if (EC_POINT_is_at_infinity(group, a) && EC_POINT_is_at_infinity(group, b))
850 return 0;
851 if (EC_POINT_is_at_infinity(group, a) || EC_POINT_is_at_infinity(group, b))
852 return 1;
853
854 if (a->Z_is_one && b->Z_is_one)
855 return BN_cmp(a->X, b->X) != 0 || BN_cmp(a->Y, b->Y) != 0;
856
857 field_mul = group->meth->field_mul;
858 field_sqr = group->meth->field_sqr;
859
860 BN_CTX_start(ctx);
861
862 if ((tmp1 = BN_CTX_get(ctx)) == NULL)
863 goto end;
864 if ((tmp2 = BN_CTX_get(ctx)) == NULL)
865 goto end;
866 if ((Za23 = BN_CTX_get(ctx)) == NULL)
867 goto end;
868 if ((Zb23 = BN_CTX_get(ctx)) == NULL)
869 goto end;
870
871 /*
872 * We have to decide whether (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2,
873 * Y_b/Z_b^3), or equivalently, whether (X_a*Z_b^2, Y_a*Z_b^3) =
874 * (X_b*Z_a^2, Y_b*Z_a^3).
875 */
876
877 if (!b->Z_is_one) {
878 if (!field_sqr(group, Zb23, b->Z, ctx))
879 goto end;
880 if (!field_mul(group, tmp1, a->X, Zb23, ctx))
881 goto end;
882 tmp1_ = tmp1;
883 } else
884 tmp1_ = a->X;
885 if (!a->Z_is_one) {
886 if (!field_sqr(group, Za23, a->Z, ctx))
887 goto end;
888 if (!field_mul(group, tmp2, b->X, Za23, ctx))
889 goto end;
890 tmp2_ = tmp2;
891 } else
892 tmp2_ = b->X;
893
894 /* compare X_a*Z_b^2 with X_b*Z_a^2 */
895 if (BN_cmp(tmp1_, tmp2_) != 0) {
896 ret = 1; /* points differ */
897 goto end;
898 }
899 if (!b->Z_is_one) {
900 if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
901 goto end;
902 if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
903 goto end;
904 /* tmp1_ = tmp1 */
905 } else
906 tmp1_ = a->Y;
907 if (!a->Z_is_one) {
908 if (!field_mul(group, Za23, Za23, a->Z, ctx))
909 goto end;
910 if (!field_mul(group, tmp2, b->Y, Za23, ctx))
911 goto end;
912 /* tmp2_ = tmp2 */
913 } else
914 tmp2_ = b->Y;
915
916 /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
917 if (BN_cmp(tmp1_, tmp2_) != 0) {
918 ret = 1; /* points differ */
919 goto end;
920 }
921 /* points are equal */
922 ret = 0;
923
924 end:
925 BN_CTX_end(ctx);
926
927 return ret;
928}
929
930static int
931ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, 931ec_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
932 BN_CTX *ctx) 932 BN_CTX *ctx)
933{ 933{
@@ -1324,14 +1324,14 @@ static const EC_METHOD ec_GFp_simple_method = {
1324 .field_type = NID_X9_62_prime_field, 1324 .field_type = NID_X9_62_prime_field,
1325 .group_set_curve = ec_group_set_curve, 1325 .group_set_curve = ec_group_set_curve,
1326 .group_get_curve = ec_group_get_curve, 1326 .group_get_curve = ec_group_get_curve,
1327 .is_on_curve = ec_is_on_curve,
1328 .point_cmp = ec_cmp,
1327 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1329 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1328 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1330 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1329 .points_make_affine = ec_points_make_affine, 1331 .points_make_affine = ec_points_make_affine,
1330 .add = ec_add, 1332 .add = ec_add,
1331 .dbl = ec_dbl, 1333 .dbl = ec_dbl,
1332 .invert = ec_invert, 1334 .invert = ec_invert,
1333 .is_on_curve = ec_is_on_curve,
1334 .point_cmp = ec_cmp,
1335 .mul_generator_ct = ec_mul_generator_ct, 1335 .mul_generator_ct = ec_mul_generator_ct,
1336 .mul_single_ct = ec_mul_single_ct, 1336 .mul_single_ct = ec_mul_single_ct,
1337 .mul_double_nonct = ec_mul_double_nonct, 1337 .mul_double_nonct = ec_mul_double_nonct,
@@ -1350,14 +1350,14 @@ static const EC_METHOD ec_GFp_mont_method = {
1350 .field_type = NID_X9_62_prime_field, 1350 .field_type = NID_X9_62_prime_field,
1351 .group_set_curve = ec_mont_group_set_curve, 1351 .group_set_curve = ec_mont_group_set_curve,
1352 .group_get_curve = ec_group_get_curve, 1352 .group_get_curve = ec_group_get_curve,
1353 .is_on_curve = ec_is_on_curve,
1354 .point_cmp = ec_cmp,
1353 .point_set_affine_coordinates = ec_point_set_affine_coordinates, 1355 .point_set_affine_coordinates = ec_point_set_affine_coordinates,
1354 .point_get_affine_coordinates = ec_point_get_affine_coordinates, 1356 .point_get_affine_coordinates = ec_point_get_affine_coordinates,
1355 .points_make_affine = ec_points_make_affine, 1357 .points_make_affine = ec_points_make_affine,
1356 .add = ec_add, 1358 .add = ec_add,
1357 .dbl = ec_dbl, 1359 .dbl = ec_dbl,
1358 .invert = ec_invert, 1360 .invert = ec_invert,
1359 .is_on_curve = ec_is_on_curve,
1360 .point_cmp = ec_cmp,
1361 .mul_generator_ct = ec_mul_generator_ct, 1361 .mul_generator_ct = ec_mul_generator_ct,
1362 .mul_single_ct = ec_mul_single_ct, 1362 .mul_single_ct = ec_mul_single_ct,
1363 .mul_double_nonct = ec_mul_double_nonct, 1363 .mul_double_nonct = ec_mul_double_nonct,