diff options
| author | tb <> | 2024-11-23 12:56:31 +0000 |
|---|---|---|
| committer | tb <> | 2024-11-23 12:56:31 +0000 |
| commit | aa46849736d505ed56c131c6b6717eea90101a5f (patch) | |
| tree | 5f349b025c06f8f850b0169de37a2b219f5ab02f /src/lib/libcrypto/ec/ec_mult.c | |
| parent | 9d99605c17e92dc8a680b04009a670e68b39af57 (diff) | |
| download | openbsd-aa46849736d505ed56c131c6b6717eea90101a5f.tar.gz openbsd-aa46849736d505ed56c131c6b6717eea90101a5f.tar.bz2 openbsd-aa46849736d505ed56c131c6b6717eea90101a5f.zip | |
Further refactoring of the wNAF code
The big change is that the "rows" are no longer slices of val[] but
that they actually own the points they contain. The price for this
is an extra allocation for val[] and to piece it together from the
two rows. That's ugly, but less ugly than before.
Add a helper for freeing a row of points. It can deal with a NULL
row so, we can remove a couple of complications.
The second change is that the logic for preparing the rows is pulled
back into ec_wNAF_mul[]. This way the m * G + n * P logic is in the
one function that needs to know about it, the rest just deals with
a pair of a point and a scalar.
This starts resembling actual code...
ok jsing
Diffstat (limited to 'src/lib/libcrypto/ec/ec_mult.c')
| -rw-r--r-- | src/lib/libcrypto/ec/ec_mult.c | 120 |
1 files changed, 65 insertions, 55 deletions
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c index c33a033805..4944c34a1e 100644 --- a/src/lib/libcrypto/ec/ec_mult.c +++ b/src/lib/libcrypto/ec/ec_mult.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_mult.c,v 1.50 2024/11/23 07:37:21 tb Exp $ */ | 1 | /* $OpenBSD: ec_mult.c,v 1.51 2024/11/23 12:56:31 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. | 3 | * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -61,7 +61,9 @@ | |||
| 61 | * and contributed to the OpenSSL project. | 61 | * and contributed to the OpenSSL project. |
| 62 | */ | 62 | */ |
| 63 | 63 | ||
| 64 | #include <stdint.h> | ||
| 64 | #include <stdlib.h> | 65 | #include <stdlib.h> |
| 66 | #include <string.h> | ||
| 65 | 67 | ||
| 66 | #include <openssl/bn.h> | 68 | #include <openssl/bn.h> |
| 67 | #include <openssl/ec.h> | 69 | #include <openssl/ec.h> |
| @@ -160,15 +162,32 @@ ec_compute_wNAF(const BIGNUM *bn, signed char **out_wNAF, size_t *out_wNAF_len, | |||
| 160 | return ret; | 162 | return ret; |
| 161 | } | 163 | } |
| 162 | 164 | ||
| 165 | static void | ||
| 166 | free_row(EC_POINT **row, size_t row_len) | ||
| 167 | { | ||
| 168 | size_t i; | ||
| 169 | |||
| 170 | if (row == NULL) | ||
| 171 | return; | ||
| 172 | |||
| 173 | for (i = 0; i < row_len; i++) | ||
| 174 | EC_POINT_free(row[i]); | ||
| 175 | free(row); | ||
| 176 | } | ||
| 177 | |||
| 163 | static int | 178 | static int |
| 164 | ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point, | 179 | ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point, |
| 165 | EC_POINT **row, size_t len, BN_CTX *ctx) | 180 | EC_POINT ***out_row, size_t row_len, BN_CTX *ctx) |
| 166 | { | 181 | { |
| 182 | EC_POINT **row = NULL; | ||
| 167 | EC_POINT *doubled = NULL; | 183 | EC_POINT *doubled = NULL; |
| 168 | size_t i; | 184 | size_t i; |
| 169 | int ret = 0; | 185 | int ret = 0; |
| 170 | 186 | ||
| 171 | if (len < 1) | 187 | if (row_len < 1) |
| 188 | goto err; | ||
| 189 | |||
| 190 | if ((row = calloc(row_len, sizeof(*row))) == NULL) | ||
| 172 | goto err; | 191 | goto err; |
| 173 | 192 | ||
| 174 | if ((row[0] = EC_POINT_dup(point, group)) == NULL) | 193 | if ((row[0] = EC_POINT_dup(point, group)) == NULL) |
| @@ -178,84 +197,66 @@ ec_compute_odd_multiples(const EC_GROUP *group, const EC_POINT *point, | |||
| 178 | goto err; | 197 | goto err; |
| 179 | if (!EC_POINT_dbl(group, doubled, point, ctx)) | 198 | if (!EC_POINT_dbl(group, doubled, point, ctx)) |
| 180 | goto err; | 199 | goto err; |
| 181 | for (i = 1; i < len; i++) { | 200 | for (i = 1; i < row_len; i++) { |
| 182 | if ((row[i] = EC_POINT_new(group)) == NULL) | 201 | if ((row[i] = EC_POINT_new(group)) == NULL) |
| 183 | goto err; | 202 | goto err; |
| 184 | if (!EC_POINT_add(group, row[i], row[i - 1], doubled, ctx)) | 203 | if (!EC_POINT_add(group, row[i], row[i - 1], doubled, ctx)) |
| 185 | goto err; | 204 | goto err; |
| 186 | } | 205 | } |
| 187 | 206 | ||
| 207 | *out_row = row; | ||
| 208 | row = NULL; | ||
| 209 | |||
| 188 | ret = 1; | 210 | ret = 1; |
| 189 | 211 | ||
| 190 | err: | 212 | err: |
| 191 | EC_POINT_free(doubled); | 213 | EC_POINT_free(doubled); |
| 214 | free_row(row, row_len); | ||
| 192 | 215 | ||
| 193 | return ret; | 216 | return ret; |
| 194 | } | 217 | } |
| 195 | 218 | ||
| 196 | /* | 219 | /* |
| 197 | * This computes the wNAF representation of m and n and uses the window size to | 220 | * Compute the wNAF representation of m and a list of odd multiples of point. |
| 198 | * precompute the two rows of odd multiples of point and generator. On success, | ||
| 199 | * out_val owns the out_val_len points in the two rows. | ||
| 200 | * | ||
| 201 | * XXX - the only reason we need a single array is to be able to pass it to | ||
| 202 | * EC_POINTs_make_affine(). Consider writing a suitable variant that doesn't | ||
| 203 | * require such grotesque gymnastics. | ||
| 204 | */ | 221 | */ |
| 205 | 222 | ||
| 206 | static int | 223 | static int |
| 207 | ec_wNAF_precompute(const EC_GROUP *group, const BIGNUM *m, const EC_POINT *point, | 224 | ec_compute_row(const EC_GROUP *group, const BIGNUM *m, const EC_POINT *point, |
| 208 | const BIGNUM *n, signed char *wNAF[2], size_t wNAF_len[2], EC_POINT **row[2], | 225 | signed char **wNAF, size_t *wNAF_len, EC_POINT ***out_row, size_t *out_row_len, |
| 209 | EC_POINT ***out_val, size_t *out_val_len, BN_CTX *ctx) | 226 | BN_CTX *ctx) |
| 227 | { | ||
| 228 | if (!ec_compute_wNAF(m, wNAF, wNAF_len, out_row_len)) | ||
| 229 | return 0; | ||
| 230 | if (!ec_compute_odd_multiples(group, point, out_row, *out_row_len, ctx)) | ||
| 231 | return 0; | ||
| 232 | return 1; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int | ||
| 236 | ec_normalize_rows(const EC_GROUP *group, EC_POINT **row0, size_t len0, | ||
| 237 | EC_POINT **row1, size_t len1, BN_CTX *ctx) | ||
| 210 | { | 238 | { |
| 211 | EC_POINT **val = NULL; | 239 | EC_POINT **val = NULL; |
| 212 | size_t val_len = 0; | 240 | size_t len = 0; |
| 213 | const EC_POINT *generator; | ||
| 214 | size_t len[2] = { 0 }; | ||
| 215 | size_t i; | ||
| 216 | int ret = 0; | 241 | int ret = 0; |
| 217 | 242 | ||
| 218 | *out_val = NULL; | 243 | if (len1 > SIZE_MAX - len0) |
| 219 | *out_val_len = 0; | ||
| 220 | |||
| 221 | if ((generator = EC_GROUP_get0_generator(group)) == NULL) { | ||
| 222 | ECerror(EC_R_UNDEFINED_GENERATOR); | ||
| 223 | goto err; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (!ec_compute_wNAF(m, &wNAF[0], &wNAF_len[0], &len[0])) | ||
| 227 | goto err; | ||
| 228 | if (!ec_compute_wNAF(n, &wNAF[1], &wNAF_len[1], &len[1])) | ||
| 229 | goto err; | 244 | goto err; |
| 245 | len = len0 + len1; | ||
| 230 | 246 | ||
| 231 | if ((val = calloc(len[0] + len[1], sizeof(*val))) == NULL) { | 247 | if ((val = calloc(len, sizeof(*val))) == NULL) { |
| 232 | ECerror(ERR_R_MALLOC_FAILURE); | 248 | ECerror(ERR_R_MALLOC_FAILURE); |
| 233 | goto err; | 249 | goto err; |
| 234 | } | 250 | } |
| 235 | val_len = len[0] + len[1]; | 251 | memcpy(&val[0], row0, sizeof(*val) * len0); |
| 236 | 252 | memcpy(&val[len0], row1, sizeof(*val) * len1); | |
| 237 | row[0] = &val[0]; | ||
| 238 | row[1] = &val[len[0]]; | ||
| 239 | 253 | ||
| 240 | if (!ec_compute_odd_multiples(group, generator, row[0], len[0], ctx)) | 254 | if (!EC_POINTs_make_affine(group, len, val, ctx)) |
| 241 | goto err; | 255 | goto err; |
| 242 | if (!ec_compute_odd_multiples(group, point, row[1], len[1], ctx)) | ||
| 243 | goto err; | ||
| 244 | |||
| 245 | if (!EC_POINTs_make_affine(group, val_len, val, ctx)) | ||
| 246 | goto err; | ||
| 247 | |||
| 248 | *out_val = val; | ||
| 249 | val = NULL; | ||
| 250 | |||
| 251 | *out_val_len = val_len; | ||
| 252 | val_len = 0; | ||
| 253 | 256 | ||
| 254 | ret = 1; | 257 | ret = 1; |
| 255 | 258 | ||
| 256 | err: | 259 | err: |
| 257 | for (i = 0; i < val_len; i++) | ||
| 258 | EC_POINT_free(val[i]); | ||
| 259 | free(val); | 260 | free(val); |
| 260 | 261 | ||
| 261 | return ret; | 262 | return ret; |
| @@ -269,11 +270,11 @@ int | |||
| 269 | ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, | 270 | ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, |
| 270 | const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx) | 271 | const EC_POINT *point, const BIGNUM *n, BN_CTX *ctx) |
| 271 | { | 272 | { |
| 273 | const EC_POINT *generator; | ||
| 272 | signed char *wNAF[2] = { 0 }; | 274 | signed char *wNAF[2] = { 0 }; |
| 273 | size_t wNAF_len[2] = { 0 }; | 275 | size_t wNAF_len[2] = { 0 }; |
| 274 | EC_POINT **row[2] = { 0 }; | 276 | EC_POINT **row[2] = { 0 }; |
| 275 | EC_POINT **val = NULL; | 277 | size_t row_len[2] = { 0 }; |
| 276 | size_t val_len = 0; | ||
| 277 | size_t i; | 278 | size_t i; |
| 278 | int k; | 279 | int k; |
| 279 | int r_is_inverted = 0; | 280 | int r_is_inverted = 0; |
| @@ -289,8 +290,18 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, | |||
| 289 | goto err; | 290 | goto err; |
| 290 | } | 291 | } |
| 291 | 292 | ||
| 292 | if (!ec_wNAF_precompute(group, m, point, n, wNAF, wNAF_len, row, | 293 | if ((generator = EC_GROUP_get0_generator(group)) == NULL) { |
| 293 | &val, &val_len, ctx)) | 294 | ECerror(EC_R_UNDEFINED_GENERATOR); |
| 295 | goto err; | ||
| 296 | } | ||
| 297 | |||
| 298 | if (!ec_compute_row(group, m, generator, &wNAF[0], &wNAF_len[0], | ||
| 299 | &row[0], &row_len[0], ctx)) | ||
| 300 | goto err; | ||
| 301 | if (!ec_compute_row(group, n, point, &wNAF[1], &wNAF_len[1], | ||
| 302 | &row[1], &row_len[1], ctx)) | ||
| 303 | goto err; | ||
| 304 | if (!ec_normalize_rows(group, row[0], row_len[0], row[1], row_len[1], ctx)) | ||
| 294 | goto err; | 305 | goto err; |
| 295 | 306 | ||
| 296 | max_len = wNAF_len[0]; | 307 | max_len = wNAF_len[0]; |
| @@ -348,9 +359,8 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *m, | |||
| 348 | err: | 359 | err: |
| 349 | free(wNAF[0]); | 360 | free(wNAF[0]); |
| 350 | free(wNAF[1]); | 361 | free(wNAF[1]); |
| 351 | for (i = 0; i < val_len; i++) | 362 | free_row(row[0], row_len[0]); |
| 352 | EC_POINT_free(val[i]); | 363 | free_row(row[1], row_len[1]); |
| 353 | free(val); | ||
| 354 | 364 | ||
| 355 | return ret; | 365 | return ret; |
| 356 | } | 366 | } |
