security/nss/lib/freebl/ecl/ecp_fp.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/freebl/ecl/ecp_fp.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,531 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "ecp_fp.h"
     1.9 +#include "ecl-priv.h"
    1.10 +#include <stdlib.h>
    1.11 +
    1.12 +/* Performs tidying on a short multi-precision floating point integer (the 
    1.13 + * lower group->numDoubles floats). */
    1.14 +void
    1.15 +ecfp_tidyShort(double *t, const EC_group_fp * group)
    1.16 +{
    1.17 +	group->ecfp_tidy(t, group->alpha, group);
    1.18 +}
    1.19 +
    1.20 +/* Performs tidying on only the upper float digits of a multi-precision
    1.21 + * floating point integer, i.e. the digits beyond the regular length which 
    1.22 + * are removed in the reduction step. */
    1.23 +void
    1.24 +ecfp_tidyUpper(double *t, const EC_group_fp * group)
    1.25 +{
    1.26 +	group->ecfp_tidy(t + group->numDoubles,
    1.27 +					 group->alpha + group->numDoubles, group);
    1.28 +}
    1.29 +
    1.30 +/* Performs a "tidy" operation, which performs carrying, moving excess
    1.31 + * bits from one double to the next double, so that the precision of the
    1.32 + * doubles is reduced to the regular precision group->doubleBitSize. This
    1.33 + * might result in some float digits being negative. Alternative C version 
    1.34 + * for portability. */
    1.35 +void
    1.36 +ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group)
    1.37 +{
    1.38 +	double q;
    1.39 +	int i;
    1.40 +
    1.41 +	/* Do carrying */
    1.42 +	for (i = 0; i < group->numDoubles - 1; i++) {
    1.43 +		q = t[i] + alpha[i + 1];
    1.44 +		q -= alpha[i + 1];
    1.45 +		t[i] -= q;
    1.46 +		t[i + 1] += q;
    1.47 +
    1.48 +		/* If we don't assume that truncation rounding is used, then q
    1.49 +		 * might be 2^n bigger than expected (if it rounds up), then t[0]
    1.50 +		 * could be negative and t[1] 2^n larger than expected. */
    1.51 +	}
    1.52 +}
    1.53 +
    1.54 +/* Performs a more mathematically precise "tidying" so that each term is
    1.55 + * positive.  This is slower than the regular tidying, and is used for
    1.56 + * conversion from floating point to integer. */
    1.57 +void
    1.58 +ecfp_positiveTidy(double *t, const EC_group_fp * group)
    1.59 +{
    1.60 +	double q;
    1.61 +	int i;
    1.62 +
    1.63 +	/* Do carrying */
    1.64 +	for (i = 0; i < group->numDoubles - 1; i++) {
    1.65 +		/* Subtract beta to force rounding down */
    1.66 +		q = t[i] - ecfp_beta[i + 1];
    1.67 +		q += group->alpha[i + 1];
    1.68 +		q -= group->alpha[i + 1];
    1.69 +		t[i] -= q;
    1.70 +		t[i + 1] += q;
    1.71 +
    1.72 +		/* Due to subtracting ecfp_beta, we should have each term a
    1.73 +		 * non-negative int */
    1.74 +		ECFP_ASSERT(t[i] / ecfp_exp[i] ==
    1.75 +					(unsigned long long) (t[i] / ecfp_exp[i]));
    1.76 +		ECFP_ASSERT(t[i] >= 0);
    1.77 +	}
    1.78 +}
    1.79 +
    1.80 +/* Converts from a floating point representation into an mp_int. Expects
    1.81 + * that d is already reduced. */
    1.82 +void
    1.83 +ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup)
    1.84 +{
    1.85 +	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
    1.86 +	unsigned short i16[(group->primeBitSize + 15) / 16];
    1.87 +	double q = 1;
    1.88 +
    1.89 +#ifdef ECL_THIRTY_TWO_BIT
    1.90 +	/* TEST uint32_t z = 0; */
    1.91 +	unsigned int z = 0;
    1.92 +#else
    1.93 +	uint64_t z = 0;
    1.94 +#endif
    1.95 +	int zBits = 0;
    1.96 +	int copiedBits = 0;
    1.97 +	int i = 0;
    1.98 +	int j = 0;
    1.99 +
   1.100 +	mp_digit *out;
   1.101 +
   1.102 +	/* Result should always be >= 0, so set sign accordingly */
   1.103 +	MP_SIGN(mpout) = MP_ZPOS;
   1.104 +
   1.105 +	/* Tidy up so we're just dealing with positive numbers */
   1.106 +	ecfp_positiveTidy(d, group);
   1.107 +
   1.108 +	/* We might need to do this reduction step more than once if the
   1.109 +	 * reduction adds smaller terms which carry-over to cause another
   1.110 +	 * reduction. However, this should happen very rarely, if ever,
   1.111 +	 * depending on the elliptic curve. */
   1.112 +	do {
   1.113 +		/* Init loop data */
   1.114 +		z = 0;
   1.115 +		zBits = 0;
   1.116 +		q = 1;
   1.117 +		i = 0;
   1.118 +		j = 0;
   1.119 +		copiedBits = 0;
   1.120 +
   1.121 +		/* Might have to do a bit more reduction */
   1.122 +		group->ecfp_singleReduce(d, group);
   1.123 +
   1.124 +		/* Grow the size of the mpint if it's too small */
   1.125 +		s_mp_grow(mpout, group->numInts);
   1.126 +		MP_USED(mpout) = group->numInts;
   1.127 +		out = MP_DIGITS(mpout);
   1.128 +
   1.129 +		/* Convert double to 16 bit integers */
   1.130 +		while (copiedBits < group->primeBitSize) {
   1.131 +			if (zBits < 16) {
   1.132 +				z += d[i] * q;
   1.133 +				i++;
   1.134 +				ECFP_ASSERT(i < (group->primeBitSize + 15) / 16);
   1.135 +				zBits += group->doubleBitSize;
   1.136 +			}
   1.137 +			i16[j] = z;
   1.138 +			j++;
   1.139 +			z >>= 16;
   1.140 +			zBits -= 16;
   1.141 +			q *= ecfp_twom16;
   1.142 +			copiedBits += 16;
   1.143 +		}
   1.144 +	} while (z != 0);
   1.145 +
   1.146 +	/* Convert 16 bit integers to mp_digit */
   1.147 +#ifdef ECL_THIRTY_TWO_BIT
   1.148 +	for (i = 0; i < (group->primeBitSize + 15) / 16; i += 2) {
   1.149 +		*out = 0;
   1.150 +		if (i + 1 < (group->primeBitSize + 15) / 16) {
   1.151 +			*out = i16[i + 1];
   1.152 +			*out <<= 16;
   1.153 +		}
   1.154 +		*out++ += i16[i];
   1.155 +	}
   1.156 +#else							/* 64 bit */
   1.157 +	for (i = 0; i < (group->primeBitSize + 15) / 16; i += 4) {
   1.158 +		*out = 0;
   1.159 +		if (i + 3 < (group->primeBitSize + 15) / 16) {
   1.160 +			*out = i16[i + 3];
   1.161 +			*out <<= 16;
   1.162 +		}
   1.163 +		if (i + 2 < (group->primeBitSize + 15) / 16) {
   1.164 +			*out += i16[i + 2];
   1.165 +			*out <<= 16;
   1.166 +		}
   1.167 +		if (i + 1 < (group->primeBitSize + 15) / 16) {
   1.168 +			*out += i16[i + 1];
   1.169 +			*out <<= 16;
   1.170 +		}
   1.171 +		*out++ += i16[i];
   1.172 +	}
   1.173 +#endif
   1.174 +
   1.175 +	/* Perform final reduction.  mpout should already be the same number
   1.176 +	 * of bits as p, but might not be less than p.  Make it so. Since
   1.177 +	 * mpout has the same number of bits as p, and 2p has a larger bit
   1.178 +	 * size, then mpout < 2p, so a single subtraction of p will suffice. */
   1.179 +	if (mp_cmp(mpout, &ecgroup->meth->irr) >= 0) {
   1.180 +		mp_sub(mpout, &ecgroup->meth->irr, mpout);
   1.181 +	}
   1.182 +
   1.183 +	/* Shrink the size of the mp_int to the actual used size (required for 
   1.184 +	 * mp_cmp_z == 0) */
   1.185 +	out = MP_DIGITS(mpout);
   1.186 +	for (i = group->numInts - 1; i > 0; i--) {
   1.187 +		if (out[i] != 0)
   1.188 +			break;
   1.189 +	}
   1.190 +	MP_USED(mpout) = i + 1;
   1.191 +
   1.192 +	/* Should be between 0 and p-1 */
   1.193 +	ECFP_ASSERT(mp_cmp(mpout, &ecgroup->meth->irr) < 0);
   1.194 +	ECFP_ASSERT(mp_cmp_z(mpout) >= 0);
   1.195 +}
   1.196 +
   1.197 +/* Converts from an mpint into a floating point representation. */
   1.198 +void
   1.199 +ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup)
   1.200 +{
   1.201 +	int i;
   1.202 +	int j = 0;
   1.203 +	int size;
   1.204 +	double shift = 1;
   1.205 +	mp_digit *in;
   1.206 +	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
   1.207 +
   1.208 +#ifdef ECL_DEBUG
   1.209 +	/* if debug mode, convert result back using ecfp_fp2i into cmp, then
   1.210 +	 * compare to x. */
   1.211 +	mp_int cmp;
   1.212 +
   1.213 +	MP_DIGITS(&cmp) = NULL;
   1.214 +	mp_init(&cmp);
   1.215 +#endif
   1.216 +
   1.217 +	ECFP_ASSERT(group != NULL);
   1.218 +
   1.219 +	/* init output to 0 (since we skip over some terms) */
   1.220 +	for (i = 0; i < group->numDoubles; i++)
   1.221 +		out[i] = 0;
   1.222 +	i = 0;
   1.223 +
   1.224 +	size = MP_USED(x);
   1.225 +	in = MP_DIGITS(x);
   1.226 +
   1.227 +	/* Copy from int into doubles */
   1.228 +#ifdef ECL_THIRTY_TWO_BIT
   1.229 +	while (j < size) {
   1.230 +		while (group->doubleBitSize * (i + 1) <= 32 * j) {
   1.231 +			i++;
   1.232 +		}
   1.233 +		ECFP_ASSERT(group->doubleBitSize * i <= 32 * j);
   1.234 +		out[i] = in[j];
   1.235 +		out[i] *= shift;
   1.236 +		shift *= ecfp_two32;
   1.237 +		j++;
   1.238 +	}
   1.239 +#else
   1.240 +	while (j < size) {
   1.241 +		while (group->doubleBitSize * (i + 1) <= 64 * j) {
   1.242 +			i++;
   1.243 +		}
   1.244 +		ECFP_ASSERT(group->doubleBitSize * i <= 64 * j);
   1.245 +		out[i] = (in[j] & 0x00000000FFFFFFFF) * shift;
   1.246 +
   1.247 +		while (group->doubleBitSize * (i + 1) <= 64 * j + 32) {
   1.248 +			i++;
   1.249 +		}
   1.250 +		ECFP_ASSERT(24 * i <= 64 * j + 32);
   1.251 +		out[i] = (in[j] & 0xFFFFFFFF00000000) * shift;
   1.252 +
   1.253 +		shift *= ecfp_two64;
   1.254 +		j++;
   1.255 +	}
   1.256 +#endif
   1.257 +	/* Realign bits to match double boundaries */
   1.258 +	ecfp_tidyShort(out, group);
   1.259 +
   1.260 +#ifdef ECL_DEBUG
   1.261 +	/* Convert result back to mp_int, compare to original */
   1.262 +	ecfp_fp2i(&cmp, out, ecgroup);
   1.263 +	ECFP_ASSERT(mp_cmp(&cmp, x) == 0);
   1.264 +	mp_clear(&cmp);
   1.265 +#endif
   1.266 +}
   1.267 +
   1.268 +/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
   1.269 + * a, b and p are the elliptic curve coefficients and the prime that
   1.270 + * determines the field GFp.  Elliptic curve points P and R can be
   1.271 + * identical.  Uses Jacobian coordinates. Uses 4-bit window method. */
   1.272 +mp_err
   1.273 +ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
   1.274 +						   const mp_int *py, mp_int *rx, mp_int *ry,
   1.275 +						   const ECGroup *ecgroup)
   1.276 +{
   1.277 +	mp_err res = MP_OKAY;
   1.278 +	ecfp_jac_pt precomp[16], r;
   1.279 +	ecfp_aff_pt p;
   1.280 +	EC_group_fp *group;
   1.281 +
   1.282 +	mp_int rz;
   1.283 +	int i, ni, d;
   1.284 +
   1.285 +	ARGCHK(ecgroup != NULL, MP_BADARG);
   1.286 +	ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
   1.287 +
   1.288 +	group = (EC_group_fp *) ecgroup->extra1;
   1.289 +	MP_DIGITS(&rz) = 0;
   1.290 +	MP_CHECKOK(mp_init(&rz));
   1.291 +
   1.292 +	/* init p, da */
   1.293 +	ecfp_i2fp(p.x, px, ecgroup);
   1.294 +	ecfp_i2fp(p.y, py, ecgroup);
   1.295 +	ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
   1.296 +
   1.297 +	/* Do precomputation */
   1.298 +	group->precompute_jac(precomp, &p, group);
   1.299 +
   1.300 +	/* Do main body of calculations */
   1.301 +	d = (mpl_significant_bits(n) + 3) / 4;
   1.302 +
   1.303 +	/* R = inf */
   1.304 +	for (i = 0; i < group->numDoubles; i++) {
   1.305 +		r.z[i] = 0;
   1.306 +	}
   1.307 +
   1.308 +	for (i = d - 1; i >= 0; i--) {
   1.309 +		/* compute window ni */
   1.310 +		ni = MP_GET_BIT(n, 4 * i + 3);
   1.311 +		ni <<= 1;
   1.312 +		ni |= MP_GET_BIT(n, 4 * i + 2);
   1.313 +		ni <<= 1;
   1.314 +		ni |= MP_GET_BIT(n, 4 * i + 1);
   1.315 +		ni <<= 1;
   1.316 +		ni |= MP_GET_BIT(n, 4 * i);
   1.317 +
   1.318 +		/* R = 2^4 * R */
   1.319 +		group->pt_dbl_jac(&r, &r, group);
   1.320 +		group->pt_dbl_jac(&r, &r, group);
   1.321 +		group->pt_dbl_jac(&r, &r, group);
   1.322 +		group->pt_dbl_jac(&r, &r, group);
   1.323 +
   1.324 +		/* R = R + (ni * P) */
   1.325 +		group->pt_add_jac(&r, &precomp[ni], &r, group);
   1.326 +	}
   1.327 +
   1.328 +	/* Convert back to integer */
   1.329 +	ecfp_fp2i(rx, r.x, ecgroup);
   1.330 +	ecfp_fp2i(ry, r.y, ecgroup);
   1.331 +	ecfp_fp2i(&rz, r.z, ecgroup);
   1.332 +
   1.333 +	/* convert result S to affine coordinates */
   1.334 +	MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, ecgroup));
   1.335 +
   1.336 +  CLEANUP:
   1.337 +	mp_clear(&rz);
   1.338 +	return res;
   1.339 +}
   1.340 +
   1.341 +/* Uses mixed Jacobian-affine coordinates to perform a point
   1.342 + * multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
   1.343 + * coordinates (Jacobian coordinates for doubles and affine coordinates
   1.344 + * for additions; based on recommendation from Brown et al.). Not very
   1.345 + * time efficient but quite space efficient, no precomputation needed.
   1.346 + * group contains the elliptic curve coefficients and the prime that
   1.347 + * determines the field GFp.  Elliptic curve points P and R can be
   1.348 + * identical. Performs calculations in floating point number format, since 
   1.349 + * this is faster than the integer operations on the ULTRASPARC III.
   1.350 + * Uses left-to-right binary method (double & add) (algorithm 9) for
   1.351 + * scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
   1.352 + * Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
   1.353 +mp_err
   1.354 +ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
   1.355 +					 mp_int *rx, mp_int *ry, const ECGroup *ecgroup)
   1.356 +{
   1.357 +	mp_err res;
   1.358 +	mp_int sx, sy, sz;
   1.359 +
   1.360 +	ecfp_aff_pt p;
   1.361 +	ecfp_jac_pt r;
   1.362 +	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
   1.363 +
   1.364 +	int i, l;
   1.365 +
   1.366 +	MP_DIGITS(&sx) = 0;
   1.367 +	MP_DIGITS(&sy) = 0;
   1.368 +	MP_DIGITS(&sz) = 0;
   1.369 +	MP_CHECKOK(mp_init(&sx));
   1.370 +	MP_CHECKOK(mp_init(&sy));
   1.371 +	MP_CHECKOK(mp_init(&sz));
   1.372 +
   1.373 +	/* if n = 0 then r = inf */
   1.374 +	if (mp_cmp_z(n) == 0) {
   1.375 +		mp_zero(rx);
   1.376 +		mp_zero(ry);
   1.377 +		res = MP_OKAY;
   1.378 +		goto CLEANUP;
   1.379 +		/* if n < 0 then out of range error */
   1.380 +	} else if (mp_cmp_z(n) < 0) {
   1.381 +		res = MP_RANGE;
   1.382 +		goto CLEANUP;
   1.383 +	}
   1.384 +
   1.385 +	/* Convert from integer to floating point */
   1.386 +	ecfp_i2fp(p.x, px, ecgroup);
   1.387 +	ecfp_i2fp(p.y, py, ecgroup);
   1.388 +	ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
   1.389 +
   1.390 +	/* Init r to point at infinity */
   1.391 +	for (i = 0; i < group->numDoubles; i++) {
   1.392 +		r.z[i] = 0;
   1.393 +	}
   1.394 +
   1.395 +	/* double and add method */
   1.396 +	l = mpl_significant_bits(n) - 1;
   1.397 +
   1.398 +	for (i = l; i >= 0; i--) {
   1.399 +		/* R = 2R */
   1.400 +		group->pt_dbl_jac(&r, &r, group);
   1.401 +
   1.402 +		/* if n_i = 1, then R = R + Q */
   1.403 +		if (MP_GET_BIT(n, i) != 0) {
   1.404 +			group->pt_add_jac_aff(&r, &p, &r, group);
   1.405 +		}
   1.406 +	}
   1.407 +
   1.408 +	/* Convert from floating point to integer */
   1.409 +	ecfp_fp2i(&sx, r.x, ecgroup);
   1.410 +	ecfp_fp2i(&sy, r.y, ecgroup);
   1.411 +	ecfp_fp2i(&sz, r.z, ecgroup);
   1.412 +
   1.413 +	/* convert result R to affine coordinates */
   1.414 +	MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
   1.415 +
   1.416 +  CLEANUP:
   1.417 +	mp_clear(&sx);
   1.418 +	mp_clear(&sy);
   1.419 +	mp_clear(&sz);
   1.420 +	return res;
   1.421 +}
   1.422 +
   1.423 +/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
   1.424 + * curve points P and R can be identical. Uses mixed Modified-Jacobian
   1.425 + * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
   1.426 + * additions. Uses 5-bit window NAF method (algorithm 11) for scalar-point 
   1.427 + * multiplication from Brown, Hankerson, Lopez, Menezes. Software
   1.428 + * Implementation of the NIST Elliptic Curves Over Prime Fields. */
   1.429 +mp_err
   1.430 +ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
   1.431 +						 const mp_int *py, mp_int *rx, mp_int *ry,
   1.432 +						 const ECGroup *ecgroup)
   1.433 +{
   1.434 +	mp_err res = MP_OKAY;
   1.435 +	mp_int sx, sy, sz;
   1.436 +	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
   1.437 +	ecfp_chud_pt precomp[16];
   1.438 +
   1.439 +	ecfp_aff_pt p;
   1.440 +	ecfp_jm_pt r;
   1.441 +
   1.442 +	signed char naf[group->orderBitSize + 1];
   1.443 +	int i;
   1.444 +
   1.445 +	MP_DIGITS(&sx) = 0;
   1.446 +	MP_DIGITS(&sy) = 0;
   1.447 +	MP_DIGITS(&sz) = 0;
   1.448 +	MP_CHECKOK(mp_init(&sx));
   1.449 +	MP_CHECKOK(mp_init(&sy));
   1.450 +	MP_CHECKOK(mp_init(&sz));
   1.451 +
   1.452 +	/* if n = 0 then r = inf */
   1.453 +	if (mp_cmp_z(n) == 0) {
   1.454 +		mp_zero(rx);
   1.455 +		mp_zero(ry);
   1.456 +		res = MP_OKAY;
   1.457 +		goto CLEANUP;
   1.458 +		/* if n < 0 then out of range error */
   1.459 +	} else if (mp_cmp_z(n) < 0) {
   1.460 +		res = MP_RANGE;
   1.461 +		goto CLEANUP;
   1.462 +	}
   1.463 +
   1.464 +	/* Convert from integer to floating point */
   1.465 +	ecfp_i2fp(p.x, px, ecgroup);
   1.466 +	ecfp_i2fp(p.y, py, ecgroup);
   1.467 +	ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
   1.468 +
   1.469 +	/* Perform precomputation */
   1.470 +	group->precompute_chud(precomp, &p, group);
   1.471 +
   1.472 +	/* Compute 5NAF */
   1.473 +	ec_compute_wNAF(naf, group->orderBitSize, n, 5);
   1.474 +
   1.475 +	/* Init R = pt at infinity */
   1.476 +	for (i = 0; i < group->numDoubles; i++) {
   1.477 +		r.z[i] = 0;
   1.478 +	}
   1.479 +
   1.480 +	/* wNAF method */
   1.481 +	for (i = group->orderBitSize; i >= 0; i--) {
   1.482 +		/* R = 2R */
   1.483 +		group->pt_dbl_jm(&r, &r, group);
   1.484 +
   1.485 +		if (naf[i] != 0) {
   1.486 +			group->pt_add_jm_chud(&r, &precomp[(naf[i] + 15) / 2], &r,
   1.487 +								  group);
   1.488 +		}
   1.489 +	}
   1.490 +
   1.491 +	/* Convert from floating point to integer */
   1.492 +	ecfp_fp2i(&sx, r.x, ecgroup);
   1.493 +	ecfp_fp2i(&sy, r.y, ecgroup);
   1.494 +	ecfp_fp2i(&sz, r.z, ecgroup);
   1.495 +
   1.496 +	/* convert result R to affine coordinates */
   1.497 +	MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
   1.498 +
   1.499 +  CLEANUP:
   1.500 +	mp_clear(&sx);
   1.501 +	mp_clear(&sy);
   1.502 +	mp_clear(&sz);
   1.503 +	return res;
   1.504 +}
   1.505 +
   1.506 +/* Cleans up extra memory allocated in ECGroup for this implementation. */
   1.507 +void
   1.508 +ec_GFp_extra_free_fp(ECGroup *group)
   1.509 +{
   1.510 +	if (group->extra1 != NULL) {
   1.511 +		free(group->extra1);
   1.512 +		group->extra1 = NULL;
   1.513 +	}
   1.514 +}
   1.515 +
   1.516 +/* Tests what precision floating point arithmetic is set to. This should
   1.517 + * be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
   1.518 + * (extended precision on x86) and sets it into the EC_group_fp. Returns
   1.519 + * either 53 or 64 accordingly. */
   1.520 +int
   1.521 +ec_set_fp_precision(EC_group_fp * group)
   1.522 +{
   1.523 +	double a = 9007199254740992.0;	/* 2^53 */
   1.524 +	double b = a + 1;
   1.525 +
   1.526 +	if (a == b) {
   1.527 +		group->fpPrecision = 53;
   1.528 +		group->alpha = ecfp_alpha_53;
   1.529 +		return 53;
   1.530 +	}
   1.531 +	group->fpPrecision = 64;
   1.532 +	group->alpha = ecfp_alpha_64;
   1.533 +	return 64;
   1.534 +}

mercurial