Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: nss/lib/freebl/ecl/ecp_jac.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/freebl/ecl/ecp_aff.c ('k') | nss/lib/freebl/ecl/ecp_jm.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "ecp.h"
6 #include "mplogic.h"
7 #include <stdlib.h>
8 #ifdef ECL_DEBUG
9 #include <assert.h>
10 #endif
11
12 /* Converts a point P(px, py) from affine coordinates to Jacobian
13 * projective coordinates R(rx, ry, rz). Assumes input is already
14 * field-encoded using field_enc, and returns output that is still
15 * field-encoded. */
16 mp_err
17 ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
18 mp_int *ry, mp_int *rz, const ECGroup *group)
19 {
20 mp_err res = MP_OKAY;
21
22 if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
23 MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
24 } else {
25 MP_CHECKOK(mp_copy(px, rx));
26 MP_CHECKOK(mp_copy(py, ry));
27 MP_CHECKOK(mp_set_int(rz, 1));
28 if (group->meth->field_enc) {
29 MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
30 }
31 }
32 CLEANUP:
33 return res;
34 }
35
36 /* Converts a point P(px, py, pz) from Jacobian projective coordinates to
37 * affine coordinates R(rx, ry). P and R can share x and y coordinates.
38 * Assumes input is already field-encoded using field_enc, and returns
39 * output that is still field-encoded. */
40 mp_err
41 ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
42 mp_int *rx, mp_int *ry, const ECGroup *group)
43 {
44 mp_err res = MP_OKAY;
45 mp_int z1, z2, z3;
46
47 MP_DIGITS(&z1) = 0;
48 MP_DIGITS(&z2) = 0;
49 MP_DIGITS(&z3) = 0;
50 MP_CHECKOK(mp_init(&z1));
51 MP_CHECKOK(mp_init(&z2));
52 MP_CHECKOK(mp_init(&z3));
53
54 /* if point at infinity, then set point at infinity and exit */
55 if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
56 MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
57 goto CLEANUP;
58 }
59
60 /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
61 if (mp_cmp_d(pz, 1) == 0) {
62 MP_CHECKOK(mp_copy(px, rx));
63 MP_CHECKOK(mp_copy(py, ry));
64 } else {
65 MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
66 MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
67 MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
68 MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
69 MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
70 }
71
72 CLEANUP:
73 mp_clear(&z1);
74 mp_clear(&z2);
75 mp_clear(&z3);
76 return res;
77 }
78
79 /* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
80 * coordinates. */
81 mp_err
82 ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
83 {
84 return mp_cmp_z(pz);
85 }
86
87 /* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
88 * coordinates. */
89 mp_err
90 ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
91 {
92 mp_zero(pz);
93 return MP_OKAY;
94 }
95
96 /* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
97 * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
98 * Uses mixed Jacobian-affine coordinates. Assumes input is already
99 * field-encoded using field_enc, and returns output that is still
100 * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
101 * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
102 * Fields. */
103 mp_err
104 ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
105 const mp_int *qx, const mp_int *qy, mp _int *rx,
106 mp_int *ry, mp_int *rz, const ECGroup *group)
107 {
108 mp_err res = MP_OKAY;
109 mp_int A, B, C, D, C2, C3;
110
111 MP_DIGITS(&A) = 0;
112 MP_DIGITS(&B) = 0;
113 MP_DIGITS(&C) = 0;
114 MP_DIGITS(&D) = 0;
115 MP_DIGITS(&C2) = 0;
116 MP_DIGITS(&C3) = 0;
117 MP_CHECKOK(mp_init(&A));
118 MP_CHECKOK(mp_init(&B));
119 MP_CHECKOK(mp_init(&C));
120 MP_CHECKOK(mp_init(&D));
121 MP_CHECKOK(mp_init(&C2));
122 MP_CHECKOK(mp_init(&C3));
123
124 /* If either P or Q is the point at infinity, then return the other
125 * point */
126 if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
127 MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
128 goto CLEANUP;
129 }
130 if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
131 MP_CHECKOK(mp_copy(px, rx));
132 MP_CHECKOK(mp_copy(py, ry));
133 MP_CHECKOK(mp_copy(pz, rz));
134 goto CLEANUP;
135 }
136
137 /* A = qx * pz^2, B = qy * pz^3 */
138 MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
139 MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
140 MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
141 MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
142
143 /* C = A - px, D = B - py */
144 MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
145 MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
146
147 if (mp_cmp_z(&C) == 0) {
148 /* P == Q or P == -Q */
149 if (mp_cmp_z(&D) == 0) {
150 /* P == Q */
151 /* It is cheaper to double (qx, qy, 1) than (px, py, pz) . */
152 MP_DIGIT(&D, 0) = 1; /* Set D to 1. */
153 MP_CHECKOK(ec_GFp_pt_dbl_jac(qx, qy, &D, rx, ry, rz, gro up));
154 } else {
155 /* P == -Q */
156 MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
157 }
158 goto CLEANUP;
159 }
160
161 /* C2 = C^2, C3 = C^3 */
162 MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
163 MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
164
165 /* rz = pz * C */
166 MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
167
168 /* C = px * C^2 */
169 MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
170 /* A = D^2 */
171 MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
172
173 /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
174 MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
175 MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
176 MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
177
178 /* C3 = py * C^3 */
179 MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
180
181 /* ry = D * (px * C^2 - rx) - py * C^3 */
182 MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
183 MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
184 MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
185
186 CLEANUP:
187 mp_clear(&A);
188 mp_clear(&B);
189 mp_clear(&C);
190 mp_clear(&D);
191 mp_clear(&C2);
192 mp_clear(&C3);
193 return res;
194 }
195
196 /* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
197 * Jacobian coordinates.
198 *
199 * Assumes input is already field-encoded using field_enc, and returns
200 * output that is still field-encoded.
201 *
202 * This routine implements Point Doubling in the Jacobian Projective
203 * space as described in the paper "Efficient elliptic curve exponentiation
204 * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
205 */
206 mp_err
207 ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
208 mp_int *rx, mp_int *ry, mp_int *rz, const ECGr oup *group)
209 {
210 mp_err res = MP_OKAY;
211 mp_int t0, t1, M, S;
212
213 MP_DIGITS(&t0) = 0;
214 MP_DIGITS(&t1) = 0;
215 MP_DIGITS(&M) = 0;
216 MP_DIGITS(&S) = 0;
217 MP_CHECKOK(mp_init(&t0));
218 MP_CHECKOK(mp_init(&t1));
219 MP_CHECKOK(mp_init(&M));
220 MP_CHECKOK(mp_init(&S));
221
222 /* P == inf or P == -P */
223 if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES || mp_cmp_z(py) == 0) {
224 MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
225 goto CLEANUP;
226 }
227
228 if (mp_cmp_d(pz, 1) == 0) {
229 /* M = 3 * px^2 + a */
230 MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
231 MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
232 MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
233 MP_CHECKOK(group->meth->
234 field_add(&t0, &group->curvea, &M, group->met h));
235 } else if (mp_cmp_int(&group->curvea, -3) == 0) {
236 /* M = 3 * (px + pz^2) * (px - pz^2) */
237 MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
238 MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
239 MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
240 MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
241 MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
242 MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
243 } else {
244 /* M = 3 * (px^2) + a * (pz^4) */
245 MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
246 MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
247 MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
248 MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
249 MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
250 MP_CHECKOK(group->meth->
251 field_mul(&M, &group->curvea, &M, group->meth ));
252 MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
253 }
254
255 /* rz = 2 * py * pz */
256 /* t0 = 4 * py^2 */
257 if (mp_cmp_d(pz, 1) == 0) {
258 MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
259 MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
260 } else {
261 MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
262 MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
263 MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
264 }
265
266 /* S = 4 * px * py^2 = px * (2 * py)^2 */
267 MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
268
269 /* rx = M^2 - 2 * S */
270 MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
271 MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
272 MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
273
274 /* ry = M * (S - rx) - 8 * py^4 */
275 MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
276 if (mp_isodd(&t1)) {
277 MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
278 }
279 MP_CHECKOK(mp_div_2(&t1, &t1));
280 MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
281 MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
282 MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
283
284 CLEANUP:
285 mp_clear(&t0);
286 mp_clear(&t1);
287 mp_clear(&M);
288 mp_clear(&S);
289 return res;
290 }
291
292 /* by default, this routine is unused and thus doesn't need to be compiled */
293 #ifdef ECL_ENABLE_GFP_PT_MUL_JAC
294 /* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
295 * a, b and p are the elliptic curve coefficients and the prime that
296 * determines the field GFp. Elliptic curve points P and R can be
297 * identical. Uses mixed Jacobian-affine coordinates. Assumes input is
298 * already field-encoded using field_enc, and returns output that is still
299 * field-encoded. Uses 4-bit window method. */
300 mp_err
301 ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
302 mp_int *rx, mp_int *ry, const ECGroup *group)
303 {
304 mp_err res = MP_OKAY;
305 mp_int precomp[16][2], rz;
306 int i, ni, d;
307
308 MP_DIGITS(&rz) = 0;
309 for (i = 0; i < 16; i++) {
310 MP_DIGITS(&precomp[i][0]) = 0;
311 MP_DIGITS(&precomp[i][1]) = 0;
312 }
313
314 ARGCHK(group != NULL, MP_BADARG);
315 ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
316
317 /* initialize precomputation table */
318 for (i = 0; i < 16; i++) {
319 MP_CHECKOK(mp_init(&precomp[i][0]));
320 MP_CHECKOK(mp_init(&precomp[i][1]));
321 }
322
323 /* fill precomputation table */
324 mp_zero(&precomp[0][0]);
325 mp_zero(&precomp[0][1]);
326 MP_CHECKOK(mp_copy(px, &precomp[1][0]));
327 MP_CHECKOK(mp_copy(py, &precomp[1][1]));
328 for (i = 2; i < 16; i++) {
329 MP_CHECKOK(group->
330 point_add(&precomp[1][0], &precomp[1][1],
331 &precomp[i - 1][0], &pr ecomp[i - 1][1],
332 &precomp[i][0], &precom p[i][1], group));
333 }
334
335 d = (mpl_significant_bits(n) + 3) / 4;
336
337 /* R = inf */
338 MP_CHECKOK(mp_init(&rz));
339 MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
340
341 for (i = d - 1; i >= 0; i--) {
342 /* compute window ni */
343 ni = MP_GET_BIT(n, 4 * i + 3);
344 ni <<= 1;
345 ni |= MP_GET_BIT(n, 4 * i + 2);
346 ni <<= 1;
347 ni |= MP_GET_BIT(n, 4 * i + 1);
348 ni <<= 1;
349 ni |= MP_GET_BIT(n, 4 * i);
350 /* R = 2^4 * R */
351 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
352 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
353 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
354 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
355 /* R = R + (ni * P) */
356 MP_CHECKOK(ec_GFp_pt_add_jac_aff
357 (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1 ], rx, ry,
358 &rz, group));
359 }
360
361 /* convert result S to affine coordinates */
362 MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
363
364 CLEANUP:
365 mp_clear(&rz);
366 for (i = 0; i < 16; i++) {
367 mp_clear(&precomp[i][0]);
368 mp_clear(&precomp[i][1]);
369 }
370 return res;
371 }
372 #endif
373
374 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
375 * k2 * P(x, y), where G is the generator (base point) of the group of
376 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
377 * Uses mixed Jacobian-affine coordinates. Input and output values are
378 * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
379 * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
380 * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
381 mp_err
382 ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
383 const mp_int *py, mp_int *rx, mp_int *ry,
384 const ECGroup *group)
385 {
386 mp_err res = MP_OKAY;
387 mp_int precomp[4][4][2];
388 mp_int rz;
389 const mp_int *a, *b;
390 unsigned int i, j;
391 int ai, bi, d;
392
393 for (i = 0; i < 4; i++) {
394 for (j = 0; j < 4; j++) {
395 MP_DIGITS(&precomp[i][j][0]) = 0;
396 MP_DIGITS(&precomp[i][j][1]) = 0;
397 }
398 }
399 MP_DIGITS(&rz) = 0;
400
401 ARGCHK(group != NULL, MP_BADARG);
402 ARGCHK(!((k1 == NULL)
403 && ((k2 == NULL) || (px == NULL)
404 || (py == NULL))), MP_BADARG);
405
406 /* if some arguments are not defined used ECPoint_mul */
407 if (k1 == NULL) {
408 return ECPoint_mul(group, k2, px, py, rx, ry);
409 } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
410 return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
411 }
412
413 /* initialize precomputation table */
414 for (i = 0; i < 4; i++) {
415 for (j = 0; j < 4; j++) {
416 MP_CHECKOK(mp_init(&precomp[i][j][0]));
417 MP_CHECKOK(mp_init(&precomp[i][j][1]));
418 }
419 }
420
421 /* fill precomputation table */
422 /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
423 if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
424 a = k2;
425 b = k1;
426 if (group->meth->field_enc) {
427 MP_CHECKOK(group->meth->
428 field_enc(px, &precomp[1][0][0], grou p->meth));
429 MP_CHECKOK(group->meth->
430 field_enc(py, &precomp[1][0][1], grou p->meth));
431 } else {
432 MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
433 MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
434 }
435 MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
436 MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
437 } else {
438 a = k1;
439 b = k2;
440 MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
441 MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
442 if (group->meth->field_enc) {
443 MP_CHECKOK(group->meth->
444 field_enc(px, &precomp[0][1][0], grou p->meth));
445 MP_CHECKOK(group->meth->
446 field_enc(py, &precomp[0][1][1], grou p->meth));
447 } else {
448 MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
449 MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
450 }
451 }
452 /* precompute [*][0][*] */
453 mp_zero(&precomp[0][0][0]);
454 mp_zero(&precomp[0][0][1]);
455 MP_CHECKOK(group->
456 point_dbl(&precomp[1][0][0], &precomp[1][0][1],
457 &precomp[2][0][0], &precomp[2][ 0][1], group));
458 MP_CHECKOK(group->
459 point_add(&precomp[1][0][0], &precomp[1][0][1],
460 &precomp[2][0][0], &precomp[2][ 0][1],
461 &precomp[3][0][0], &precomp[3][ 0][1], group));
462 /* precompute [*][1][*] */
463 for (i = 1; i < 4; i++) {
464 MP_CHECKOK(group->
465 point_add(&precomp[0][1][0], &precomp[0][1][1 ],
466 &precomp[i][0][0], &pre comp[i][0][1],
467 &precomp[i][1][0], &pre comp[i][1][1], group));
468 }
469 /* precompute [*][2][*] */
470 MP_CHECKOK(group->
471 point_dbl(&precomp[0][1][0], &precomp[0][1][1],
472 &precomp[0][2][0], &precomp[0][ 2][1], group));
473 for (i = 1; i < 4; i++) {
474 MP_CHECKOK(group->
475 point_add(&precomp[0][2][0], &precomp[0][2][1 ],
476 &precomp[i][0][0], &pre comp[i][0][1],
477 &precomp[i][2][0], &pre comp[i][2][1], group));
478 }
479 /* precompute [*][3][*] */
480 MP_CHECKOK(group->
481 point_add(&precomp[0][1][0], &precomp[0][1][1],
482 &precomp[0][2][0], &precomp[0][ 2][1],
483 &precomp[0][3][0], &precomp[0][ 3][1], group));
484 for (i = 1; i < 4; i++) {
485 MP_CHECKOK(group->
486 point_add(&precomp[0][3][0], &precomp[0][3][1 ],
487 &precomp[i][0][0], &pre comp[i][0][1],
488 &precomp[i][3][0], &pre comp[i][3][1], group));
489 }
490
491 d = (mpl_significant_bits(a) + 1) / 2;
492
493 /* R = inf */
494 MP_CHECKOK(mp_init(&rz));
495 MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
496
497 for (i = d; i-- > 0;) {
498 ai = MP_GET_BIT(a, 2 * i + 1);
499 ai <<= 1;
500 ai |= MP_GET_BIT(a, 2 * i);
501 bi = MP_GET_BIT(b, 2 * i + 1);
502 bi <<= 1;
503 bi |= MP_GET_BIT(b, 2 * i);
504 /* R = 2^2 * R */
505 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
506 MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
507 /* R = R + (ai * A + bi * B) */
508 MP_CHECKOK(ec_GFp_pt_add_jac_aff
509 (rx, ry, &rz, &precomp[ai][bi][0], &precomp[a i][bi][1],
510 rx, ry, &rz, group));
511 }
512
513 MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
514
515 if (group->meth->field_dec) {
516 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
517 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
518 }
519
520 CLEANUP:
521 mp_clear(&rz);
522 for (i = 0; i < 4; i++) {
523 for (j = 0; j < 4; j++) {
524 mp_clear(&precomp[i][j][0]);
525 mp_clear(&precomp[i][j][1]);
526 }
527 }
528 return res;
529 }
OLDNEW
« no previous file with comments | « nss/lib/freebl/ecl/ecp_aff.c ('k') | nss/lib/freebl/ecl/ecp_jm.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698