diff options
Diffstat (limited to 'lib/libcrypto/ec/ec_mult.c')
-rw-r--r-- | lib/libcrypto/ec/ec_mult.c | 752 |
1 files changed, 354 insertions, 398 deletions
diff --git a/lib/libcrypto/ec/ec_mult.c b/lib/libcrypto/ec/ec_mult.c index b48c888048b..c0525c49406 100644 --- a/lib/libcrypto/ec/ec_mult.c +++ b/lib/libcrypto/ec/ec_mult.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -80,46 +80,49 @@ /* structure for precomputed multiples of the generator */ typedef struct ec_pre_comp_st { - const EC_GROUP *group; /* parent EC_GROUP object */ - size_t blocksize; /* block size for wNAF splitting */ - size_t numblocks; /* max. number of blocks for which we have precomputation */ - size_t w; /* window size */ - EC_POINT **points; /* array with pre-calculated multiples of generator: - * 'num' pointers to EC_POINT objects followed by a NULL */ - size_t num; /* numblocks * 2^(w-1) */ + const EC_GROUP *group; /* parent EC_GROUP object */ + size_t blocksize; /* block size for wNAF splitting */ + size_t numblocks; /* max. number of blocks for which we have + * precomputation */ + size_t w; /* window size */ + EC_POINT **points; /* array with pre-calculated multiples of + * generator: 'num' pointers to EC_POINT + * objects followed by a NULL */ + size_t num; /* numblocks * 2^(w-1) */ int references; } EC_PRE_COMP; - + /* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */ static void *ec_pre_comp_dup(void *); static void ec_pre_comp_free(void *); static void ec_pre_comp_clear_free(void *); -static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) - { +static EC_PRE_COMP * +ec_pre_comp_new(const EC_GROUP * group) +{ EC_PRE_COMP *ret = NULL; if (!group) return NULL; - ret = (EC_PRE_COMP *)malloc(sizeof(EC_PRE_COMP)); - if (!ret) - { + ret = (EC_PRE_COMP *) malloc(sizeof(EC_PRE_COMP)); + if (!ret) { ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); return ret; - } + } ret->group = group; - ret->blocksize = 8; /* default */ + ret->blocksize = 8; /* default */ ret->numblocks = 0; - ret->w = 4; /* default */ + ret->w = 4; /* default */ ret->points = NULL; ret->num = 0; ret->references = 1; return ret; - } +} -static void *ec_pre_comp_dup(void *src_) - { +static void * +ec_pre_comp_dup(void *src_) +{ EC_PRE_COMP *src = src_; /* no need to actually copy, these objects never change! */ @@ -127,10 +130,11 @@ static void *ec_pre_comp_dup(void *src_) CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); return src_; - } +} -static void ec_pre_comp_free(void *pre_) - { +static void +ec_pre_comp_free(void *pre_) +{ int i; EC_PRE_COMP *pre = pre_; @@ -141,19 +145,19 @@ static void ec_pre_comp_free(void *pre_) if (i > 0) return; - if (pre->points) - { + if (pre->points) { EC_POINT **p; for (p = pre->points; *p != NULL; p++) EC_POINT_free(*p); free(pre->points); - } - free(pre); } + free(pre); +} -static void ec_pre_comp_clear_free(void *pre_) - { +static void +ec_pre_comp_clear_free(void *pre_) +{ int i; EC_PRE_COMP *pre = pre_; @@ -164,20 +168,18 @@ static void ec_pre_comp_clear_free(void *pre_) if (i > 0) return; - if (pre->points) - { + if (pre->points) { EC_POINT **p; - for (p = pre->points; *p != NULL; p++) - { + for (p = pre->points; *p != NULL; p++) { EC_POINT_clear_free(*p); OPENSSL_cleanse(p, sizeof *p); - } - free(pre->points); } + free(pre->points); + } OPENSSL_cleanse(pre, sizeof *pre); free(pre); - } +} @@ -190,138 +192,125 @@ static void ec_pre_comp_clear_free(void *pre_) * with the exception that the most significant digit may be only * w-1 zeros away from that next non-zero digit. */ -static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) - { +static signed char * +compute_wNAF(const BIGNUM * scalar, int w, size_t * ret_len) +{ int window_val; int ok = 0; signed char *r = NULL; int sign = 1; int bit, next_bit, mask; size_t len = 0, j; - - if (BN_is_zero(scalar)) - { + + if (BN_is_zero(scalar)) { r = malloc(1); - if (!r) - { + if (!r) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); goto err; - } + } r[0] = 0; *ret_len = 1; return r; - } - - if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */ - { + } + if (w <= 0 || w > 7) { + /* 'signed char' can represent integers with + * absolute values less than 2^7 */ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } - bit = 1 << w; /* at most 128 */ - next_bit = bit << 1; /* at most 256 */ - mask = next_bit - 1; /* at most 255 */ + } + bit = 1 << w; /* at most 128 */ + next_bit = bit << 1; /* at most 256 */ + mask = next_bit - 1; /* at most 255 */ - if (BN_is_negative(scalar)) - { + if (BN_is_negative(scalar)) { sign = -1; - } - - if (scalar->d == NULL || scalar->top == 0) - { + } + if (scalar->d == NULL || scalar->top == 0) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } - + } len = BN_num_bits(scalar); - r = malloc(len + 1); /* modified wNAF may be one digit longer than binary representation - * (*ret_len will be set to the actual length, i.e. at most - * BN_num_bits(scalar) + 1) */ - if (r == NULL) - { + r = malloc(len + 1); /* modified wNAF may be one digit longer than + * binary representation (*ret_len will be + * set to the actual length, i.e. at most + * BN_num_bits(scalar) + 1) */ + if (r == NULL) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); goto err; - } + } window_val = scalar->d[0] & mask; j = 0; - while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */ - { + while ((window_val != 0) || (j + w + 1 < len)) { + /* if j+w+1 >= len, window_val will not increase */ int digit = 0; /* 0 <= window_val <= 2^(w+1) */ - - if (window_val & 1) - { + if (window_val & 1) { /* 0 < window_val < 2^(w+1) */ - - if (window_val & bit) - { - digit = window_val - next_bit; /* -2^w < digit < 0 */ - -#if 1 /* modified wNAF */ - if (j + w + 1 >= len) - { - /* special case for generating modified wNAFs: - * no new bits will be added into window_val, - * so using a positive digit here will decrease - * the total length of the representation */ - - digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ - } -#endif - } - else - { - digit = window_val; /* 0 < digit < 2^w */ + if (window_val & bit) { + digit = window_val - next_bit; /* -2^w < digit < 0 */ + +#if 1 /* modified wNAF */ + if (j + w + 1 >= len) { + /* + * special case for generating + * modified wNAFs: no new bits will + * be added into window_val, so using + * a positive digit here will + * decrease the total length of the + * representation + */ + + digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ } - - if (digit <= -bit || digit >= bit || !(digit & 1)) - { +#endif + } else { + digit = window_val; /* 0 < digit < 2^w */ + } + + if (digit <= -bit || digit >= bit || !(digit & 1)) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } - + } window_val -= digit; - /* now window_val is 0 or 2^(w+1) in standard wNAF generation; - * for modified window NAFs, it may also be 2^w + /* + * now window_val is 0 or 2^(w+1) in standard wNAF + * generation; for modified window NAFs, it may also + * be 2^w */ - if (window_val != 0 && window_val != next_bit && window_val != bit) - { + if (window_val != 0 && window_val != next_bit && window_val != bit) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } } - + } r[j++] = sign * digit; window_val >>= 1; window_val += bit * BN_is_bit_set(scalar, j + w); - if (window_val > next_bit) - { + if (window_val > next_bit) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } } + } - if (j > len + 1) - { + if (j > len + 1) { ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); goto err; - } + } len = j; ok = 1; - err: - if (!ok) - { +err: + if (!ok) { free(r); r = NULL; - } + } if (ok) *ret_len = len; return r; - } +} /* TODO: table should be optimised for the wNAF-based implementation, @@ -343,374 +332,353 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) * scalar*generator * in the addition if scalar != NULL */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) - { +int +ec_wNAF_mul(const EC_GROUP * group, EC_POINT * r, const BIGNUM * scalar, + size_t num, const EC_POINT * points[], const BIGNUM * scalars[], BN_CTX * ctx) +{ BN_CTX *new_ctx = NULL; const EC_POINT *generator = NULL; EC_POINT *tmp = NULL; size_t totalnum; - size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ + size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ size_t pre_points_per_block = 0; size_t i, j; int k; int r_is_inverted = 0; int r_is_at_infinity = 1; - size_t *wsize = NULL; /* individual window sizes */ - signed char **wNAF = NULL; /* individual wNAFs */ + size_t *wsize = NULL; /* individual window sizes */ + signed char **wNAF = NULL; /* individual wNAFs */ size_t *wNAF_len = NULL; size_t max_len = 0; size_t num_val; - EC_POINT **val = NULL; /* precomputation */ + EC_POINT **val = NULL; /* precomputation */ EC_POINT **v; - EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */ + EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or + * 'pre_comp->points' */ const EC_PRE_COMP *pre_comp = NULL; - int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like other scalars, - * i.e. precomputation is not available */ + int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be + * treated like other scalars, i.e. + * precomputation is not available */ int ret = 0; - - if (group->meth != r->meth) - { + + if (group->meth != r->meth) { ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; - } - - if ((scalar == NULL) && (num == 0)) - { + } + if ((scalar == NULL) && (num == 0)) { return EC_POINT_set_to_infinity(group, r); - } - - for (i = 0; i < num; i++) - { - if (group->meth != points[i]->meth) - { + } + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); return 0; - } } + } - if (ctx == NULL) - { + if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) goto err; - } - - if (scalar != NULL) - { + } + if (scalar != NULL) { generator = EC_GROUP_get0_generator(group); - if (generator == NULL) - { + if (generator == NULL) { ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); goto err; - } - + } /* look if we can use precomputed multiples of generator */ pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free); - if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) - { + if (pre_comp && pre_comp->numblocks && + (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) { blocksize = pre_comp->blocksize; - /* determine maximum number of blocks that wNAF splitting may yield - * (NB: maximum wNAF length is bit length plus one) */ + /* + * determine maximum number of blocks that wNAF + * splitting may yield (NB: maximum wNAF length is + * bit length plus one) + */ numblocks = (BN_num_bits(scalar) / blocksize) + 1; - /* we cannot use more blocks than we have precomputation for */ + /* + * we cannot use more blocks than we have + * precomputation for + */ if (numblocks > pre_comp->numblocks) numblocks = pre_comp->numblocks; - pre_points_per_block = (size_t)1 << (pre_comp->w - 1); + pre_points_per_block = (size_t) 1 << (pre_comp->w - 1); /* check that pre_comp looks sane */ - if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) - { + if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } } - else - { + } else { /* can't use precomputation */ pre_comp = NULL; numblocks = 1; - num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */ - } + num_scalar = 1; /* treat 'scalar' like 'num'-th + * element of 'scalars' */ } - + } totalnum = num + numblocks; - wsize = malloc(totalnum * sizeof wsize[0]); + wsize = malloc(totalnum * sizeof wsize[0]); wNAF_len = malloc(totalnum * sizeof wNAF_len[0]); - wNAF = malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */ - val_sub = malloc(totalnum * sizeof val_sub[0]); - - if (!wsize || !wNAF_len || !wNAF || !val_sub) - { + wNAF = malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for + * pivot */ + val_sub = malloc(totalnum * sizeof val_sub[0]); + + if (!wsize || !wNAF_len || !wNAF || !val_sub) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); goto err; - } - - wNAF[0] = NULL; /* preliminary pivot */ + } + wNAF[0] = NULL; /* preliminary pivot */ /* num_val will be the total number of temporarily precomputed points */ num_val = 0; - for (i = 0; i < num + num_scalar; i++) - { + for (i = 0; i < num + num_scalar; i++) { size_t bits; bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); wsize[i] = EC_window_bits_for_scalar_size(bits); - num_val += (size_t)1 << (wsize[i] - 1); - wNAF[i + 1] = NULL; /* make sure we always have a pivot */ + num_val += (size_t) 1 << (wsize[i] - 1); + wNAF[i + 1] = NULL; /* make sure we always have a pivot */ wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]); if (wNAF[i] == NULL) goto err; if (wNAF_len[i] > max_len) max_len = wNAF_len[i]; - } + } - if (numblocks) - { + if (numblocks) { /* we go here iff scalar != NULL */ - - if (pre_comp == NULL) - { - if (num_scalar != 1) - { + + if (pre_comp == NULL) { + if (num_scalar != 1) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } - /* we have already generated a wNAF for 'scalar' */ } - else - { + /* we have already generated a wNAF for 'scalar' */ + } else { signed char *tmp_wNAF = NULL; size_t tmp_len = 0; - - if (num_scalar != 0) - { + + if (num_scalar != 0) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } - - /* use the window size for which we have precomputation */ + } + /* + * use the window size for which we have + * precomputation + */ wsize[num] = pre_comp->w; tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); if (!tmp_wNAF) goto err; - if (tmp_len <= max_len) - { - /* One of the other wNAFs is at least as long - * as the wNAF belonging to the generator, - * so wNAF splitting will not buy us anything. */ + if (tmp_len <= max_len) { + /* + * One of the other wNAFs is at least as long + * as the wNAF belonging to the generator, so + * wNAF splitting will not buy us anything. + */ numblocks = 1; - totalnum = num + 1; /* don't use wNAF splitting */ + totalnum = num + 1; /* don't use wNAF + * splitting */ wNAF[num] = tmp_wNAF; wNAF[num + 1] = NULL; wNAF_len[num] = tmp_len; if (tmp_len > max_len) max_len = tmp_len; - /* pre_comp->points starts with the points that we need here: */ + /* + * pre_comp->points starts with the points + * that we need here: + */ val_sub[num] = pre_comp->points; - } - else - { - /* don't include tmp_wNAF directly into wNAF array - * - use wNAF splitting and include the blocks */ + } else { + /* + * don't include tmp_wNAF directly into wNAF + * array - use wNAF splitting and include the + * blocks + */ signed char *pp; EC_POINT **tmp_points; - - if (tmp_len < numblocks * blocksize) - { - /* possibly we can do with fewer blocks than estimated */ + + if (tmp_len < numblocks * blocksize) { + /* + * possibly we can do with fewer + * blocks than estimated + */ numblocks = (tmp_len + blocksize - 1) / blocksize; - if (numblocks > pre_comp->numblocks) - { + if (numblocks > pre_comp->numblocks) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } - totalnum = num + numblocks; } - + totalnum = num + numblocks; + } /* split wNAF in 'numblocks' parts */ pp = tmp_wNAF; tmp_points = pre_comp->points; - for (i = num; i < totalnum; i++) - { - if (i < totalnum - 1) - { + for (i = num; i < totalnum; i++) { + if (i < totalnum - 1) { wNAF_len[i] = blocksize; - if (tmp_len < blocksize) - { + if (tmp_len < blocksize) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } - tmp_len -= blocksize; } - else - /* last block gets whatever is left - * (this could be more or less than 'blocksize'!) */ + tmp_len -= blocksize; + } else + /* + * last block gets whatever + * is left (this could be + * more or less than + * 'blocksize'!) + */ wNAF_len[i] = tmp_len; - + wNAF[i + 1] = NULL; wNAF[i] = malloc(wNAF_len[i]); - if (wNAF[i] == NULL) - { + if (wNAF[i] == NULL) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); free(tmp_wNAF); goto err; - } + } memcpy(wNAF[i], pp, wNAF_len[i]); if (wNAF_len[i] > max_len) max_len = wNAF_len[i]; - if (*tmp_points == NULL) - { + if (*tmp_points == NULL) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); free(tmp_wNAF); goto err; - } + } val_sub[i] = tmp_points; tmp_points += pre_points_per_block; pp += blocksize; - } - free(tmp_wNAF); } + free(tmp_wNAF); } } - - /* All points we precompute now go into a single array 'val'. - * 'val_sub[i]' is a pointer to the subarray for the i-th point, - * or to a subarray of 'pre_comp->points' if we already have precomputation. */ + } + /* + * All points we precompute now go into a single array 'val'. + * 'val_sub[i]' is a pointer to the subarray for the i-th point, or + * to a subarray of 'pre_comp->points' if we already have + * precomputation. + */ val = malloc((num_val + 1) * sizeof val[0]); - if (val == NULL) - { + if (val == NULL) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); goto err; - } - val[num_val] = NULL; /* pivot element */ + } + val[num_val] = NULL; /* pivot element */ /* allocate points for precomputation */ v = val; - for (i = 0; i < num + num_scalar; i++) - { + for (i = 0; i < num + num_scalar; i++) { val_sub[i] = v; - for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) - { + for (j = 0; j < ((size_t) 1 << (wsize[i] - 1)); j++) { *v = EC_POINT_new(group); - if (*v == NULL) goto err; + if (*v == NULL) + goto err; v++; - } } - if (!(v == val + num_val)) - { + } + if (!(v == val + num_val)) { ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); goto err; - } - + } if (!(tmp = EC_POINT_new(group))) goto err; - /* prepare precomputed values: - * val_sub[i][0] := points[i] - * val_sub[i][1] := 3 * points[i] - * val_sub[i][2] := 5 * points[i] - * ... + /* + * prepare precomputed values: val_sub[i][0] := points[i] + * val_sub[i][1] := 3 * points[i] val_sub[i][2] := 5 * points[i] ... */ - for (i = 0; i < num + num_scalar; i++) - { - if (i < num) - { - if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err; - } - else - { - if (!EC_POINT_copy(val_sub[i][0], generator)) goto err; - } + for (i = 0; i < num + num_scalar; i++) { + if (i < num) { + if (!EC_POINT_copy(val_sub[i][0], points[i])) + goto err; + } else { + if (!EC_POINT_copy(val_sub[i][0], generator)) + goto err; + } - if (wsize[i] > 1) - { - if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err; - for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) - { - if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err; - } + if (wsize[i] > 1) { + if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) + goto err; + for (j = 1; j < ((size_t) 1 << (wsize[i] - 1)); j++) { + if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) + goto err; } } + } -#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */ +#if 1 /* optional; EC_window_bits_for_scalar_size + * assumes we do this step */ if (!EC_POINTs_make_affine(group, num_val, val, ctx)) goto err; #endif r_is_at_infinity = 1; - for (k = max_len - 1; k >= 0; k--) - { - if (!r_is_at_infinity) - { - if (!EC_POINT_dbl(group, r, r, ctx)) goto err; - } - - for (i = 0; i < totalnum; i++) - { - if (wNAF_len[i] > (size_t)k) - { + for (k = max_len - 1; k >= 0; k--) { + if (!r_is_at_infinity) { + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + } + for (i = 0; i < totalnum; i++) { + if (wNAF_len[i] > (size_t) k) { int digit = wNAF[i][k]; int is_neg; - if (digit) - { + if (digit) { is_neg = digit < 0; if (is_neg) digit = -digit; - if (is_neg != r_is_inverted) - { - if (!r_is_at_infinity) - { - if (!EC_POINT_invert(group, r, ctx)) goto err; - } - r_is_inverted = !r_is_inverted; + if (is_neg != r_is_inverted) { + if (!r_is_at_infinity) { + if (!EC_POINT_invert(group, r, ctx)) + goto err; } - + r_is_inverted = !r_is_inverted; + } /* digit > 0 */ - if (r_is_at_infinity) - { - if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err; + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) + goto err; r_is_at_infinity = 0; - } - else - { - if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err; - } + } else { + if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) + goto err; } } } } + } - if (r_is_at_infinity) - { - if (!EC_POINT_set_to_infinity(group, r)) goto err; - } - else - { + if (r_is_at_infinity) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { if (r_is_inverted) - if (!EC_POINT_invert(group, r, ctx)) goto err; - } - + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + ret = 1; - err: +err: if (new_ctx != NULL) BN_CTX_free(new_ctx); if (tmp != NULL) @@ -719,34 +687,31 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, free(wsize); if (wNAF_len != NULL) free(wNAF_len); - if (wNAF != NULL) - { + if (wNAF != NULL) { signed char **w; - + for (w = wNAF; *w != NULL; w++) free(*w); - + free(wNAF); - } - if (val != NULL) - { + } + if (val != NULL) { for (v = val; *v != NULL; v++) EC_POINT_clear_free(*v); free(val); - } - if (val_sub != NULL) - { + } + if (val_sub != NULL) { free(val_sub); - } - return ret; } + return ret; +} /* ec_wNAF_precompute_mult() * creates an EC_PRE_COMP object with preprecomputed multiples of the generator * for use with wNAF splitting as implemented in ec_wNAF_mul(). - * + * * 'pre_comp->points' is an array of multiples of the generator * of the following form: * points[0] = generator; @@ -762,13 +727,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator * points[2^(w-1)*numblocks] = NULL */ -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) - { +int +ec_wNAF_precompute_mult(EC_GROUP * group, BN_CTX * ctx) +{ const EC_POINT *generator; EC_POINT *tmp_point = NULL, *base = NULL, **var; BN_CTX *new_ctx = NULL; BIGNUM *order; - size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; + size_t i, bits, w, pre_points_per_block, blocksize, numblocks, + num; EC_POINT **points = NULL; EC_PRE_COMP *pre_comp; int ret = 0; @@ -780,81 +747,72 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) return 0; generator = EC_GROUP_get0_generator(group); - if (generator == NULL) - { + if (generator == NULL) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); goto err; - } - - if (ctx == NULL) - { + } + if (ctx == NULL) { ctx = new_ctx = BN_CTX_new(); if (ctx == NULL) goto err; - } - + } BN_CTX_start(ctx); order = BN_CTX_get(ctx); - if (order == NULL) goto err; - - if (!EC_GROUP_get_order(group, order, ctx)) goto err; - if (BN_is_zero(order)) - { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); + if (order == NULL) goto err; - } + if (!EC_GROUP_get_order(group, order, ctx)) + goto err; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); + goto err; + } bits = BN_num_bits(order); - /* The following parameters mean we precompute (approximately) - * one point per bit. - * - * TBD: The combination 8, 4 is perfect for 160 bits; for other - * bit lengths, other parameter combinations might provide better + /* + * The following parameters mean we precompute (approximately) one + * point per bit. + * + * TBD: The combination 8, 4 is perfect for 160 bits; for other bit + * lengths, other parameter combinations might provide better * efficiency. */ blocksize = 8; w = 4; - if (EC_window_bits_for_scalar_size(bits) > w) - { + if (EC_window_bits_for_scalar_size(bits) > w) { /* let's not make the window too small ... */ w = EC_window_bits_for_scalar_size(bits); - } + } + numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks + * to use for wNAF + * splitting */ - numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */ - - pre_points_per_block = (size_t)1 << (w - 1); - num = pre_points_per_block * numblocks; /* number of points to compute and store */ + pre_points_per_block = (size_t) 1 << (w - 1); + num = pre_points_per_block * numblocks; /* number of points to + * compute and store */ - points = malloc(sizeof (EC_POINT*)*(num + 1)); - if (!points) - { + points = malloc(sizeof(EC_POINT *) * (num + 1)); + if (!points) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); goto err; - } - + } var = points; - var[num] = NULL; /* pivot */ - for (i = 0; i < num; i++) - { - if ((var[i] = EC_POINT_new(group)) == NULL) - { + var[num] = NULL; /* pivot */ + for (i = 0; i < num; i++) { + if ((var[i] = EC_POINT_new(group)) == NULL) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); goto err; - } } + } - if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) - { + if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); goto err; - } - + } if (!EC_POINT_copy(base, generator)) goto err; - + /* do the precomputation */ - for (i = 0; i < numblocks; i++) - { + for (i = 0; i < numblocks; i++) { size_t j; if (!EC_POINT_dbl(group, tmp_point, base, ctx)) @@ -863,37 +821,35 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) if (!EC_POINT_copy(*var++, base)) goto err; - for (j = 1; j < pre_points_per_block; j++, var++) - { + for (j = 1; j < pre_points_per_block; j++, var++) { /* calculate odd multiples of the current base point */ if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) goto err; - } + } - if (i < numblocks - 1) - { - /* get the next base (multiply current one by 2^blocksize) */ + if (i < numblocks - 1) { + /* + * get the next base (multiply current one by + * 2^blocksize) + */ size_t k; - if (blocksize <= 2) - { + if (blocksize <= 2) { ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); goto err; - } - + } if (!EC_POINT_dbl(group, base, tmp_point, ctx)) goto err; - for (k = 2; k < blocksize; k++) - { - if (!EC_POINT_dbl(group,base,base,ctx)) + for (k = 2; k < blocksize; k++) { + if (!EC_POINT_dbl(group, base, base, ctx)) goto err; - } } - } + } + } if (!EC_POINTs_make_affine(group, num, points, ctx)) goto err; - + pre_comp->group = group; pre_comp->blocksize = blocksize; pre_comp->numblocks = numblocks; @@ -908,33 +864,33 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) pre_comp = NULL; ret = 1; - err: +err: if (ctx != NULL) BN_CTX_end(ctx); if (new_ctx != NULL) BN_CTX_free(new_ctx); if (pre_comp) ec_pre_comp_free(pre_comp); - if (points) - { + if (points) { EC_POINT **p; for (p = points; *p != NULL; p++) EC_POINT_free(*p); free(points); - } + } if (tmp_point) EC_POINT_free(tmp_point); if (base) EC_POINT_free(base); return ret; - } +} -int ec_wNAF_have_precompute_mult(const EC_GROUP *group) - { +int +ec_wNAF_have_precompute_mult(const EC_GROUP * group) +{ if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL) return 1; else return 0; - } +} |