security/nss/lib/freebl/ecl/tests/ecp_fpt.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "ecp_fp.h"
michael@0 6 #include "mpprime.h"
michael@0 7
michael@0 8 #include <stdio.h>
michael@0 9 #include <time.h>
michael@0 10 #include <sys/time.h>
michael@0 11 #include <sys/resource.h>
michael@0 12
michael@0 13 /* Time k repetitions of operation op. */
michael@0 14 #define M_TimeOperation(op, k) { \
michael@0 15 double dStart, dNow, dUserTime; \
michael@0 16 struct rusage ru; \
michael@0 17 int i; \
michael@0 18 getrusage(RUSAGE_SELF, &ru); \
michael@0 19 dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
michael@0 20 for (i = 0; i < k; i++) { \
michael@0 21 { op; } \
michael@0 22 }; \
michael@0 23 getrusage(RUSAGE_SELF, &ru); \
michael@0 24 dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
michael@0 25 dUserTime = dNow-dStart; \
michael@0 26 if (dUserTime) printf(" %-45s\n k: %6i, t: %6.2f sec, k/t: %6.2f ops/sec\n", #op, k, dUserTime, k/dUserTime); \
michael@0 27 }
michael@0 28
michael@0 29 /* Test curve using specific floating point field arithmetic. */
michael@0 30 #define M_TestCurve(name_c, name) { \
michael@0 31 printf("Testing %s using specific floating point implementation...\n", name_c); \
michael@0 32 ECGroup_free(ecgroup); \
michael@0 33 ecgroup = ECGroup_fromName(name); \
michael@0 34 if (ecgroup == NULL) { \
michael@0 35 printf(" Warning: could not construct group.\n"); \
michael@0 36 printf("%s failed.\n", name_c); \
michael@0 37 res = MP_NO; \
michael@0 38 goto CLEANUP; \
michael@0 39 } else { \
michael@0 40 MP_CHECKOK( testCurve(ecgroup)); \
michael@0 41 printf("%s passed.\n", name_c); \
michael@0 42 } \
michael@0 43 }
michael@0 44
michael@0 45 /* Outputs a floating point double (currently not used) */
michael@0 46 void
michael@0 47 d_output(const double *u, int len, char *name, const EC_group_fp * group)
michael@0 48 {
michael@0 49 int i;
michael@0 50
michael@0 51 printf("%s: ", name);
michael@0 52 for (i = 0; i < len; i++) {
michael@0 53 printf("+ %.2f * 2^%i ", u[i] / ecfp_exp[i],
michael@0 54 group->doubleBitSize * i);
michael@0 55 }
michael@0 56 printf("\n");
michael@0 57 }
michael@0 58
michael@0 59 /* Tests a point p in Jacobian coordinates, comparing against the
michael@0 60 * expected affine result (x, y). */
michael@0 61 mp_err
michael@0 62 testJacPoint(ecfp_jac_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup)
michael@0 63 {
michael@0 64 char s[1000];
michael@0 65 mp_int rx, ry, rz;
michael@0 66 mp_err res = MP_OKAY;
michael@0 67
michael@0 68 MP_DIGITS(&rx) = 0;
michael@0 69 MP_DIGITS(&ry) = 0;
michael@0 70 MP_DIGITS(&rz) = 0;
michael@0 71
michael@0 72 MP_CHECKOK(mp_init(&rx));
michael@0 73 MP_CHECKOK(mp_init(&ry));
michael@0 74 MP_CHECKOK(mp_init(&rz));
michael@0 75
michael@0 76 ecfp_fp2i(&rx, p->x, ecgroup);
michael@0 77 ecfp_fp2i(&ry, p->y, ecgroup);
michael@0 78 ecfp_fp2i(&rz, p->z, ecgroup);
michael@0 79
michael@0 80 /* convert result R to affine coordinates */
michael@0 81 ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
michael@0 82
michael@0 83 /* Compare to expected result */
michael@0 84 if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
michael@0 85 printf(" Error: Jacobian Floating Point Incorrect.\n");
michael@0 86 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 87 printf("floating point result\nrx %s\n", s);
michael@0 88 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 89 printf("ry %s\n", s);
michael@0 90 MP_CHECKOK(mp_toradix(x, s, 16));
michael@0 91 printf("integer result\nx %s\n", s);
michael@0 92 MP_CHECKOK(mp_toradix(y, s, 16));
michael@0 93 printf("y %s\n", s);
michael@0 94 res = MP_NO;
michael@0 95 goto CLEANUP;
michael@0 96 }
michael@0 97
michael@0 98 CLEANUP:
michael@0 99 mp_clear(&rx);
michael@0 100 mp_clear(&ry);
michael@0 101 mp_clear(&rz);
michael@0 102
michael@0 103 return res;
michael@0 104 }
michael@0 105
michael@0 106 /* Tests a point p in Chudnovsky Jacobian coordinates, comparing against
michael@0 107 * the expected affine result (x, y). */
michael@0 108 mp_err
michael@0 109 testChudPoint(ecfp_chud_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup)
michael@0 110 {
michael@0 111
michael@0 112 char s[1000];
michael@0 113 mp_int rx, ry, rz, rz2, rz3, test;
michael@0 114 mp_err res = MP_OKAY;
michael@0 115
michael@0 116 /* Initialization */
michael@0 117 MP_DIGITS(&rx) = 0;
michael@0 118 MP_DIGITS(&ry) = 0;
michael@0 119 MP_DIGITS(&rz) = 0;
michael@0 120 MP_DIGITS(&rz2) = 0;
michael@0 121 MP_DIGITS(&rz3) = 0;
michael@0 122 MP_DIGITS(&test) = 0;
michael@0 123
michael@0 124 MP_CHECKOK(mp_init(&rx));
michael@0 125 MP_CHECKOK(mp_init(&ry));
michael@0 126 MP_CHECKOK(mp_init(&rz));
michael@0 127 MP_CHECKOK(mp_init(&rz2));
michael@0 128 MP_CHECKOK(mp_init(&rz3));
michael@0 129 MP_CHECKOK(mp_init(&test));
michael@0 130
michael@0 131 /* Convert to integers */
michael@0 132 ecfp_fp2i(&rx, p->x, ecgroup);
michael@0 133 ecfp_fp2i(&ry, p->y, ecgroup);
michael@0 134 ecfp_fp2i(&rz, p->z, ecgroup);
michael@0 135 ecfp_fp2i(&rz2, p->z2, ecgroup);
michael@0 136 ecfp_fp2i(&rz3, p->z3, ecgroup);
michael@0 137
michael@0 138 /* Verify z2, z3 are valid */
michael@0 139 mp_sqrmod(&rz, &ecgroup->meth->irr, &test);
michael@0 140 if (mp_cmp(&test, &rz2) != 0) {
michael@0 141 printf(" Error: rzp2 not valid\n");
michael@0 142 res = MP_NO;
michael@0 143 goto CLEANUP;
michael@0 144 }
michael@0 145 mp_mulmod(&test, &rz, &ecgroup->meth->irr, &test);
michael@0 146 if (mp_cmp(&test, &rz3) != 0) {
michael@0 147 printf(" Error: rzp2 not valid\n");
michael@0 148 res = MP_NO;
michael@0 149 goto CLEANUP;
michael@0 150 }
michael@0 151
michael@0 152 /* convert result R to affine coordinates */
michael@0 153 ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
michael@0 154
michael@0 155 /* Compare against expected result */
michael@0 156 if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
michael@0 157 printf(" Error: Chudnovsky Floating Point Incorrect.\n");
michael@0 158 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 159 printf("floating point result\nrx %s\n", s);
michael@0 160 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 161 printf("ry %s\n", s);
michael@0 162 MP_CHECKOK(mp_toradix(x, s, 16));
michael@0 163 printf("integer result\nx %s\n", s);
michael@0 164 MP_CHECKOK(mp_toradix(y, s, 16));
michael@0 165 printf("y %s\n", s);
michael@0 166 res = MP_NO;
michael@0 167 goto CLEANUP;
michael@0 168 }
michael@0 169
michael@0 170 CLEANUP:
michael@0 171 mp_clear(&rx);
michael@0 172 mp_clear(&ry);
michael@0 173 mp_clear(&rz);
michael@0 174 mp_clear(&rz2);
michael@0 175 mp_clear(&rz3);
michael@0 176 mp_clear(&test);
michael@0 177
michael@0 178 return res;
michael@0 179 }
michael@0 180
michael@0 181 /* Tests a point p in Modified Jacobian coordinates, comparing against the
michael@0 182 * expected affine result (x, y). */
michael@0 183 mp_err
michael@0 184 testJmPoint(ecfp_jm_pt * r, mp_int *x, mp_int *y, ECGroup *ecgroup)
michael@0 185 {
michael@0 186
michael@0 187 char s[1000];
michael@0 188 mp_int rx, ry, rz, raz4, test;
michael@0 189 mp_err res = MP_OKAY;
michael@0 190
michael@0 191 /* Initialization */
michael@0 192 MP_DIGITS(&rx) = 0;
michael@0 193 MP_DIGITS(&ry) = 0;
michael@0 194 MP_DIGITS(&rz) = 0;
michael@0 195 MP_DIGITS(&raz4) = 0;
michael@0 196 MP_DIGITS(&test) = 0;
michael@0 197
michael@0 198 MP_CHECKOK(mp_init(&rx));
michael@0 199 MP_CHECKOK(mp_init(&ry));
michael@0 200 MP_CHECKOK(mp_init(&rz));
michael@0 201 MP_CHECKOK(mp_init(&raz4));
michael@0 202 MP_CHECKOK(mp_init(&test));
michael@0 203
michael@0 204 /* Convert to integer */
michael@0 205 ecfp_fp2i(&rx, r->x, ecgroup);
michael@0 206 ecfp_fp2i(&ry, r->y, ecgroup);
michael@0 207 ecfp_fp2i(&rz, r->z, ecgroup);
michael@0 208 ecfp_fp2i(&raz4, r->az4, ecgroup);
michael@0 209
michael@0 210 /* Verify raz4 = rz^4 * a */
michael@0 211 mp_sqrmod(&rz, &ecgroup->meth->irr, &test);
michael@0 212 mp_sqrmod(&test, &ecgroup->meth->irr, &test);
michael@0 213 mp_mulmod(&test, &ecgroup->curvea, &ecgroup->meth->irr, &test);
michael@0 214 if (mp_cmp(&test, &raz4) != 0) {
michael@0 215 printf(" Error: a*z^4 not valid\n");
michael@0 216 MP_CHECKOK(mp_toradix(&ecgroup->curvea, s, 16));
michael@0 217 printf("a %s\n", s);
michael@0 218 MP_CHECKOK(mp_toradix(&rz, s, 16));
michael@0 219 printf("rz %s\n", s);
michael@0 220 MP_CHECKOK(mp_toradix(&raz4, s, 16));
michael@0 221 printf("raz4 %s\n", s);
michael@0 222 res = MP_NO;
michael@0 223 goto CLEANUP;
michael@0 224 }
michael@0 225
michael@0 226 /* convert result R to affine coordinates */
michael@0 227 ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
michael@0 228
michael@0 229 /* Compare against expected result */
michael@0 230 if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
michael@0 231 printf(" Error: Modified Jacobian Floating Point Incorrect.\n");
michael@0 232 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 233 printf("floating point result\nrx %s\n", s);
michael@0 234 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 235 printf("ry %s\n", s);
michael@0 236 MP_CHECKOK(mp_toradix(x, s, 16));
michael@0 237 printf("integer result\nx %s\n", s);
michael@0 238 MP_CHECKOK(mp_toradix(y, s, 16));
michael@0 239 printf("y %s\n", s);
michael@0 240 res = MP_NO;
michael@0 241 goto CLEANUP;
michael@0 242 }
michael@0 243 CLEANUP:
michael@0 244 mp_clear(&rx);
michael@0 245 mp_clear(&ry);
michael@0 246 mp_clear(&rz);
michael@0 247 mp_clear(&raz4);
michael@0 248 mp_clear(&test);
michael@0 249
michael@0 250 return res;
michael@0 251 }
michael@0 252
michael@0 253 /* Tests point addition of Jacobian + Affine -> Jacobian */
michael@0 254 mp_err
michael@0 255 testPointAddJacAff(ECGroup *ecgroup)
michael@0 256 {
michael@0 257 mp_err res;
michael@0 258 mp_int pz, rx2, ry2, rz2;
michael@0 259 ecfp_jac_pt p, r;
michael@0 260 ecfp_aff_pt q;
michael@0 261 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 262
michael@0 263 /* Init */
michael@0 264 MP_DIGITS(&pz) = 0;
michael@0 265 MP_DIGITS(&rx2) = 0;
michael@0 266 MP_DIGITS(&ry2) = 0;
michael@0 267 MP_DIGITS(&rz2) = 0;
michael@0 268 MP_CHECKOK(mp_init(&pz));
michael@0 269 MP_CHECKOK(mp_init(&rx2));
michael@0 270 MP_CHECKOK(mp_init(&ry2));
michael@0 271 MP_CHECKOK(mp_init(&rz2));
michael@0 272
michael@0 273 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 274
michael@0 275 /* Set p */
michael@0 276 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 277 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 278 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 279 /* Set q */
michael@0 280 ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
michael@0 281 ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
michael@0 282
michael@0 283 /* Do calculations */
michael@0 284 group->pt_add_jac_aff(&p, &q, &r, group);
michael@0 285
michael@0 286 /* Do calculation in integer to compare against */
michael@0 287 MP_CHECKOK(ec_GFp_pt_add_jac_aff
michael@0 288 (&ecgroup->genx, &ecgroup->geny, &pz, &ecgroup->geny,
michael@0 289 &ecgroup->genx, &rx2, &ry2, &rz2, ecgroup));
michael@0 290 /* convert result R to affine coordinates */
michael@0 291 ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
michael@0 292
michael@0 293 MP_CHECKOK(testJacPoint(&r, &rx2, &ry2, ecgroup));
michael@0 294
michael@0 295 CLEANUP:
michael@0 296 if (res == MP_OKAY)
michael@0 297 printf(" Test Passed - Point Addition - Jacobian & Affine\n");
michael@0 298 else
michael@0 299 printf("TEST FAILED - Point Addition - Jacobian & Affine\n");
michael@0 300
michael@0 301 mp_clear(&pz);
michael@0 302 mp_clear(&rx2);
michael@0 303 mp_clear(&ry2);
michael@0 304 mp_clear(&rz2);
michael@0 305
michael@0 306 return res;
michael@0 307 }
michael@0 308
michael@0 309 /* Tests point addition in Jacobian coordinates */
michael@0 310 mp_err
michael@0 311 testPointAddJac(ECGroup *ecgroup)
michael@0 312 {
michael@0 313 mp_err res;
michael@0 314 mp_int pz, qz, qx, qy, rx2, ry2, rz2;
michael@0 315 ecfp_jac_pt p, q, r;
michael@0 316 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 317
michael@0 318 /* Init */
michael@0 319 MP_DIGITS(&pz) = 0;
michael@0 320 MP_DIGITS(&qx) = 0;
michael@0 321 MP_DIGITS(&qy) = 0;
michael@0 322 MP_DIGITS(&qz) = 0;
michael@0 323 MP_DIGITS(&rx2) = 0;
michael@0 324 MP_DIGITS(&ry2) = 0;
michael@0 325 MP_DIGITS(&rz2) = 0;
michael@0 326 MP_CHECKOK(mp_init(&pz));
michael@0 327 MP_CHECKOK(mp_init(&qx));
michael@0 328 MP_CHECKOK(mp_init(&qy));
michael@0 329 MP_CHECKOK(mp_init(&qz));
michael@0 330 MP_CHECKOK(mp_init(&rx2));
michael@0 331 MP_CHECKOK(mp_init(&ry2));
michael@0 332 MP_CHECKOK(mp_init(&rz2));
michael@0 333
michael@0 334 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 335 MP_CHECKOK(mp_set_int(&qz, 105));
michael@0 336
michael@0 337 /* Set p */
michael@0 338 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 339 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 340 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 341 /* Set q */
michael@0 342 ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
michael@0 343 ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
michael@0 344 ecfp_i2fp(q.z, &qz, ecgroup);
michael@0 345
michael@0 346 /* Do calculations */
michael@0 347 group->pt_add_jac(&p, &q, &r, group);
michael@0 348
michael@0 349 /* Do calculation in integer to compare against */
michael@0 350 ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
michael@0 351 ecgroup);
michael@0 352 MP_CHECKOK(ec_GFp_pt_add_jac_aff
michael@0 353 (&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy, &rx2, &ry2,
michael@0 354 &rz2, ecgroup));
michael@0 355 /* convert result R to affine coordinates */
michael@0 356 ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
michael@0 357
michael@0 358 MP_CHECKOK(testJacPoint(&r, &rx2, &ry2, ecgroup));
michael@0 359
michael@0 360 CLEANUP:
michael@0 361 if (res == MP_OKAY)
michael@0 362 printf(" Test Passed - Point Addition - Jacobian\n");
michael@0 363 else
michael@0 364 printf("TEST FAILED - Point Addition - Jacobian\n");
michael@0 365
michael@0 366 mp_clear(&pz);
michael@0 367 mp_clear(&qx);
michael@0 368 mp_clear(&qy);
michael@0 369 mp_clear(&qz);
michael@0 370 mp_clear(&rx2);
michael@0 371 mp_clear(&ry2);
michael@0 372 mp_clear(&rz2);
michael@0 373
michael@0 374 return res;
michael@0 375 }
michael@0 376
michael@0 377 /* Tests point addition in Chudnovsky Jacobian Coordinates */
michael@0 378 mp_err
michael@0 379 testPointAddChud(ECGroup *ecgroup)
michael@0 380 {
michael@0 381 mp_err res;
michael@0 382 mp_int rx2, ry2, ix, iy, iz, test, pz, qx, qy, qz;
michael@0 383 ecfp_chud_pt p, q, r;
michael@0 384 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 385
michael@0 386 MP_DIGITS(&qx) = 0;
michael@0 387 MP_DIGITS(&qy) = 0;
michael@0 388 MP_DIGITS(&qz) = 0;
michael@0 389 MP_DIGITS(&pz) = 0;
michael@0 390 MP_DIGITS(&rx2) = 0;
michael@0 391 MP_DIGITS(&ry2) = 0;
michael@0 392 MP_DIGITS(&ix) = 0;
michael@0 393 MP_DIGITS(&iy) = 0;
michael@0 394 MP_DIGITS(&iz) = 0;
michael@0 395 MP_DIGITS(&test) = 0;
michael@0 396
michael@0 397 MP_CHECKOK(mp_init(&qx));
michael@0 398 MP_CHECKOK(mp_init(&qy));
michael@0 399 MP_CHECKOK(mp_init(&qz));
michael@0 400 MP_CHECKOK(mp_init(&pz));
michael@0 401 MP_CHECKOK(mp_init(&rx2));
michael@0 402 MP_CHECKOK(mp_init(&ry2));
michael@0 403 MP_CHECKOK(mp_init(&ix));
michael@0 404 MP_CHECKOK(mp_init(&iy));
michael@0 405 MP_CHECKOK(mp_init(&iz));
michael@0 406 MP_CHECKOK(mp_init(&test));
michael@0 407
michael@0 408 /* Test Chudnovsky form addition */
michael@0 409 /* Set p */
michael@0 410 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 411 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 412 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 413 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 414 mp_sqrmod(&pz, &ecgroup->meth->irr, &test);
michael@0 415 ecfp_i2fp(p.z2, &test, ecgroup);
michael@0 416 mp_mulmod(&test, &pz, &ecgroup->meth->irr, &test);
michael@0 417 ecfp_i2fp(p.z3, &test, ecgroup);
michael@0 418
michael@0 419 /* Set q */
michael@0 420 MP_CHECKOK(mp_set_int(&qz, 105));
michael@0 421 ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
michael@0 422 ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
michael@0 423 ecfp_i2fp(q.z, &qz, ecgroup);
michael@0 424 mp_sqrmod(&qz, &ecgroup->meth->irr, &test);
michael@0 425 ecfp_i2fp(q.z2, &test, ecgroup);
michael@0 426 mp_mulmod(&test, &qz, &ecgroup->meth->irr, &test);
michael@0 427 ecfp_i2fp(q.z3, &test, ecgroup);
michael@0 428
michael@0 429 group->pt_add_chud(&p, &q, &r, group);
michael@0 430
michael@0 431 /* Calculate addition to compare against */
michael@0 432 ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
michael@0 433 ecgroup);
michael@0 434 ec_GFp_pt_add_jac_aff(&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy,
michael@0 435 &ix, &iy, &iz, ecgroup);
michael@0 436 ec_GFp_pt_jac2aff(&ix, &iy, &iz, &rx2, &ry2, ecgroup);
michael@0 437
michael@0 438 MP_CHECKOK(testChudPoint(&r, &rx2, &ry2, ecgroup));
michael@0 439
michael@0 440 CLEANUP:
michael@0 441 if (res == MP_OKAY)
michael@0 442 printf(" Test Passed - Point Addition - Chudnovsky Jacobian\n");
michael@0 443 else
michael@0 444 printf("TEST FAILED - Point Addition - Chudnovsky Jacobian\n");
michael@0 445
michael@0 446 mp_clear(&qx);
michael@0 447 mp_clear(&qy);
michael@0 448 mp_clear(&qz);
michael@0 449 mp_clear(&pz);
michael@0 450 mp_clear(&rx2);
michael@0 451 mp_clear(&ry2);
michael@0 452 mp_clear(&ix);
michael@0 453 mp_clear(&iy);
michael@0 454 mp_clear(&iz);
michael@0 455 mp_clear(&test);
michael@0 456
michael@0 457 return res;
michael@0 458 }
michael@0 459
michael@0 460 /* Tests point addition in Modified Jacobian + Chudnovsky Jacobian ->
michael@0 461 * Modified Jacobian coordinates. */
michael@0 462 mp_err
michael@0 463 testPointAddJmChud(ECGroup *ecgroup)
michael@0 464 {
michael@0 465 mp_err res;
michael@0 466 mp_int rx2, ry2, ix, iy, iz, test, pz, paz4, qx, qy, qz;
michael@0 467 ecfp_chud_pt q;
michael@0 468 ecfp_jm_pt p, r;
michael@0 469 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 470
michael@0 471 MP_DIGITS(&qx) = 0;
michael@0 472 MP_DIGITS(&qy) = 0;
michael@0 473 MP_DIGITS(&qz) = 0;
michael@0 474 MP_DIGITS(&pz) = 0;
michael@0 475 MP_DIGITS(&paz4) = 0;
michael@0 476 MP_DIGITS(&iz) = 0;
michael@0 477 MP_DIGITS(&rx2) = 0;
michael@0 478 MP_DIGITS(&ry2) = 0;
michael@0 479 MP_DIGITS(&ix) = 0;
michael@0 480 MP_DIGITS(&iy) = 0;
michael@0 481 MP_DIGITS(&iz) = 0;
michael@0 482 MP_DIGITS(&test) = 0;
michael@0 483
michael@0 484 MP_CHECKOK(mp_init(&qx));
michael@0 485 MP_CHECKOK(mp_init(&qy));
michael@0 486 MP_CHECKOK(mp_init(&qz));
michael@0 487 MP_CHECKOK(mp_init(&pz));
michael@0 488 MP_CHECKOK(mp_init(&paz4));
michael@0 489 MP_CHECKOK(mp_init(&rx2));
michael@0 490 MP_CHECKOK(mp_init(&ry2));
michael@0 491 MP_CHECKOK(mp_init(&ix));
michael@0 492 MP_CHECKOK(mp_init(&iy));
michael@0 493 MP_CHECKOK(mp_init(&iz));
michael@0 494 MP_CHECKOK(mp_init(&test));
michael@0 495
michael@0 496 /* Test Modified Jacobian form addition */
michael@0 497 /* Set p */
michael@0 498 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 499 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 500 ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
michael@0 501 /* paz4 = az^4 */
michael@0 502 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 503 mp_sqrmod(&pz, &ecgroup->meth->irr, &paz4);
michael@0 504 mp_sqrmod(&paz4, &ecgroup->meth->irr, &paz4);
michael@0 505 mp_mulmod(&paz4, &ecgroup->curvea, &ecgroup->meth->irr, &paz4);
michael@0 506 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 507 ecfp_i2fp(p.az4, &paz4, ecgroup);
michael@0 508
michael@0 509 /* Set q */
michael@0 510 MP_CHECKOK(mp_set_int(&qz, 105));
michael@0 511 ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
michael@0 512 ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
michael@0 513 ecfp_i2fp(q.z, &qz, ecgroup);
michael@0 514 mp_sqrmod(&qz, &ecgroup->meth->irr, &test);
michael@0 515 ecfp_i2fp(q.z2, &test, ecgroup);
michael@0 516 mp_mulmod(&test, &qz, &ecgroup->meth->irr, &test);
michael@0 517 ecfp_i2fp(q.z3, &test, ecgroup);
michael@0 518
michael@0 519 /* Do calculation */
michael@0 520 group->pt_add_jm_chud(&p, &q, &r, group);
michael@0 521
michael@0 522 /* Calculate addition to compare against */
michael@0 523 ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
michael@0 524 ecgroup);
michael@0 525 ec_GFp_pt_add_jac_aff(&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy,
michael@0 526 &ix, &iy, &iz, ecgroup);
michael@0 527 ec_GFp_pt_jac2aff(&ix, &iy, &iz, &rx2, &ry2, ecgroup);
michael@0 528
michael@0 529 MP_CHECKOK(testJmPoint(&r, &rx2, &ry2, ecgroup));
michael@0 530
michael@0 531 CLEANUP:
michael@0 532 if (res == MP_OKAY)
michael@0 533 printf
michael@0 534 (" Test Passed - Point Addition - Modified & Chudnovsky Jacobian\n");
michael@0 535 else
michael@0 536 printf
michael@0 537 ("TEST FAILED - Point Addition - Modified & Chudnovsky Jacobian\n");
michael@0 538
michael@0 539 mp_clear(&qx);
michael@0 540 mp_clear(&qy);
michael@0 541 mp_clear(&qz);
michael@0 542 mp_clear(&pz);
michael@0 543 mp_clear(&paz4);
michael@0 544 mp_clear(&rx2);
michael@0 545 mp_clear(&ry2);
michael@0 546 mp_clear(&ix);
michael@0 547 mp_clear(&iy);
michael@0 548 mp_clear(&iz);
michael@0 549 mp_clear(&test);
michael@0 550
michael@0 551 return res;
michael@0 552 }
michael@0 553
michael@0 554 /* Tests point doubling in Modified Jacobian coordinates */
michael@0 555 mp_err
michael@0 556 testPointDoubleJm(ECGroup *ecgroup)
michael@0 557 {
michael@0 558 mp_err res;
michael@0 559 mp_int pz, paz4, rx2, ry2, rz2, raz4;
michael@0 560 ecfp_jm_pt p, r;
michael@0 561 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 562
michael@0 563 MP_DIGITS(&pz) = 0;
michael@0 564 MP_DIGITS(&paz4) = 0;
michael@0 565 MP_DIGITS(&rx2) = 0;
michael@0 566 MP_DIGITS(&ry2) = 0;
michael@0 567 MP_DIGITS(&rz2) = 0;
michael@0 568 MP_DIGITS(&raz4) = 0;
michael@0 569
michael@0 570 MP_CHECKOK(mp_init(&pz));
michael@0 571 MP_CHECKOK(mp_init(&paz4));
michael@0 572 MP_CHECKOK(mp_init(&rx2));
michael@0 573 MP_CHECKOK(mp_init(&ry2));
michael@0 574 MP_CHECKOK(mp_init(&rz2));
michael@0 575 MP_CHECKOK(mp_init(&raz4));
michael@0 576
michael@0 577 /* Set p */
michael@0 578 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 579 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 580 ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
michael@0 581
michael@0 582 /* paz4 = az^4 */
michael@0 583 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 584 mp_sqrmod(&pz, &ecgroup->meth->irr, &paz4);
michael@0 585 mp_sqrmod(&paz4, &ecgroup->meth->irr, &paz4);
michael@0 586 mp_mulmod(&paz4, &ecgroup->curvea, &ecgroup->meth->irr, &paz4);
michael@0 587
michael@0 588 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 589 ecfp_i2fp(p.az4, &paz4, ecgroup);
michael@0 590
michael@0 591 group->pt_dbl_jm(&p, &r, group);
michael@0 592
michael@0 593 M_TimeOperation(group->pt_dbl_jm(&p, &r, group), 100000);
michael@0 594
michael@0 595 /* Calculate doubling to compare against */
michael@0 596 ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
michael@0 597 &rz2, ecgroup);
michael@0 598 ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
michael@0 599
michael@0 600 /* Do comparison and check az^4 */
michael@0 601 MP_CHECKOK(testJmPoint(&r, &rx2, &ry2, ecgroup));
michael@0 602
michael@0 603 CLEANUP:
michael@0 604 if (res == MP_OKAY)
michael@0 605 printf(" Test Passed - Point Doubling - Modified Jacobian\n");
michael@0 606 else
michael@0 607 printf("TEST FAILED - Point Doubling - Modified Jacobian\n");
michael@0 608 mp_clear(&pz);
michael@0 609 mp_clear(&paz4);
michael@0 610 mp_clear(&rx2);
michael@0 611 mp_clear(&ry2);
michael@0 612 mp_clear(&rz2);
michael@0 613 mp_clear(&raz4);
michael@0 614
michael@0 615 return res;
michael@0 616
michael@0 617 }
michael@0 618
michael@0 619 /* Tests point doubling in Chudnovsky Jacobian coordinates */
michael@0 620 mp_err
michael@0 621 testPointDoubleChud(ECGroup *ecgroup)
michael@0 622 {
michael@0 623 mp_err res;
michael@0 624 mp_int px, py, pz, rx2, ry2, rz2;
michael@0 625 ecfp_aff_pt p;
michael@0 626 ecfp_chud_pt p2;
michael@0 627 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 628
michael@0 629 MP_DIGITS(&rx2) = 0;
michael@0 630 MP_DIGITS(&ry2) = 0;
michael@0 631 MP_DIGITS(&rz2) = 0;
michael@0 632 MP_DIGITS(&px) = 0;
michael@0 633 MP_DIGITS(&py) = 0;
michael@0 634 MP_DIGITS(&pz) = 0;
michael@0 635
michael@0 636 MP_CHECKOK(mp_init(&rx2));
michael@0 637 MP_CHECKOK(mp_init(&ry2));
michael@0 638 MP_CHECKOK(mp_init(&rz2));
michael@0 639 MP_CHECKOK(mp_init(&px));
michael@0 640 MP_CHECKOK(mp_init(&py));
michael@0 641 MP_CHECKOK(mp_init(&pz));
michael@0 642
michael@0 643 /* Set p2 = 2P */
michael@0 644 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 645 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 646 ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
michael@0 647
michael@0 648 group->pt_dbl_aff2chud(&p, &p2, group);
michael@0 649
michael@0 650 /* Calculate doubling to compare against */
michael@0 651 MP_CHECKOK(mp_set_int(&pz, 1));
michael@0 652 ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
michael@0 653 &rz2, ecgroup);
michael@0 654 ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
michael@0 655
michael@0 656 /* Do comparison and check az^4 */
michael@0 657 MP_CHECKOK(testChudPoint(&p2, &rx2, &ry2, ecgroup));
michael@0 658
michael@0 659 CLEANUP:
michael@0 660 if (res == MP_OKAY)
michael@0 661 printf(" Test Passed - Point Doubling - Chudnovsky Jacobian\n");
michael@0 662 else
michael@0 663 printf("TEST FAILED - Point Doubling - Chudnovsky Jacobian\n");
michael@0 664
michael@0 665 mp_clear(&rx2);
michael@0 666 mp_clear(&ry2);
michael@0 667 mp_clear(&rz2);
michael@0 668 mp_clear(&px);
michael@0 669 mp_clear(&py);
michael@0 670 mp_clear(&pz);
michael@0 671
michael@0 672 return res;
michael@0 673 }
michael@0 674
michael@0 675 /* Test point doubling in Jacobian coordinates */
michael@0 676 mp_err
michael@0 677 testPointDoubleJac(ECGroup *ecgroup)
michael@0 678 {
michael@0 679 mp_err res;
michael@0 680 mp_int pz, rx, ry, rz, rx2, ry2, rz2;
michael@0 681 ecfp_jac_pt p, p2;
michael@0 682 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 683
michael@0 684 MP_DIGITS(&pz) = 0;
michael@0 685 MP_DIGITS(&rx) = 0;
michael@0 686 MP_DIGITS(&ry) = 0;
michael@0 687 MP_DIGITS(&rz) = 0;
michael@0 688 MP_DIGITS(&rx2) = 0;
michael@0 689 MP_DIGITS(&ry2) = 0;
michael@0 690 MP_DIGITS(&rz2) = 0;
michael@0 691
michael@0 692 MP_CHECKOK(mp_init(&pz));
michael@0 693 MP_CHECKOK(mp_init(&rx));
michael@0 694 MP_CHECKOK(mp_init(&ry));
michael@0 695 MP_CHECKOK(mp_init(&rz));
michael@0 696 MP_CHECKOK(mp_init(&rx2));
michael@0 697 MP_CHECKOK(mp_init(&ry2));
michael@0 698 MP_CHECKOK(mp_init(&rz2));
michael@0 699
michael@0 700 MP_CHECKOK(mp_set_int(&pz, 5));
michael@0 701
michael@0 702 /* Set p2 = 2P */
michael@0 703 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 704 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 705 ecfp_i2fp(p.z, &pz, ecgroup);
michael@0 706 ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
michael@0 707
michael@0 708 group->pt_dbl_jac(&p, &p2, group);
michael@0 709 M_TimeOperation(group->pt_dbl_jac(&p, &p2, group), 100000);
michael@0 710
michael@0 711 /* Calculate doubling to compare against */
michael@0 712 ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
michael@0 713 &rz2, ecgroup);
michael@0 714 ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
michael@0 715
michael@0 716 /* Do comparison */
michael@0 717 MP_CHECKOK(testJacPoint(&p2, &rx2, &ry2, ecgroup));
michael@0 718
michael@0 719 CLEANUP:
michael@0 720 if (res == MP_OKAY)
michael@0 721 printf(" Test Passed - Point Doubling - Jacobian\n");
michael@0 722 else
michael@0 723 printf("TEST FAILED - Point Doubling - Jacobian\n");
michael@0 724
michael@0 725 mp_clear(&pz);
michael@0 726 mp_clear(&rx);
michael@0 727 mp_clear(&ry);
michael@0 728 mp_clear(&rz);
michael@0 729 mp_clear(&rx2);
michael@0 730 mp_clear(&ry2);
michael@0 731 mp_clear(&rz2);
michael@0 732
michael@0 733 return res;
michael@0 734 }
michael@0 735
michael@0 736 /* Tests a point multiplication (various algorithms) */
michael@0 737 mp_err
michael@0 738 testPointMul(ECGroup *ecgroup)
michael@0 739 {
michael@0 740 mp_err res;
michael@0 741 char s[1000];
michael@0 742 mp_int rx, ry, order_1;
michael@0 743
michael@0 744 /* Init */
michael@0 745 MP_DIGITS(&rx) = 0;
michael@0 746 MP_DIGITS(&ry) = 0;
michael@0 747 MP_DIGITS(&order_1) = 0;
michael@0 748
michael@0 749 MP_CHECKOK(mp_init(&rx));
michael@0 750 MP_CHECKOK(mp_init(&ry));
michael@0 751 MP_CHECKOK(mp_init(&order_1));
michael@0 752
michael@0 753 MP_CHECKOK(mp_set_int(&order_1, 1));
michael@0 754 MP_CHECKOK(mp_sub(&ecgroup->order, &order_1, &order_1));
michael@0 755
michael@0 756 /* Test Algorithm 1: Jacobian-Affine Double & Add */
michael@0 757 ec_GFp_pt_mul_jac_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx,
michael@0 758 &ry, ecgroup);
michael@0 759 MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
michael@0 760 if ((mp_cmp(&rx, &ecgroup->genx) != 0)
michael@0 761 || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
michael@0 762 printf
michael@0 763 (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected (- base point)).\n");
michael@0 764 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 765 printf("rx %s\n", s);
michael@0 766 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 767 printf("ry %s\n", s);
michael@0 768 res = MP_NO;
michael@0 769 goto CLEANUP;
michael@0 770 }
michael@0 771
michael@0 772 ec_GFp_pt_mul_jac_fp(&ecgroup->order, &ecgroup->genx, &ecgroup->geny,
michael@0 773 &rx, &ry, ecgroup);
michael@0 774 if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
michael@0 775 printf
michael@0 776 (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected point at infinity.\n");
michael@0 777 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 778 printf("rx %s\n", s);
michael@0 779 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 780 printf("ry %s\n", s);
michael@0 781 res = MP_NO;
michael@0 782 goto CLEANUP;
michael@0 783 }
michael@0 784
michael@0 785 /* Test Algorithm 2: 4-bit Window in Jacobian */
michael@0 786 ec_GFp_point_mul_jac_4w_fp(&order_1, &ecgroup->genx, &ecgroup->geny,
michael@0 787 &rx, &ry, ecgroup);
michael@0 788 MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
michael@0 789 if ((mp_cmp(&rx, &ecgroup->genx) != 0)
michael@0 790 || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
michael@0 791 printf
michael@0 792 (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected (- base point)).\n");
michael@0 793 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 794 printf("rx %s\n", s);
michael@0 795 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 796 printf("ry %s\n", s);
michael@0 797 res = MP_NO;
michael@0 798 goto CLEANUP;
michael@0 799 }
michael@0 800
michael@0 801 ec_GFp_point_mul_jac_4w_fp(&ecgroup->order, &ecgroup->genx,
michael@0 802 &ecgroup->geny, &rx, &ry, ecgroup);
michael@0 803 if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
michael@0 804 printf
michael@0 805 (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected point at infinity.\n");
michael@0 806 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 807 printf("rx %s\n", s);
michael@0 808 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 809 printf("ry %s\n", s);
michael@0 810 res = MP_NO;
michael@0 811 goto CLEANUP;
michael@0 812 }
michael@0 813
michael@0 814 /* Test Algorithm 3: wNAF with modified Jacobian coordinates */
michael@0 815 ec_GFp_point_mul_wNAF_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx,
michael@0 816 &ry, ecgroup);
michael@0 817 MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
michael@0 818 if ((mp_cmp(&rx, &ecgroup->genx) != 0)
michael@0 819 || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
michael@0 820 printf
michael@0 821 (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected (- base point)).\n");
michael@0 822 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 823 printf("rx %s\n", s);
michael@0 824 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 825 printf("ry %s\n", s);
michael@0 826 res = MP_NO;
michael@0 827 goto CLEANUP;
michael@0 828 }
michael@0 829
michael@0 830 ec_GFp_point_mul_wNAF_fp(&ecgroup->order, &ecgroup->genx,
michael@0 831 &ecgroup->geny, &rx, &ry, ecgroup);
michael@0 832 if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
michael@0 833 printf
michael@0 834 (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected point at infinity.\n");
michael@0 835 MP_CHECKOK(mp_toradix(&rx, s, 16));
michael@0 836 printf("rx %s\n", s);
michael@0 837 MP_CHECKOK(mp_toradix(&ry, s, 16));
michael@0 838 printf("ry %s\n", s);
michael@0 839 res = MP_NO;
michael@0 840 goto CLEANUP;
michael@0 841 }
michael@0 842
michael@0 843 CLEANUP:
michael@0 844 if (res == MP_OKAY)
michael@0 845 printf(" Test Passed - Point Multiplication\n");
michael@0 846 else
michael@0 847 printf("TEST FAILED - Point Multiplication\n");
michael@0 848 mp_clear(&rx);
michael@0 849 mp_clear(&ry);
michael@0 850 mp_clear(&order_1);
michael@0 851
michael@0 852 return res;
michael@0 853 }
michael@0 854
michael@0 855 /* Tests point multiplication with a random scalar repeatedly, comparing
michael@0 856 * for consistency within different algorithms. */
michael@0 857 mp_err
michael@0 858 testPointMulRandom(ECGroup *ecgroup)
michael@0 859 {
michael@0 860 mp_err res;
michael@0 861 mp_int rx, ry, rx2, ry2, n;
michael@0 862 int i, size;
michael@0 863 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 864
michael@0 865 MP_DIGITS(&rx) = 0;
michael@0 866 MP_DIGITS(&ry) = 0;
michael@0 867 MP_DIGITS(&rx2) = 0;
michael@0 868 MP_DIGITS(&ry2) = 0;
michael@0 869 MP_DIGITS(&n) = 0;
michael@0 870
michael@0 871 MP_CHECKOK(mp_init(&rx));
michael@0 872 MP_CHECKOK(mp_init(&ry));
michael@0 873 MP_CHECKOK(mp_init(&rx2));
michael@0 874 MP_CHECKOK(mp_init(&ry2));
michael@0 875 MP_CHECKOK(mp_init(&n));
michael@0 876
michael@0 877 for (i = 0; i < 100; i++) {
michael@0 878 /* compute random scalar */
michael@0 879 size = mpl_significant_bits(&ecgroup->meth->irr);
michael@0 880 if (size < MP_OKAY) {
michael@0 881 res = MP_NO;
michael@0 882 goto CLEANUP;
michael@0 883 }
michael@0 884 MP_CHECKOK(mpp_random_size(&n, group->orderBitSize));
michael@0 885 MP_CHECKOK(mp_mod(&n, &ecgroup->order, &n));
michael@0 886
michael@0 887 ec_GFp_pt_mul_jac(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
michael@0 888 ecgroup);
michael@0 889 ec_GFp_pt_mul_jac_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx2,
michael@0 890 &ry2, ecgroup);
michael@0 891
michael@0 892 if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
michael@0 893 printf
michael@0 894 (" Error: different results for Point Multiplication - Double & Add.\n");
michael@0 895 res = MP_NO;
michael@0 896 goto CLEANUP;
michael@0 897 }
michael@0 898
michael@0 899 ec_GFp_point_mul_wNAF_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx,
michael@0 900 &ry, ecgroup);
michael@0 901 if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
michael@0 902 printf
michael@0 903 (" Error: different results for Point Multiplication - wNAF.\n");
michael@0 904 res = MP_NO;
michael@0 905 goto CLEANUP;
michael@0 906 }
michael@0 907
michael@0 908 ec_GFp_point_mul_jac_4w_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx,
michael@0 909 &ry, ecgroup);
michael@0 910 if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
michael@0 911 printf
michael@0 912 (" Error: different results for Point Multiplication - 4 bit window.\n");
michael@0 913 res = MP_NO;
michael@0 914 goto CLEANUP;
michael@0 915 }
michael@0 916
michael@0 917 }
michael@0 918
michael@0 919 CLEANUP:
michael@0 920 if (res == MP_OKAY)
michael@0 921 printf(" Test Passed - Point Random Multiplication\n");
michael@0 922 else
michael@0 923 printf("TEST FAILED - Point Random Multiplication\n");
michael@0 924 mp_clear(&rx);
michael@0 925 mp_clear(&ry);
michael@0 926 mp_clear(&rx2);
michael@0 927 mp_clear(&ry2);
michael@0 928 mp_clear(&n);
michael@0 929
michael@0 930 return res;
michael@0 931 }
michael@0 932
michael@0 933 /* Tests the time required for a point multiplication */
michael@0 934 mp_err
michael@0 935 testPointMulTime(ECGroup *ecgroup)
michael@0 936 {
michael@0 937 mp_err res = MP_OKAY;
michael@0 938 mp_int rx, ry, n;
michael@0 939 int size;
michael@0 940
michael@0 941 MP_DIGITS(&rx) = 0;
michael@0 942 MP_DIGITS(&ry) = 0;
michael@0 943 MP_DIGITS(&n) = 0;
michael@0 944
michael@0 945 MP_CHECKOK(mp_init(&rx));
michael@0 946 MP_CHECKOK(mp_init(&ry));
michael@0 947 MP_CHECKOK(mp_init(&n));
michael@0 948
michael@0 949 /* compute random scalar */
michael@0 950 size = mpl_significant_bits(&ecgroup->meth->irr);
michael@0 951 if (size < MP_OKAY) {
michael@0 952 res = MP_NO;
michael@0 953 goto CLEANUP;
michael@0 954 }
michael@0 955
michael@0 956 MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS));
michael@0 957 MP_CHECKOK(ecgroup->meth->field_mod(&n, &n, ecgroup->meth));
michael@0 958
michael@0 959 M_TimeOperation(ec_GFp_pt_mul_jac_fp
michael@0 960 (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
michael@0 961 ecgroup), 1000);
michael@0 962
michael@0 963 M_TimeOperation(ec_GFp_point_mul_jac_4w_fp
michael@0 964 (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
michael@0 965 ecgroup), 1000);
michael@0 966
michael@0 967 M_TimeOperation(ec_GFp_point_mul_wNAF_fp
michael@0 968 (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
michael@0 969 ecgroup), 1000);
michael@0 970
michael@0 971 M_TimeOperation(ec_GFp_pt_mul_jac
michael@0 972 (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
michael@0 973 ecgroup), 100);
michael@0 974
michael@0 975 CLEANUP:
michael@0 976 if (res == MP_OKAY)
michael@0 977 printf(" Test Passed - Point Multiplication Timing\n");
michael@0 978 else
michael@0 979 printf("TEST FAILED - Point Multiplication Timing\n");
michael@0 980 mp_clear(&rx);
michael@0 981 mp_clear(&ry);
michael@0 982 mp_clear(&n);
michael@0 983
michael@0 984 return res;
michael@0 985 }
michael@0 986
michael@0 987 /* Tests pre computation of Chudnovsky Jacobian points used in wNAF form */
michael@0 988 mp_err
michael@0 989 testPreCompute(ECGroup *ecgroup)
michael@0 990 {
michael@0 991 ecfp_chud_pt precomp[16];
michael@0 992 ecfp_aff_pt p;
michael@0 993 EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
michael@0 994 int i;
michael@0 995 mp_err res;
michael@0 996
michael@0 997 mp_int x, y, ny, x2, y2;
michael@0 998
michael@0 999 MP_DIGITS(&x) = 0;
michael@0 1000 MP_DIGITS(&y) = 0;
michael@0 1001 MP_DIGITS(&ny) = 0;
michael@0 1002 MP_DIGITS(&x2) = 0;
michael@0 1003 MP_DIGITS(&y2) = 0;
michael@0 1004
michael@0 1005 MP_CHECKOK(mp_init(&x));
michael@0 1006 MP_CHECKOK(mp_init(&y));
michael@0 1007 MP_CHECKOK(mp_init(&ny));
michael@0 1008 MP_CHECKOK(mp_init(&x2));
michael@0 1009 MP_CHECKOK(mp_init(&y2));
michael@0 1010
michael@0 1011 ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
michael@0 1012 ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
michael@0 1013 ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
michael@0 1014
michael@0 1015 /* Perform precomputation */
michael@0 1016 group->precompute_chud(precomp, &p, group);
michael@0 1017
michael@0 1018 M_TimeOperation(group->precompute_chud(precomp, &p, group), 10000);
michael@0 1019
michael@0 1020 /* Calculate addition to compare against */
michael@0 1021 MP_CHECKOK(mp_copy(&ecgroup->genx, &x));
michael@0 1022 MP_CHECKOK(mp_copy(&ecgroup->geny, &y));
michael@0 1023 MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));
michael@0 1024
michael@0 1025 ec_GFp_pt_dbl_aff(&x, &y, &x2, &y2, ecgroup);
michael@0 1026
michael@0 1027 for (i = 0; i < 8; i++) {
michael@0 1028 MP_CHECKOK(testChudPoint(&precomp[8 + i], &x, &y, ecgroup));
michael@0 1029 MP_CHECKOK(testChudPoint(&precomp[7 - i], &x, &ny, ecgroup));
michael@0 1030 ec_GFp_pt_add_aff(&x, &y, &x2, &y2, &x, &y, ecgroup);
michael@0 1031 MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));
michael@0 1032 }
michael@0 1033
michael@0 1034 CLEANUP:
michael@0 1035 if (res == MP_OKAY)
michael@0 1036 printf(" Test Passed - Precomputation\n");
michael@0 1037 else
michael@0 1038 printf("TEST FAILED - Precomputation\n");
michael@0 1039
michael@0 1040 mp_clear(&x);
michael@0 1041 mp_clear(&y);
michael@0 1042 mp_clear(&ny);
michael@0 1043 mp_clear(&x2);
michael@0 1044 mp_clear(&y2);
michael@0 1045 return res;
michael@0 1046 }
michael@0 1047
michael@0 1048 /* Given a curve using floating point arithmetic, test it. This method
michael@0 1049 * specifies which of the above tests to run. */
michael@0 1050 mp_err
michael@0 1051 testCurve(ECGroup *ecgroup)
michael@0 1052 {
michael@0 1053 int res = MP_OKAY;
michael@0 1054
michael@0 1055 MP_CHECKOK(testPointAddJacAff(ecgroup));
michael@0 1056 MP_CHECKOK(testPointAddJac(ecgroup));
michael@0 1057 MP_CHECKOK(testPointAddChud(ecgroup));
michael@0 1058 MP_CHECKOK(testPointAddJmChud(ecgroup));
michael@0 1059 MP_CHECKOK(testPointDoubleJac(ecgroup));
michael@0 1060 MP_CHECKOK(testPointDoubleChud(ecgroup));
michael@0 1061 MP_CHECKOK(testPointDoubleJm(ecgroup));
michael@0 1062 MP_CHECKOK(testPreCompute(ecgroup));
michael@0 1063 MP_CHECKOK(testPointMul(ecgroup));
michael@0 1064 MP_CHECKOK(testPointMulRandom(ecgroup));
michael@0 1065 MP_CHECKOK(testPointMulTime(ecgroup));
michael@0 1066 CLEANUP:
michael@0 1067 return res;
michael@0 1068 }
michael@0 1069
michael@0 1070 /* Tests a number of curves optimized using floating point arithmetic */
michael@0 1071 int
michael@0 1072 main(void)
michael@0 1073 {
michael@0 1074 mp_err res = MP_OKAY;
michael@0 1075 ECGroup *ecgroup = NULL;
michael@0 1076
michael@0 1077 /* specific arithmetic tests */
michael@0 1078 M_TestCurve("SECG-160R1", ECCurve_SECG_PRIME_160R1);
michael@0 1079 M_TestCurve("SECG-192R1", ECCurve_SECG_PRIME_192R1);
michael@0 1080 M_TestCurve("SEGC-224R1", ECCurve_SECG_PRIME_224R1);
michael@0 1081
michael@0 1082 CLEANUP:
michael@0 1083 ECGroup_free(ecgroup);
michael@0 1084 if (res != MP_OKAY) {
michael@0 1085 printf("Error: exiting with error value %i\n", res);
michael@0 1086 }
michael@0 1087 return res;
michael@0 1088 }

mercurial