Wed, 31 Dec 2014 06:09:35 +0100
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 | } |