summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ec_lib.c
diff options
context:
space:
mode:
authortb <>2025-01-11 15:02:42 +0000
committertb <>2025-01-11 15:02:42 +0000
commit8bbda20016e5c5fe4b795ed53292cc98a0c9232f (patch)
tree292a6d20431880d1a728f0dc021debd5765db59f /src/lib/libcrypto/ec/ec_lib.c
parent793c33000da18d1042676e579534a57987870576 (diff)
downloadopenbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.tar.gz
openbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.tar.bz2
openbsd-8bbda20016e5c5fe4b795ed53292cc98a0c9232f.zip
Move compressed coordinate setting into public API
Now that it is method-agnostic, we can remove the method and move the implementation to the body of the public API function. And another method goes away. We're soon down to the ones we really need. discussed with jsing
Diffstat (limited to 'src/lib/libcrypto/ec/ec_lib.c')
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c89
1 files changed, 81 insertions, 8 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index ed51582146..a8b74ce89d 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.109 2025/01/11 14:38:57 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.110 2025/01/11 15:02:42 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 */
@@ -1026,8 +1026,9 @@ LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates_GFp);
1026 1026
1027int 1027int
1028EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 1028EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
1029 const BIGNUM *x, int y_bit, BN_CTX *ctx_in) 1029 const BIGNUM *in_x, int y_bit, BN_CTX *ctx_in)
1030{ 1030{
1031 BIGNUM *p, *a, *b, *w, *x, *y;
1031 BN_CTX *ctx; 1032 BN_CTX *ctx;
1032 int ret = 0; 1033 int ret = 0;
1033 1034
@@ -1036,18 +1037,90 @@ EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
1036 if (ctx == NULL) 1037 if (ctx == NULL)
1037 goto err; 1038 goto err;
1038 1039
1039 if (group->meth->point_set_compressed_coordinates == NULL) { 1040 y_bit = (y_bit != 0);
1040 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1041
1042 BN_CTX_start(ctx);
1043
1044 if ((p = BN_CTX_get(ctx)) == NULL)
1045 goto err;
1046 if ((a = BN_CTX_get(ctx)) == NULL)
1047 goto err;
1048 if ((b = BN_CTX_get(ctx)) == NULL)
1049 goto err;
1050 if ((w = BN_CTX_get(ctx)) == NULL)
1051 goto err;
1052 if ((x = BN_CTX_get(ctx)) == NULL)
1053 goto err;
1054 if ((y = BN_CTX_get(ctx)) == NULL)
1055 goto err;
1056
1057 /*
1058 * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the
1059 * square roots of x^3 + ax + b. The y-bit indicates which one.
1060 */
1061
1062 if (!EC_GROUP_get_curve(group, p, a, b, ctx))
1063 goto err;
1064
1065 /* XXX - should we not insist on 0 <= x < p instead? */
1066 if (!BN_nnmod(x, in_x, p, ctx))
1067 goto err;
1068
1069 /* y = x^3 */
1070 if (!BN_mod_sqr(y, x, p, ctx))
1071 goto err;
1072 if (!BN_mod_mul(y, y, x, p, ctx))
1073 goto err;
1074
1075 /* y += ax */
1076 if (group->a_is_minus3) {
1077 if (!BN_mod_lshift1_quick(w, x, p))
1078 goto err;
1079 if (!BN_mod_add_quick(w, w, x, p))
1080 goto err;
1081 if (!BN_mod_sub_quick(y, y, w, p))
1082 goto err;
1083 } else {
1084 if (!BN_mod_mul(w, a, x, p, ctx))
1085 goto err;
1086 if (!BN_mod_add_quick(y, y, w, p))
1087 goto err;
1088 }
1089
1090 /* y += b */
1091 if (!BN_mod_add_quick(y, y, b, p))
1092 goto err;
1093
1094 if (!BN_mod_sqrt(y, y, p, ctx)) {
1095 ECerror(EC_R_INVALID_COMPRESSED_POINT);
1041 goto err; 1096 goto err;
1042 } 1097 }
1043 if (group->meth != point->meth) { 1098
1044 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1099 if (y_bit == BN_is_odd(y))
1100 goto done;
1101
1102 if (BN_is_zero(y)) {
1103 ECerror(EC_R_INVALID_COMPRESSION_BIT);
1045 goto err; 1104 goto err;
1046 } 1105 }
1047 ret = group->meth->point_set_compressed_coordinates(group, point, 1106 if (!BN_usub(y, p, y))
1048 x, y_bit, ctx); 1107 goto err;
1108
1109 if (y_bit != BN_is_odd(y)) {
1110 /* Can only happen if p is even and should not be reachable. */
1111 ECerror(ERR_R_INTERNAL_ERROR);
1112 goto err;
1113 }
1114
1115 done:
1116 if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
1117 goto err;
1118
1119 ret = 1;
1049 1120
1050 err: 1121 err:
1122 BN_CTX_end(ctx);
1123
1051 if (ctx != ctx_in) 1124 if (ctx != ctx_in)
1052 BN_CTX_free(ctx); 1125 BN_CTX_free(ctx);
1053 1126