Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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 "mpi.h" |
michael@0 | 6 | #include "mplogic.h" |
michael@0 | 7 | #include "mpprime.h" |
michael@0 | 8 | #include "mp_gf2m.h" |
michael@0 | 9 | #include "ecl.h" |
michael@0 | 10 | #include "ecl-curve.h" |
michael@0 | 11 | #include "ec2.h" |
michael@0 | 12 | #include <stdio.h> |
michael@0 | 13 | #include <strings.h> |
michael@0 | 14 | #include <assert.h> |
michael@0 | 15 | |
michael@0 | 16 | #include <time.h> |
michael@0 | 17 | #include <sys/time.h> |
michael@0 | 18 | #include <sys/resource.h> |
michael@0 | 19 | |
michael@0 | 20 | /* Time k repetitions of operation op. */ |
michael@0 | 21 | #define M_TimeOperation(op, k) { \ |
michael@0 | 22 | double dStart, dNow, dUserTime; \ |
michael@0 | 23 | struct rusage ru; \ |
michael@0 | 24 | int i; \ |
michael@0 | 25 | getrusage(RUSAGE_SELF, &ru); \ |
michael@0 | 26 | dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \ |
michael@0 | 27 | for (i = 0; i < k; i++) { \ |
michael@0 | 28 | { op; } \ |
michael@0 | 29 | }; \ |
michael@0 | 30 | getrusage(RUSAGE_SELF, &ru); \ |
michael@0 | 31 | dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \ |
michael@0 | 32 | dUserTime = dNow-dStart; \ |
michael@0 | 33 | if (dUserTime) printf(" %-45s k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ |
michael@0 | 34 | } |
michael@0 | 35 | |
michael@0 | 36 | /* Test curve using generic field arithmetic. */ |
michael@0 | 37 | #define ECTEST_GENERIC_GF2M(name_c, name) \ |
michael@0 | 38 | printf("Testing %s using generic implementation...\n", name_c); \ |
michael@0 | 39 | params = EC_GetNamedCurveParams(name); \ |
michael@0 | 40 | if (params == NULL) { \ |
michael@0 | 41 | printf(" Error: could not construct params.\n"); \ |
michael@0 | 42 | res = MP_NO; \ |
michael@0 | 43 | goto CLEANUP; \ |
michael@0 | 44 | } \ |
michael@0 | 45 | ECGroup_free(group); \ |
michael@0 | 46 | group = ECGroup_fromHex(params); \ |
michael@0 | 47 | if (group == NULL) { \ |
michael@0 | 48 | printf(" Error: could not construct group.\n"); \ |
michael@0 | 49 | res = MP_NO; \ |
michael@0 | 50 | goto CLEANUP; \ |
michael@0 | 51 | } \ |
michael@0 | 52 | MP_CHECKOK( ectest_curve_GF2m(group, ectestPrint, ectestTime, 1) ); \ |
michael@0 | 53 | printf("... okay.\n"); |
michael@0 | 54 | |
michael@0 | 55 | /* Test curve using specific field arithmetic. */ |
michael@0 | 56 | #define ECTEST_NAMED_GF2M(name_c, name) \ |
michael@0 | 57 | printf("Testing %s using specific implementation...\n", name_c); \ |
michael@0 | 58 | ECGroup_free(group); \ |
michael@0 | 59 | group = ECGroup_fromName(name); \ |
michael@0 | 60 | if (group == NULL) { \ |
michael@0 | 61 | printf(" Warning: could not construct group.\n"); \ |
michael@0 | 62 | printf("... failed; continuing with remaining tests.\n"); \ |
michael@0 | 63 | } else { \ |
michael@0 | 64 | MP_CHECKOK( ectest_curve_GF2m(group, ectestPrint, ectestTime, 0) ); \ |
michael@0 | 65 | printf("... okay.\n"); \ |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | /* Performs basic tests of elliptic curve cryptography over binary |
michael@0 | 69 | * polynomial fields. If tests fail, then it prints an error message, |
michael@0 | 70 | * aborts, and returns an error code. Otherwise, returns 0. */ |
michael@0 | 71 | int |
michael@0 | 72 | ectest_curve_GF2m(ECGroup *group, int ectestPrint, int ectestTime, |
michael@0 | 73 | int generic) |
michael@0 | 74 | { |
michael@0 | 75 | |
michael@0 | 76 | mp_int one, order_1, gx, gy, rx, ry, n; |
michael@0 | 77 | int size; |
michael@0 | 78 | mp_err res; |
michael@0 | 79 | char s[1000]; |
michael@0 | 80 | |
michael@0 | 81 | /* initialize values */ |
michael@0 | 82 | MP_CHECKOK(mp_init(&one)); |
michael@0 | 83 | MP_CHECKOK(mp_init(&order_1)); |
michael@0 | 84 | MP_CHECKOK(mp_init(&gx)); |
michael@0 | 85 | MP_CHECKOK(mp_init(&gy)); |
michael@0 | 86 | MP_CHECKOK(mp_init(&rx)); |
michael@0 | 87 | MP_CHECKOK(mp_init(&ry)); |
michael@0 | 88 | MP_CHECKOK(mp_init(&n)); |
michael@0 | 89 | |
michael@0 | 90 | MP_CHECKOK(mp_set_int(&one, 1)); |
michael@0 | 91 | MP_CHECKOK(mp_sub(&group->order, &one, &order_1)); |
michael@0 | 92 | |
michael@0 | 93 | /* encode base point */ |
michael@0 | 94 | if (group->meth->field_dec) { |
michael@0 | 95 | MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth)); |
michael@0 | 96 | MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth)); |
michael@0 | 97 | } else { |
michael@0 | 98 | MP_CHECKOK(mp_copy(&group->genx, &gx)); |
michael@0 | 99 | MP_CHECKOK(mp_copy(&group->geny, &gy)); |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | if (ectestPrint) { |
michael@0 | 103 | /* output base point */ |
michael@0 | 104 | printf(" base point P:\n"); |
michael@0 | 105 | MP_CHECKOK(mp_toradix(&gx, s, 16)); |
michael@0 | 106 | printf(" %s\n", s); |
michael@0 | 107 | MP_CHECKOK(mp_toradix(&gy, s, 16)); |
michael@0 | 108 | printf(" %s\n", s); |
michael@0 | 109 | if (group->meth->field_enc) { |
michael@0 | 110 | printf(" base point P (encoded):\n"); |
michael@0 | 111 | MP_CHECKOK(mp_toradix(&group->genx, s, 16)); |
michael@0 | 112 | printf(" %s\n", s); |
michael@0 | 113 | MP_CHECKOK(mp_toradix(&group->geny, s, 16)); |
michael@0 | 114 | printf(" %s\n", s); |
michael@0 | 115 | } |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | #ifdef ECL_ENABLE_GF2M_PT_MUL_AFF |
michael@0 | 119 | /* multiply base point by order - 1 and check for negative of base |
michael@0 | 120 | * point */ |
michael@0 | 121 | MP_CHECKOK(ec_GF2m_pt_mul_aff |
michael@0 | 122 | (&order_1, &group->genx, &group->geny, &rx, &ry, group)); |
michael@0 | 123 | if (ectestPrint) { |
michael@0 | 124 | printf(" (order-1)*P (affine):\n"); |
michael@0 | 125 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 126 | printf(" %s\n", s); |
michael@0 | 127 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 128 | printf(" %s\n", s); |
michael@0 | 129 | } |
michael@0 | 130 | MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 131 | if ((mp_cmp(&rx, &group->genx) != 0) |
michael@0 | 132 | || (mp_cmp(&ry, &group->geny) != 0)) { |
michael@0 | 133 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 134 | res = MP_NO; |
michael@0 | 135 | goto CLEANUP; |
michael@0 | 136 | } |
michael@0 | 137 | #endif |
michael@0 | 138 | |
michael@0 | 139 | /* multiply base point by order - 1 and check for negative of base |
michael@0 | 140 | * point */ |
michael@0 | 141 | MP_CHECKOK(ec_GF2m_pt_mul_mont |
michael@0 | 142 | (&order_1, &group->genx, &group->geny, &rx, &ry, group)); |
michael@0 | 143 | if (ectestPrint) { |
michael@0 | 144 | printf(" (order-1)*P (montgomery):\n"); |
michael@0 | 145 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 146 | printf(" %s\n", s); |
michael@0 | 147 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 148 | printf(" %s\n", s); |
michael@0 | 149 | } |
michael@0 | 150 | MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 151 | if ((mp_cmp(&rx, &group->genx) != 0) |
michael@0 | 152 | || (mp_cmp(&ry, &group->geny) != 0)) { |
michael@0 | 153 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 154 | res = MP_NO; |
michael@0 | 155 | goto CLEANUP; |
michael@0 | 156 | } |
michael@0 | 157 | |
michael@0 | 158 | #ifdef ECL_ENABLE_GF2M_PROJ |
michael@0 | 159 | /* multiply base point by order - 1 and check for negative of base |
michael@0 | 160 | * point */ |
michael@0 | 161 | MP_CHECKOK(ec_GF2m_pt_mul_proj |
michael@0 | 162 | (&order_1, &group->genx, &group->geny, &rx, &ry, group)); |
michael@0 | 163 | if (ectestPrint) { |
michael@0 | 164 | printf(" (order-1)*P (projective):\n"); |
michael@0 | 165 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 166 | printf(" %s\n", s); |
michael@0 | 167 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 168 | printf(" %s\n", s); |
michael@0 | 169 | } |
michael@0 | 170 | MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 171 | if ((mp_cmp(&rx, &group->genx) != 0) |
michael@0 | 172 | || (mp_cmp(&ry, &group->geny) != 0)) { |
michael@0 | 173 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 174 | res = MP_NO; |
michael@0 | 175 | goto CLEANUP; |
michael@0 | 176 | } |
michael@0 | 177 | #endif |
michael@0 | 178 | |
michael@0 | 179 | /* multiply base point by order - 1 and check for negative of base |
michael@0 | 180 | * point */ |
michael@0 | 181 | MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry)); |
michael@0 | 182 | if (ectestPrint) { |
michael@0 | 183 | printf(" (order-1)*P (ECPoint_mul):\n"); |
michael@0 | 184 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 185 | printf(" %s\n", s); |
michael@0 | 186 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 187 | printf(" %s\n", s); |
michael@0 | 188 | } |
michael@0 | 189 | MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 190 | if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { |
michael@0 | 191 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 192 | res = MP_NO; |
michael@0 | 193 | goto CLEANUP; |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | /* multiply base point by order - 1 and check for negative of base |
michael@0 | 197 | * point */ |
michael@0 | 198 | MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry)); |
michael@0 | 199 | if (ectestPrint) { |
michael@0 | 200 | printf(" (order-1)*P (ECPoint_mul):\n"); |
michael@0 | 201 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 202 | printf(" %s\n", s); |
michael@0 | 203 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 204 | printf(" %s\n", s); |
michael@0 | 205 | } |
michael@0 | 206 | MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 207 | if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { |
michael@0 | 208 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 209 | res = MP_NO; |
michael@0 | 210 | goto CLEANUP; |
michael@0 | 211 | } |
michael@0 | 212 | |
michael@0 | 213 | #ifdef ECL_ENABLE_GF2M_PT_MUL_AFF |
michael@0 | 214 | /* multiply base point by order and check for point at infinity */ |
michael@0 | 215 | MP_CHECKOK(ec_GF2m_pt_mul_aff |
michael@0 | 216 | (&group->order, &group->genx, &group->geny, &rx, &ry, |
michael@0 | 217 | group)); |
michael@0 | 218 | if (ectestPrint) { |
michael@0 | 219 | printf(" (order)*P (affine):\n"); |
michael@0 | 220 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 221 | printf(" %s\n", s); |
michael@0 | 222 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 223 | printf(" %s\n", s); |
michael@0 | 224 | } |
michael@0 | 225 | if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) { |
michael@0 | 226 | printf(" Error: invalid result (expected point at infinity).\n"); |
michael@0 | 227 | res = MP_NO; |
michael@0 | 228 | goto CLEANUP; |
michael@0 | 229 | } |
michael@0 | 230 | #endif |
michael@0 | 231 | |
michael@0 | 232 | /* multiply base point by order and check for point at infinity */ |
michael@0 | 233 | MP_CHECKOK(ec_GF2m_pt_mul_mont |
michael@0 | 234 | (&group->order, &group->genx, &group->geny, &rx, &ry, |
michael@0 | 235 | group)); |
michael@0 | 236 | if (ectestPrint) { |
michael@0 | 237 | printf(" (order)*P (montgomery):\n"); |
michael@0 | 238 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 239 | printf(" %s\n", s); |
michael@0 | 240 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 241 | printf(" %s\n", s); |
michael@0 | 242 | } |
michael@0 | 243 | if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) { |
michael@0 | 244 | printf(" Error: invalid result (expected point at infinity).\n"); |
michael@0 | 245 | res = MP_NO; |
michael@0 | 246 | goto CLEANUP; |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | #ifdef ECL_ENABLE_GF2M_PROJ |
michael@0 | 250 | /* multiply base point by order and check for point at infinity */ |
michael@0 | 251 | MP_CHECKOK(ec_GF2m_pt_mul_proj |
michael@0 | 252 | (&group->order, &group->genx, &group->geny, &rx, &ry, |
michael@0 | 253 | group)); |
michael@0 | 254 | if (ectestPrint) { |
michael@0 | 255 | printf(" (order)*P (projective):\n"); |
michael@0 | 256 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 257 | printf(" %s\n", s); |
michael@0 | 258 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 259 | printf(" %s\n", s); |
michael@0 | 260 | } |
michael@0 | 261 | if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) { |
michael@0 | 262 | printf(" Error: invalid result (expected point at infinity).\n"); |
michael@0 | 263 | res = MP_NO; |
michael@0 | 264 | goto CLEANUP; |
michael@0 | 265 | } |
michael@0 | 266 | #endif |
michael@0 | 267 | |
michael@0 | 268 | /* multiply base point by order and check for point at infinity */ |
michael@0 | 269 | MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry)); |
michael@0 | 270 | if (ectestPrint) { |
michael@0 | 271 | printf(" (order)*P (ECPoint_mul):\n"); |
michael@0 | 272 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 273 | printf(" %s\n", s); |
michael@0 | 274 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 275 | printf(" %s\n", s); |
michael@0 | 276 | } |
michael@0 | 277 | if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) { |
michael@0 | 278 | printf(" Error: invalid result (expected point at infinity).\n"); |
michael@0 | 279 | res = MP_NO; |
michael@0 | 280 | goto CLEANUP; |
michael@0 | 281 | } |
michael@0 | 282 | |
michael@0 | 283 | /* multiply base point by order and check for point at infinity */ |
michael@0 | 284 | MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry)); |
michael@0 | 285 | if (ectestPrint) { |
michael@0 | 286 | printf(" (order)*P (ECPoint_mul):\n"); |
michael@0 | 287 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 288 | printf(" %s\n", s); |
michael@0 | 289 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 290 | printf(" %s\n", s); |
michael@0 | 291 | } |
michael@0 | 292 | if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) { |
michael@0 | 293 | printf(" Error: invalid result (expected point at infinity).\n"); |
michael@0 | 294 | res = MP_NO; |
michael@0 | 295 | goto CLEANUP; |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | /* check that (order-1)P + (order-1)P + P == (order-1)P */ |
michael@0 | 299 | MP_CHECKOK(ECPoints_mul |
michael@0 | 300 | (group, &order_1, &order_1, &gx, &gy, &rx, &ry)); |
michael@0 | 301 | MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry)); |
michael@0 | 302 | if (ectestPrint) { |
michael@0 | 303 | printf |
michael@0 | 304 | (" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n"); |
michael@0 | 305 | MP_CHECKOK(mp_toradix(&rx, s, 16)); |
michael@0 | 306 | printf(" %s\n", s); |
michael@0 | 307 | MP_CHECKOK(mp_toradix(&ry, s, 16)); |
michael@0 | 308 | printf(" %s\n", s); |
michael@0 | 309 | } |
michael@0 | 310 | MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth)); |
michael@0 | 311 | if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { |
michael@0 | 312 | printf(" Error: invalid result (expected (- base point)).\n"); |
michael@0 | 313 | res = MP_NO; |
michael@0 | 314 | goto CLEANUP; |
michael@0 | 315 | } |
michael@0 | 316 | |
michael@0 | 317 | /* test validate_point function */ |
michael@0 | 318 | if (ECPoint_validate(group, &gx, &gy) != MP_YES) { |
michael@0 | 319 | printf(" Error: validate point on base point failed.\n"); |
michael@0 | 320 | res = MP_NO; |
michael@0 | 321 | goto CLEANUP; |
michael@0 | 322 | } |
michael@0 | 323 | MP_CHECKOK(mp_add_d(&gy, 1, &ry)); |
michael@0 | 324 | if (ECPoint_validate(group, &gx, &ry) != MP_NO) { |
michael@0 | 325 | printf(" Error: validate point on invalid point passed.\n"); |
michael@0 | 326 | res = MP_NO; |
michael@0 | 327 | goto CLEANUP; |
michael@0 | 328 | } |
michael@0 | 329 | |
michael@0 | 330 | if (ectestTime) { |
michael@0 | 331 | /* compute random scalar */ |
michael@0 | 332 | size = mpl_significant_bits(&group->meth->irr); |
michael@0 | 333 | if (size < MP_OKAY) { |
michael@0 | 334 | goto CLEANUP; |
michael@0 | 335 | } |
michael@0 | 336 | MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS)); |
michael@0 | 337 | MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth)); |
michael@0 | 338 | /* timed test */ |
michael@0 | 339 | if (generic) { |
michael@0 | 340 | #ifdef ECL_ENABLE_GF2M_PT_MUL_AFF |
michael@0 | 341 | M_TimeOperation(MP_CHECKOK |
michael@0 | 342 | (ec_GF2m_pt_mul_aff |
michael@0 | 343 | (&n, &group->genx, &group->geny, &rx, &ry, |
michael@0 | 344 | group)), 100); |
michael@0 | 345 | #endif |
michael@0 | 346 | M_TimeOperation(MP_CHECKOK |
michael@0 | 347 | (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), |
michael@0 | 348 | 100); |
michael@0 | 349 | M_TimeOperation(MP_CHECKOK |
michael@0 | 350 | (ECPoints_mul |
michael@0 | 351 | (group, &n, &n, &gx, &gy, &rx, &ry)), 100); |
michael@0 | 352 | } else { |
michael@0 | 353 | M_TimeOperation(MP_CHECKOK |
michael@0 | 354 | (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), |
michael@0 | 355 | 100); |
michael@0 | 356 | M_TimeOperation(MP_CHECKOK |
michael@0 | 357 | (ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)), |
michael@0 | 358 | 100); |
michael@0 | 359 | M_TimeOperation(MP_CHECKOK |
michael@0 | 360 | (ECPoints_mul |
michael@0 | 361 | (group, &n, &n, &gx, &gy, &rx, &ry)), 100); |
michael@0 | 362 | } |
michael@0 | 363 | } |
michael@0 | 364 | |
michael@0 | 365 | CLEANUP: |
michael@0 | 366 | mp_clear(&one); |
michael@0 | 367 | mp_clear(&order_1); |
michael@0 | 368 | mp_clear(&gx); |
michael@0 | 369 | mp_clear(&gy); |
michael@0 | 370 | mp_clear(&rx); |
michael@0 | 371 | mp_clear(&ry); |
michael@0 | 372 | mp_clear(&n); |
michael@0 | 373 | if (res != MP_OKAY) { |
michael@0 | 374 | printf(" Error: exiting with error value %i\n", res); |
michael@0 | 375 | } |
michael@0 | 376 | return res; |
michael@0 | 377 | } |
michael@0 | 378 | |
michael@0 | 379 | /* Prints help information. */ |
michael@0 | 380 | void |
michael@0 | 381 | printUsage() |
michael@0 | 382 | { |
michael@0 | 383 | printf("Usage: ecp_test [--print] [--time]\n"); |
michael@0 | 384 | printf |
michael@0 | 385 | (" --print Print out results of each point arithmetic test.\n"); |
michael@0 | 386 | printf |
michael@0 | 387 | (" --time Benchmark point operations and print results.\n"); |
michael@0 | 388 | } |
michael@0 | 389 | |
michael@0 | 390 | /* Performs tests of elliptic curve cryptography over binary polynomial |
michael@0 | 391 | * fields. If tests fail, then it prints an error message, aborts, and |
michael@0 | 392 | * returns an error code. Otherwise, returns 0. */ |
michael@0 | 393 | int |
michael@0 | 394 | main(int argv, char **argc) |
michael@0 | 395 | { |
michael@0 | 396 | |
michael@0 | 397 | int ectestTime = 0; |
michael@0 | 398 | int ectestPrint = 0; |
michael@0 | 399 | int i; |
michael@0 | 400 | ECGroup *group = NULL; |
michael@0 | 401 | ECCurveParams *params = NULL; |
michael@0 | 402 | mp_err res; |
michael@0 | 403 | |
michael@0 | 404 | /* read command-line arguments */ |
michael@0 | 405 | for (i = 1; i < argv; i++) { |
michael@0 | 406 | if ((strcasecmp(argc[i], "time") == 0) |
michael@0 | 407 | || (strcasecmp(argc[i], "-time") == 0) |
michael@0 | 408 | || (strcasecmp(argc[i], "--time") == 0)) { |
michael@0 | 409 | ectestTime = 1; |
michael@0 | 410 | } else if ((strcasecmp(argc[i], "print") == 0) |
michael@0 | 411 | || (strcasecmp(argc[i], "-print") == 0) |
michael@0 | 412 | || (strcasecmp(argc[i], "--print") == 0)) { |
michael@0 | 413 | ectestPrint = 1; |
michael@0 | 414 | } else { |
michael@0 | 415 | printUsage(); |
michael@0 | 416 | return 0; |
michael@0 | 417 | } |
michael@0 | 418 | } |
michael@0 | 419 | |
michael@0 | 420 | /* generic arithmetic tests */ |
michael@0 | 421 | ECTEST_GENERIC_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); |
michael@0 | 422 | |
michael@0 | 423 | /* specific arithmetic tests */ |
michael@0 | 424 | ECTEST_NAMED_GF2M("NIST-K163", ECCurve_NIST_K163); |
michael@0 | 425 | ECTEST_NAMED_GF2M("NIST-B163", ECCurve_NIST_B163); |
michael@0 | 426 | ECTEST_NAMED_GF2M("NIST-K233", ECCurve_NIST_K233); |
michael@0 | 427 | ECTEST_NAMED_GF2M("NIST-B233", ECCurve_NIST_B233); |
michael@0 | 428 | ECTEST_NAMED_GF2M("NIST-K283", ECCurve_NIST_K283); |
michael@0 | 429 | ECTEST_NAMED_GF2M("NIST-B283", ECCurve_NIST_B283); |
michael@0 | 430 | ECTEST_NAMED_GF2M("NIST-K409", ECCurve_NIST_K409); |
michael@0 | 431 | ECTEST_NAMED_GF2M("NIST-B409", ECCurve_NIST_B409); |
michael@0 | 432 | ECTEST_NAMED_GF2M("NIST-K571", ECCurve_NIST_K571); |
michael@0 | 433 | ECTEST_NAMED_GF2M("NIST-B571", ECCurve_NIST_B571); |
michael@0 | 434 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V1", ECCurve_X9_62_CHAR2_PNB163V1); |
michael@0 | 435 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V2", ECCurve_X9_62_CHAR2_PNB163V2); |
michael@0 | 436 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V3", ECCurve_X9_62_CHAR2_PNB163V3); |
michael@0 | 437 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB176V1", ECCurve_X9_62_CHAR2_PNB176V1); |
michael@0 | 438 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V1", ECCurve_X9_62_CHAR2_TNB191V1); |
michael@0 | 439 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V2", ECCurve_X9_62_CHAR2_TNB191V2); |
michael@0 | 440 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V3", ECCurve_X9_62_CHAR2_TNB191V3); |
michael@0 | 441 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB208W1", ECCurve_X9_62_CHAR2_PNB208W1); |
michael@0 | 442 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V1", ECCurve_X9_62_CHAR2_TNB239V1); |
michael@0 | 443 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V2", ECCurve_X9_62_CHAR2_TNB239V2); |
michael@0 | 444 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V3", ECCurve_X9_62_CHAR2_TNB239V3); |
michael@0 | 445 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB272W1", ECCurve_X9_62_CHAR2_PNB272W1); |
michael@0 | 446 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB304W1", ECCurve_X9_62_CHAR2_PNB304W1); |
michael@0 | 447 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB359V1", ECCurve_X9_62_CHAR2_TNB359V1); |
michael@0 | 448 | ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB368W1", ECCurve_X9_62_CHAR2_PNB368W1); |
michael@0 | 449 | ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB431R1", ECCurve_X9_62_CHAR2_TNB431R1); |
michael@0 | 450 | ECTEST_NAMED_GF2M("SECT-113R1", ECCurve_SECG_CHAR2_113R1); |
michael@0 | 451 | ECTEST_NAMED_GF2M("SECT-113R2", ECCurve_SECG_CHAR2_113R2); |
michael@0 | 452 | ECTEST_NAMED_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); |
michael@0 | 453 | ECTEST_NAMED_GF2M("SECT-131R2", ECCurve_SECG_CHAR2_131R2); |
michael@0 | 454 | ECTEST_NAMED_GF2M("SECT-163K1", ECCurve_SECG_CHAR2_163K1); |
michael@0 | 455 | ECTEST_NAMED_GF2M("SECT-163R1", ECCurve_SECG_CHAR2_163R1); |
michael@0 | 456 | ECTEST_NAMED_GF2M("SECT-163R2", ECCurve_SECG_CHAR2_163R2); |
michael@0 | 457 | ECTEST_NAMED_GF2M("SECT-193R1", ECCurve_SECG_CHAR2_193R1); |
michael@0 | 458 | ECTEST_NAMED_GF2M("SECT-193R2", ECCurve_SECG_CHAR2_193R2); |
michael@0 | 459 | ECTEST_NAMED_GF2M("SECT-233K1", ECCurve_SECG_CHAR2_233K1); |
michael@0 | 460 | ECTEST_NAMED_GF2M("SECT-233R1", ECCurve_SECG_CHAR2_233R1); |
michael@0 | 461 | ECTEST_NAMED_GF2M("SECT-239K1", ECCurve_SECG_CHAR2_239K1); |
michael@0 | 462 | ECTEST_NAMED_GF2M("SECT-283K1", ECCurve_SECG_CHAR2_283K1); |
michael@0 | 463 | ECTEST_NAMED_GF2M("SECT-283R1", ECCurve_SECG_CHAR2_283R1); |
michael@0 | 464 | ECTEST_NAMED_GF2M("SECT-409K1", ECCurve_SECG_CHAR2_409K1); |
michael@0 | 465 | ECTEST_NAMED_GF2M("SECT-409R1", ECCurve_SECG_CHAR2_409R1); |
michael@0 | 466 | ECTEST_NAMED_GF2M("SECT-571K1", ECCurve_SECG_CHAR2_571K1); |
michael@0 | 467 | ECTEST_NAMED_GF2M("SECT-571R1", ECCurve_SECG_CHAR2_571R1); |
michael@0 | 468 | ECTEST_NAMED_GF2M("WTLS-1 (113)", ECCurve_WTLS_1); |
michael@0 | 469 | ECTEST_NAMED_GF2M("WTLS-3 (163)", ECCurve_WTLS_3); |
michael@0 | 470 | ECTEST_NAMED_GF2M("WTLS-4 (113)", ECCurve_WTLS_4); |
michael@0 | 471 | ECTEST_NAMED_GF2M("WTLS-5 (163)", ECCurve_WTLS_5); |
michael@0 | 472 | ECTEST_NAMED_GF2M("WTLS-10 (233)", ECCurve_WTLS_10); |
michael@0 | 473 | ECTEST_NAMED_GF2M("WTLS-11 (233)", ECCurve_WTLS_11); |
michael@0 | 474 | |
michael@0 | 475 | CLEANUP: |
michael@0 | 476 | EC_FreeCurveParams(params); |
michael@0 | 477 | ECGroup_free(group); |
michael@0 | 478 | if (res != MP_OKAY) { |
michael@0 | 479 | printf("Error: exiting with error value %i\n", res); |
michael@0 | 480 | } |
michael@0 | 481 | return res; |
michael@0 | 482 | } |