2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the elliptic curve math library for prime
15
* field curves using floating point operations.
17
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
18
* Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
19
* Sun Microsystems, Inc. All Rights Reserved.
22
* Sheueling Chang-Shantz <sheueling.chang@sun.com>,
23
* Stephen Fung <fungstep@hotmail.com>, and
24
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the MPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the MPL, the GPL or the LGPL.
44
/* Performs tidying on a short multi-precision floating point integer (the
45
* lower group->numDoubles floats). */
47
ecfp_tidyShort(double *t, const EC_group_fp * group)
49
group->ecfp_tidy(t, group->alpha, group);
52
/* Performs tidying on only the upper float digits of a multi-precision
53
* floating point integer, i.e. the digits beyond the regular length which
54
* are removed in the reduction step. */
56
ecfp_tidyUpper(double *t, const EC_group_fp * group)
58
group->ecfp_tidy(t + group->numDoubles,
59
group->alpha + group->numDoubles, group);
62
/* Performs a "tidy" operation, which performs carrying, moving excess
63
* bits from one double to the next double, so that the precision of the
64
* doubles is reduced to the regular precision group->doubleBitSize. This
65
* might result in some float digits being negative. Alternative C version
68
ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group)
74
for (i = 0; i < group->numDoubles - 1; i++) {
75
q = t[i] + alpha[i + 1];
80
/* If we don't assume that truncation rounding is used, then q
81
* might be 2^n bigger than expected (if it rounds up), then t[0]
82
* could be negative and t[1] 2^n larger than expected. */
86
/* Performs a more mathematically precise "tidying" so that each term is
87
* positive. This is slower than the regular tidying, and is used for
88
* conversion from floating point to integer. */
90
ecfp_positiveTidy(double *t, const EC_group_fp * group)
96
for (i = 0; i < group->numDoubles - 1; i++) {
97
/* Subtract beta to force rounding down */
98
q = t[i] - ecfp_beta[i + 1];
99
q += group->alpha[i + 1];
100
q -= group->alpha[i + 1];
104
/* Due to subtracting ecfp_beta, we should have each term a
105
* non-negative int */
106
ECFP_ASSERT(t[i] / ecfp_exp[i] ==
107
(unsigned long long) (t[i] / ecfp_exp[i]));
108
ECFP_ASSERT(t[i] >= 0);
112
/* Converts from a floating point representation into an mp_int. Expects
113
* that d is already reduced. */
115
ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup)
117
EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
118
unsigned short i16[(group->primeBitSize + 15) / 16];
121
#ifdef ECL_THIRTY_TWO_BIT
122
/* TEST uint32_t z = 0; */
134
/* Result should always be >= 0, so set sign accordingly */
135
MP_SIGN(mpout) = MP_ZPOS;
137
/* Tidy up so we're just dealing with positive numbers */
138
ecfp_positiveTidy(d, group);
140
/* We might need to do this reduction step more than once if the
141
* reduction adds smaller terms which carry-over to cause another
142
* reduction. However, this should happen very rarely, if ever,
143
* depending on the elliptic curve. */
153
/* Might have to do a bit more reduction */
154
group->ecfp_singleReduce(d, group);
156
/* Grow the size of the mpint if it's too small */
157
s_mp_grow(mpout, group->numInts);
158
MP_USED(mpout) = group->numInts;
159
out = MP_DIGITS(mpout);
161
/* Convert double to 16 bit integers */
162
while (copiedBits < group->primeBitSize) {
166
ECFP_ASSERT(i < (group->primeBitSize + 15) / 16);
167
zBits += group->doubleBitSize;
178
/* Convert 16 bit integers to mp_digit */
179
#ifdef ECL_THIRTY_TWO_BIT
180
for (i = 0; i < (group->primeBitSize + 15) / 16; i += 2) {
182
if (i + 1 < (group->primeBitSize + 15) / 16) {
189
for (i = 0; i < (group->primeBitSize + 15) / 16; i += 4) {
191
if (i + 3 < (group->primeBitSize + 15) / 16) {
195
if (i + 2 < (group->primeBitSize + 15) / 16) {
199
if (i + 1 < (group->primeBitSize + 15) / 16) {
207
/* Perform final reduction. mpout should already be the same number
208
* of bits as p, but might not be less than p. Make it so. Since
209
* mpout has the same number of bits as p, and 2p has a larger bit
210
* size, then mpout < 2p, so a single subtraction of p will suffice. */
211
if (mp_cmp(mpout, &ecgroup->meth->irr) >= 0) {
212
mp_sub(mpout, &ecgroup->meth->irr, mpout);
215
/* Shrink the size of the mp_int to the actual used size (required for
217
out = MP_DIGITS(mpout);
218
for (i = group->numInts - 1; i > 0; i--) {
222
MP_USED(mpout) = i + 1;
224
/* Should be between 0 and p-1 */
225
ECFP_ASSERT(mp_cmp(mpout, &ecgroup->meth->irr) < 0);
226
ECFP_ASSERT(mp_cmp_z(mpout) >= 0);
229
/* Converts from an mpint into a floating point representation. */
231
ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup)
238
EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
241
/* if debug mode, convert result back using ecfp_fp2i into cmp, then
245
MP_DIGITS(&cmp) = NULL;
249
ECFP_ASSERT(group != NULL);
251
/* init output to 0 (since we skip over some terms) */
252
for (i = 0; i < group->numDoubles; i++)
259
/* Copy from int into doubles */
260
#ifdef ECL_THIRTY_TWO_BIT
262
while (group->doubleBitSize * (i + 1) <= 32 * j) {
265
ECFP_ASSERT(group->doubleBitSize * i <= 32 * j);
273
while (group->doubleBitSize * (i + 1) <= 64 * j) {
276
ECFP_ASSERT(group->doubleBitSize * i <= 64 * j);
277
out[i] = (in[j] & 0x00000000FFFFFFFF) * shift;
279
while (group->doubleBitSize * (i + 1) <= 64 * j + 32) {
282
ECFP_ASSERT(24 * i <= 64 * j + 32);
283
out[i] = (in[j] & 0xFFFFFFFF00000000) * shift;
289
/* Realign bits to match double boundaries */
290
ecfp_tidyShort(out, group);
293
/* Convert result back to mp_int, compare to original */
294
ecfp_fp2i(&cmp, out, ecgroup);
295
ECFP_ASSERT(mp_cmp(&cmp, x) == 0);
300
/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
301
* a, b and p are the elliptic curve coefficients and the prime that
302
* determines the field GFp. Elliptic curve points P and R can be
303
* identical. Uses Jacobian coordinates. Uses 4-bit window method. */
305
ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
306
const mp_int *py, mp_int *rx, mp_int *ry,
307
const ECGroup *ecgroup)
309
mp_err res = MP_OKAY;
310
ecfp_jac_pt precomp[16], r;
317
ARGCHK(ecgroup != NULL, MP_BADARG);
318
ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
320
group = (EC_group_fp *) ecgroup->extra1;
322
MP_CHECKOK(mp_init(&rz));
325
ecfp_i2fp(p.x, px, ecgroup);
326
ecfp_i2fp(p.y, py, ecgroup);
327
ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
329
/* Do precomputation */
330
group->precompute_jac(precomp, &p, group);
332
/* Do main body of calculations */
333
d = (mpl_significant_bits(n) + 3) / 4;
336
for (i = 0; i < group->numDoubles; i++) {
340
for (i = d - 1; i >= 0; i--) {
341
/* compute window ni */
342
ni = MP_GET_BIT(n, 4 * i + 3);
344
ni |= MP_GET_BIT(n, 4 * i + 2);
346
ni |= MP_GET_BIT(n, 4 * i + 1);
348
ni |= MP_GET_BIT(n, 4 * i);
351
group->pt_dbl_jac(&r, &r, group);
352
group->pt_dbl_jac(&r, &r, group);
353
group->pt_dbl_jac(&r, &r, group);
354
group->pt_dbl_jac(&r, &r, group);
356
/* R = R + (ni * P) */
357
group->pt_add_jac(&r, &precomp[ni], &r, group);
360
/* Convert back to integer */
361
ecfp_fp2i(rx, r.x, ecgroup);
362
ecfp_fp2i(ry, r.y, ecgroup);
363
ecfp_fp2i(&rz, r.z, ecgroup);
365
/* convert result S to affine coordinates */
366
MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, ecgroup));
373
/* Uses mixed Jacobian-affine coordinates to perform a point
374
* multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
375
* coordinates (Jacobian coordinates for doubles and affine coordinates
376
* for additions; based on recommendation from Brown et al.). Not very
377
* time efficient but quite space efficient, no precomputation needed.
378
* group contains the elliptic curve coefficients and the prime that
379
* determines the field GFp. Elliptic curve points P and R can be
380
* identical. Performs calculations in floating point number format, since
381
* this is faster than the integer operations on the ULTRASPARC III.
382
* Uses left-to-right binary method (double & add) (algorithm 9) for
383
* scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
384
* Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
386
ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
387
mp_int *rx, mp_int *ry, const ECGroup *ecgroup)
394
EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
401
MP_CHECKOK(mp_init(&sx));
402
MP_CHECKOK(mp_init(&sy));
403
MP_CHECKOK(mp_init(&sz));
405
/* if n = 0 then r = inf */
406
if (mp_cmp_z(n) == 0) {
411
/* if n < 0 then out of range error */
412
} else if (mp_cmp_z(n) < 0) {
417
/* Convert from integer to floating point */
418
ecfp_i2fp(p.x, px, ecgroup);
419
ecfp_i2fp(p.y, py, ecgroup);
420
ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
422
/* Init r to point at infinity */
423
for (i = 0; i < group->numDoubles; i++) {
427
/* double and add method */
428
l = mpl_significant_bits(n) - 1;
430
for (i = l; i >= 0; i--) {
432
group->pt_dbl_jac(&r, &r, group);
434
/* if n_i = 1, then R = R + Q */
435
if (MP_GET_BIT(n, i) != 0) {
436
group->pt_add_jac_aff(&r, &p, &r, group);
440
/* Convert from floating point to integer */
441
ecfp_fp2i(&sx, r.x, ecgroup);
442
ecfp_fp2i(&sy, r.y, ecgroup);
443
ecfp_fp2i(&sz, r.z, ecgroup);
445
/* convert result R to affine coordinates */
446
MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
455
/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
456
* curve points P and R can be identical. Uses mixed Modified-Jacobian
457
* co-ordinates for doubling and Chudnovsky Jacobian coordinates for
458
* additions. Uses 5-bit window NAF method (algorithm 11) for scalar-point
459
* multiplication from Brown, Hankerson, Lopez, Menezes. Software
460
* Implementation of the NIST Elliptic Curves Over Prime Fields. */
462
ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
463
const mp_int *py, mp_int *rx, mp_int *ry,
464
const ECGroup *ecgroup)
466
mp_err res = MP_OKAY;
468
EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
469
ecfp_chud_pt precomp[16];
474
signed char naf[group->orderBitSize + 1];
480
MP_CHECKOK(mp_init(&sx));
481
MP_CHECKOK(mp_init(&sy));
482
MP_CHECKOK(mp_init(&sz));
484
/* if n = 0 then r = inf */
485
if (mp_cmp_z(n) == 0) {
490
/* if n < 0 then out of range error */
491
} else if (mp_cmp_z(n) < 0) {
496
/* Convert from integer to floating point */
497
ecfp_i2fp(p.x, px, ecgroup);
498
ecfp_i2fp(p.y, py, ecgroup);
499
ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
501
/* Perform precomputation */
502
group->precompute_chud(precomp, &p, group);
505
ec_compute_wNAF(naf, group->orderBitSize, n, 5);
507
/* Init R = pt at infinity */
508
for (i = 0; i < group->numDoubles; i++) {
513
for (i = group->orderBitSize; i >= 0; i--) {
515
group->pt_dbl_jm(&r, &r, group);
518
group->pt_add_jm_chud(&r, &precomp[(naf[i] + 15) / 2], &r,
523
/* Convert from floating point to integer */
524
ecfp_fp2i(&sx, r.x, ecgroup);
525
ecfp_fp2i(&sy, r.y, ecgroup);
526
ecfp_fp2i(&sz, r.z, ecgroup);
528
/* convert result R to affine coordinates */
529
MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
538
/* Cleans up extra memory allocated in ECGroup for this implementation. */
540
ec_GFp_extra_free_fp(ECGroup *group)
542
if (group->extra1 != NULL) {
544
group->extra1 = NULL;
548
/* Tests what precision floating point arithmetic is set to. This should
549
* be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
550
* (extended precision on x86) and sets it into the EC_group_fp. Returns
551
* either 53 or 64 accordingly. */
553
ec_set_fp_precision(EC_group_fp * group)
555
double a = 9007199254740992.0; /* 2^53 */
559
group->fpPrecision = 53;
560
group->alpha = ecfp_alpha_53;
563
group->fpPrecision = 64;
564
group->alpha = ecfp_alpha_64;