1 /*############################################################################ 2 # Copyright 2016-2017 Intel Corporation 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 ############################################################################*/ 16 17 /*! 18 * \file 19 * \brief Intel(R) EPID 2.0 constant parameters implementation. 20 */ 21 #include "epid/common/src/epid2params.h" 22 #include "epid/common/src/memory.h" 23 24 /// create a new Finite Field Fp 25 static EpidStatus NewFp(Epid2Params const* param, FiniteField** Fp); 26 /// create a new Finite Field Fq 27 static EpidStatus NewFq(Epid2Params const* param, FiniteField** Fq); 28 /// create a new Finite Field Fq2 29 static EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq, 30 FiniteField** Fq2); 31 /// create a new Finite Field Fq6 32 EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi, 33 FiniteField** Fq6); 34 /// create a new Elliptic curve group G1 over Fq 35 static EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq, 36 EcGroup** G1); 37 /// create a new Elliptic curve group G2 over Fq2 38 static EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q, 39 FiniteField* Fq, FiniteField* Fq2, EcGroup** G2); 40 /// create a new Finite Field Fq12 41 static EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT); 42 /// create a new pairing state 43 44 /// Deallocate Finite Field Fp 45 static void DeleteFp(FiniteField** Fp); 46 47 /// Deallocate Finite Field Fq 48 static void DeleteFq(FiniteField** Fq); 49 /// Deallocate Finite Field Fq2 50 static void DeleteFq2(FiniteField** Fq2); 51 /// Deallocate Finite Field Fq6 52 static void DeleteFq6(FiniteField** Fq6); 53 /// Deallocate Elliptic curve group G1 over Fq 54 static void DeleteG1(EcGroup** G1); 55 /// Deallocate Elliptic curve group G2 over Fq2 56 static void DeleteG2(EcGroup** G2); 57 /// Deallocate Finite Field Fq12 58 static void DeleteGT(FiniteField** GT); 59 60 EpidStatus CreateEpid2Params(Epid2Params_** params) { 61 EpidStatus result = kEpidErr; 62 Epid2Params_* internal_param = NULL; 63 BigNumStr t_str = {0}; 64 Epid2Params params_str = { 65 #include "epid/common/src/epid2params_ate.inc" 66 }; 67 if (!params) { 68 return kEpidBadArgErr; 69 } 70 do { 71 internal_param = SAFE_ALLOC(sizeof(Epid2Params_)); 72 if (!internal_param) { 73 result = kEpidMemAllocErr; 74 break; 75 } 76 result = NewBigNum(sizeof(params_str.p), &internal_param->p); 77 if (kEpidNoErr != result) { 78 break; 79 } 80 result = ReadBigNum(¶ms_str.p, sizeof(params_str.p), internal_param->p); 81 if (kEpidNoErr != result) { 82 break; 83 } 84 result = NewBigNum(sizeof(params_str.q), &internal_param->q); 85 if (kEpidNoErr != result) { 86 break; 87 } 88 result = ReadBigNum(¶ms_str.q, sizeof(params_str.q), internal_param->q); 89 if (kEpidNoErr != result) { 90 break; 91 } 92 result = NewBigNum(sizeof(params_str.t), &internal_param->t); 93 if (kEpidNoErr != result) { 94 break; 95 } 96 result = ReadBigNum(¶ms_str.t, sizeof(params_str.t), internal_param->t); 97 if (kEpidNoErr != result) { 98 break; 99 } 100 internal_param->neg = (params_str.neg.data[0]) ? true : false; 101 102 result = NewFp(¶ms_str, &internal_param->Fp); 103 if (kEpidNoErr != result) { 104 break; 105 } 106 result = NewFq(¶ms_str, &internal_param->Fq); 107 if (kEpidNoErr != result) { 108 break; 109 } 110 result = NewFq2(¶ms_str, internal_param->Fq, &internal_param->Fq2); 111 if (kEpidNoErr != result) { 112 break; 113 } 114 result = NewFfElement(internal_param->Fq, &internal_param->b); 115 if (kEpidNoErr != result) { 116 break; 117 } 118 result = ReadFfElement(internal_param->Fq, ¶ms_str.b, 119 sizeof(params_str.b), internal_param->b); 120 if (kEpidNoErr != result) { 121 break; 122 } 123 result = NewFfElement(internal_param->Fq2, &internal_param->xi); 124 if (kEpidNoErr != result) { 125 break; 126 } 127 result = ReadFfElement(internal_param->Fq2, ¶ms_str.xi, 128 sizeof(params_str.xi), internal_param->xi); 129 if (kEpidNoErr != result) { 130 break; 131 } 132 result = NewFq6(¶ms_str, internal_param->Fq2, internal_param->xi, 133 &internal_param->Fq6); 134 if (kEpidNoErr != result) { 135 break; 136 } 137 result = NewGT(internal_param->Fq6, &internal_param->GT); 138 if (kEpidNoErr != result) { 139 break; 140 } 141 result = NewG1(¶ms_str, internal_param->Fq, &internal_param->G1); 142 if (kEpidNoErr != result) { 143 break; 144 } 145 result = NewEcPoint(internal_param->G1, &internal_param->g1); 146 if (kEpidNoErr != result) { 147 break; 148 } 149 result = ReadEcPoint(internal_param->G1, ¶ms_str.g1, 150 sizeof(params_str.g1), internal_param->g1); 151 if (kEpidNoErr != result) { 152 break; 153 } 154 result = 155 NewG2(¶ms_str, internal_param->p, internal_param->q, 156 internal_param->Fq, internal_param->Fq2, &internal_param->G2); 157 if (kEpidNoErr != result) { 158 break; 159 } 160 result = NewEcPoint(internal_param->G2, &internal_param->g2); 161 if (kEpidNoErr != result) { 162 break; 163 } 164 result = ReadEcPoint(internal_param->G2, ¶ms_str.g2, 165 sizeof(params_str.g2), internal_param->g2); 166 if (kEpidNoErr != result) { 167 break; 168 } 169 result = WriteBigNum(internal_param->t, sizeof(t_str), &t_str); 170 if (kEpidNoErr != result) { 171 break; 172 } 173 result = NewPairingState(internal_param->G1, internal_param->G2, 174 internal_param->GT, &t_str, internal_param->neg, 175 &internal_param->pairing_state); 176 if (kEpidNoErr != result) { 177 break; 178 } 179 *params = internal_param; 180 result = kEpidNoErr; 181 } while (0); 182 if (kEpidNoErr != result && internal_param) { 183 DeletePairingState(&internal_param->pairing_state); 184 185 DeleteEcPoint(&internal_param->g2); 186 DeleteEcPoint(&internal_param->g1); 187 188 DeleteBigNum(&internal_param->p); 189 DeleteBigNum(&internal_param->q); 190 DeleteFfElement(&internal_param->b); 191 DeleteBigNum(&internal_param->t); 192 193 DeleteFp(&internal_param->Fp); 194 DeleteFq(&internal_param->Fq); 195 DeleteFq2(&internal_param->Fq2); 196 DeleteFq6(&internal_param->Fq6); 197 DeleteGT(&internal_param->GT); 198 199 DeleteG1(&internal_param->G1); 200 DeleteG2(&internal_param->G2); 201 202 SAFE_FREE(internal_param); 203 } 204 return result; 205 } 206 207 void DeleteEpid2Params(Epid2Params_** epid_params) { 208 if (epid_params && *epid_params) { 209 DeletePairingState(&(*epid_params)->pairing_state); 210 211 DeleteBigNum(&(*epid_params)->p); 212 DeleteBigNum(&(*epid_params)->q); 213 DeleteFfElement(&(*epid_params)->b); 214 DeleteBigNum(&(*epid_params)->t); 215 DeleteFfElement(&(*epid_params)->xi); 216 DeleteEcPoint(&(*epid_params)->g1); 217 DeleteEcPoint(&(*epid_params)->g2); 218 219 DeleteFp(&(*epid_params)->Fp); 220 DeleteFq(&(*epid_params)->Fq); 221 DeleteFq2(&(*epid_params)->Fq2); 222 DeleteFq6(&(*epid_params)->Fq6); 223 DeleteGT(&(*epid_params)->GT); 224 225 DeleteG1(&(*epid_params)->G1); 226 DeleteG2(&(*epid_params)->G2); 227 228 SAFE_FREE(*epid_params); 229 } 230 } 231 232 static EpidStatus NewFp(Epid2Params const* param, FiniteField** Fp) { 233 EpidStatus result = kEpidErr; 234 if (!param || !Fp) { 235 return kEpidBadArgErr; 236 } 237 result = NewFiniteField(¶m->p, Fp); 238 if (kEpidNoErr != result) { 239 return result; 240 } 241 return kEpidNoErr; 242 } 243 244 static EpidStatus NewFq(Epid2Params const* param, FiniteField** Fq) { 245 EpidStatus result = kEpidErr; 246 if (!param || !Fq) { 247 return kEpidBadArgErr; 248 } 249 result = NewFiniteField(¶m->q, Fq); 250 if (kEpidNoErr != result) { 251 return result; 252 } 253 return kEpidNoErr; 254 } 255 EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq, 256 FiniteField** Fq2) { 257 EpidStatus result = kEpidErr; 258 FiniteField* Ff = NULL; 259 FfElement* beta = NULL; 260 FfElement* neg_beta = NULL; 261 if (!param || !Fq || !Fq2) { 262 return kEpidBadArgErr; 263 } 264 do { 265 result = NewFfElement(Fq, &beta); 266 if (kEpidNoErr != result) { 267 break; 268 } 269 result = NewFfElement(Fq, &neg_beta); 270 if (kEpidNoErr != result) { 271 break; 272 } 273 result = ReadFfElement(Fq, ¶m->beta, sizeof(param->beta), beta); 274 if (kEpidNoErr != result) { 275 break; 276 } 277 result = FfNeg(Fq, beta, neg_beta); 278 if (kEpidNoErr != result) { 279 break; 280 } 281 result = NewFiniteFieldViaBinomalExtension(Fq, neg_beta, 2, &Ff); 282 if (kEpidNoErr != result) { 283 break; 284 } 285 *Fq2 = Ff; 286 result = kEpidNoErr; 287 } while (0); 288 289 DeleteFfElement(&neg_beta); 290 DeleteFfElement(&beta); 291 292 return result; 293 } 294 EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi, 295 FiniteField** Fq6) { 296 EpidStatus result = kEpidErr; 297 FiniteField* Ff = NULL; 298 FfElement* neg_xi = NULL; 299 if (!param || !Fq2 || !Fq6) { 300 return kEpidBadArgErr; 301 } 302 do { 303 result = NewFfElement(Fq2, &neg_xi); 304 if (kEpidNoErr != result) { 305 break; 306 } 307 result = FfNeg(Fq2, xi, neg_xi); 308 if (kEpidNoErr != result) { 309 break; 310 } 311 result = NewFiniteFieldViaBinomalExtension(Fq2, neg_xi, 3, &Ff); 312 if (kEpidNoErr != result) { 313 break; 314 } 315 *Fq6 = Ff; 316 result = kEpidNoErr; 317 } while (0); 318 319 DeleteFfElement(&neg_xi); 320 321 return result; 322 } 323 EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq, EcGroup** G1) { 324 EpidStatus result = kEpidErr; 325 EcGroup* ec = NULL; 326 FfElement* fq_a = NULL; 327 FfElement* fq_b = NULL; 328 FfElement* g1_x = NULL; 329 FfElement* g1_y = NULL; 330 BigNum* order = NULL; 331 BigNum* cofactor = NULL; 332 // h = 1; 333 const BigNumStr h1 = { 334 {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}}; 337 338 if (!param || !Fq || !G1) { 339 return kEpidBadArgErr; 340 } 341 do { 342 // Create G1 343 // G1 is an elliptic curve group E(Fq).It can be initialized as follows : 344 // 1. Set G1 = E(Fq).init(p, q, n = p, h = 1, a = 0, b, g1.x, g1.y). 345 // a = 0 346 // NewFfelement is Identidy 347 result = NewFfElement(Fq, &fq_a); 348 if (kEpidNoErr != result) { 349 break; 350 } 351 // b 352 result = NewFfElement(Fq, &fq_b); 353 if (kEpidNoErr != result) { 354 break; 355 } 356 result = ReadFfElement(Fq, ¶m->b, sizeof(param->b), fq_b); 357 if (kEpidNoErr != result) { 358 break; 359 } 360 // g1.x 361 result = NewFfElement(Fq, &g1_x); 362 if (kEpidNoErr != result) { 363 break; 364 } 365 result = ReadFfElement(Fq, ¶m->g1.x, sizeof(param->g1.x), g1_x); 366 if (kEpidNoErr != result) { 367 break; 368 } 369 // g1.y 370 result = NewFfElement(Fq, &g1_y); 371 if (kEpidNoErr != result) { 372 break; 373 } 374 result = ReadFfElement(Fq, ¶m->g1.y, sizeof(param->g1.y), g1_y); 375 if (kEpidNoErr != result) { 376 break; 377 } 378 // order 379 result = NewBigNum(sizeof(BigNumStr), &order); 380 if (kEpidNoErr != result) { 381 break; 382 } 383 result = ReadBigNum(¶m->p, sizeof(param->p), order); 384 if (kEpidNoErr != result) { 385 break; 386 } 387 // cofactor 388 result = NewBigNum(sizeof(BigNumStr), &cofactor); 389 if (kEpidNoErr != result) { 390 break; 391 } 392 393 result = ReadBigNum(&h1, sizeof(h1), cofactor); 394 if (kEpidNoErr != result) { 395 break; 396 } 397 result = NewEcGroup(Fq, fq_a, fq_b, g1_x, g1_y, order, cofactor, &ec); 398 if (kEpidNoErr != result) { 399 break; 400 } 401 *G1 = ec; 402 result = kEpidNoErr; 403 } while (0); 404 405 DeleteBigNum(&cofactor); 406 DeleteBigNum(&order); 407 DeleteFfElement(&g1_y); 408 DeleteFfElement(&g1_x); 409 DeleteFfElement(&fq_b); 410 DeleteFfElement(&fq_a); 411 412 return result; 413 } 414 EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q, 415 FiniteField* Fq, FiniteField* Fq2, EcGroup** G2) { 416 EpidStatus result = kEpidErr; 417 EcGroup* ec = NULL; 418 FfElement* a = NULL; 419 FfElement* b = NULL; 420 FfElement* fq_param_b = NULL; 421 FfElement* x = NULL; 422 FfElement* y = NULL; 423 BigNum* order = NULL; 424 BigNum* cofactor = NULL; 425 if (!param || !Fq || !Fq2 || !G2) { 426 return kEpidBadArgErr; 427 } 428 do { 429 // 2. Set xi = (xi0, xi1) an element of Fq2. 430 // 3. Let b', xi' be a temporary variable in Fq2. 431 // 4. Compute xi' = Fq2.inverse(xi). 432 // 5. Compute b' = Fq2.mul(xi', b). 433 result = NewFfElement(Fq2, &b); 434 if (kEpidNoErr != result) { 435 break; 436 } 437 result = ReadFfElement(Fq2, ¶m->xi, sizeof(param->xi), b); 438 if (kEpidNoErr != result) { 439 break; 440 } 441 result = FfInv(Fq2, b, b); 442 if (kEpidNoErr != result) { 443 break; 444 } 445 result = NewFfElement(Fq, &fq_param_b); 446 if (kEpidNoErr != result) { 447 break; 448 } 449 result = ReadFfElement(Fq, ¶m->b, sizeof(param->b), fq_param_b); 450 if (kEpidNoErr != result) { 451 break; 452 } 453 result = FfMul(Fq2, b, fq_param_b, b); // ??? overflow fq2*fq 454 if (kEpidNoErr != result) { 455 break; 456 } 457 // 6. Set g2.x = (g2.x[0], g2.x[1]) an element of Fq2. 458 // 7. Set g2.y = (g2.y[0], g2.y[1]) an element of Fq2. 459 result = NewFfElement(Fq2, &x); 460 if (kEpidNoErr != result) { 461 break; 462 } 463 result = ReadFfElement(Fq2, ¶m->g2.x, sizeof(param->g2.x), x); 464 if (kEpidNoErr != result) { 465 break; 466 } 467 result = NewFfElement(Fq2, &y); 468 if (kEpidNoErr != result) { 469 break; 470 } 471 result = ReadFfElement(Fq2, ¶m->g2.y, sizeof(param->g2.y), y); 472 if (kEpidNoErr != result) { 473 break; 474 } 475 // 8. set h = 2q - p, aka cofactor 476 result = NewBigNum(2 * sizeof(param->q), &cofactor); 477 if (kEpidNoErr != result) { 478 break; 479 } 480 result = BigNumAdd(q, q, cofactor); 481 if (kEpidNoErr != result) { 482 break; 483 } 484 result = BigNumSub(cofactor, p, cofactor); 485 if (kEpidNoErr != result) { 486 break; 487 } 488 // 9. set n = p * h, AKA order 489 result = NewBigNum(2 * sizeof(param->q), &order); 490 if (kEpidNoErr != result) { 491 break; 492 } 493 result = BigNumMul(p, cofactor, order); 494 if (kEpidNoErr != result) { 495 break; 496 } 497 // set a to identity, NewFfElement does it by default 498 result = NewFfElement(Fq2, &a); 499 if (kEpidNoErr != result) { 500 break; 501 } 502 // 10. Set G2 = E(Fq2).init(p, param(Fq2), n, h, 0, b', g2.x, g2.y) 503 result = NewEcGroup(Fq2, a, b, x, y, order, cofactor, &ec); 504 if (kEpidNoErr != result) { 505 break; 506 } 507 *G2 = ec; 508 result = kEpidNoErr; 509 } while (0); 510 511 DeleteBigNum(&cofactor); 512 DeleteBigNum(&order); 513 DeleteFfElement(&y); 514 DeleteFfElement(&x); 515 DeleteFfElement(&b); 516 DeleteFfElement(&a); 517 DeleteFfElement(&fq_param_b); 518 519 return result; 520 } 521 EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT) { 522 EpidStatus result = kEpidErr; 523 FiniteField* Ff = NULL; 524 FfElement* v = NULL; 525 FfElement* neg_v = NULL; 526 527 const Fq6ElemStr v_str = { 528 {{{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, 531 {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}, 534 {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}}, 537 {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}, 540 {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}, 543 {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}}}; 546 547 if (!Fq6 || !GT) { 548 return kEpidBadArgErr; 549 } 550 do { 551 result = NewFfElement(Fq6, &v); 552 if (kEpidNoErr != result) { 553 break; 554 } 555 result = NewFfElement(Fq6, &neg_v); 556 if (kEpidNoErr != result) { 557 break; 558 } 559 result = ReadFfElement(Fq6, &v_str, sizeof(v_str), v); 560 if (kEpidNoErr != result) { 561 break; 562 } 563 result = FfNeg(Fq6, v, neg_v); 564 if (kEpidNoErr != result) { 565 break; 566 } 567 result = NewFiniteFieldViaBinomalExtension(Fq6, neg_v, 2, &Ff); 568 if (kEpidNoErr != result) { 569 break; 570 } 571 *GT = Ff; 572 result = kEpidNoErr; 573 } while (0); 574 575 DeleteFfElement(&v); 576 DeleteFfElement(&neg_v); 577 578 return result; 579 } 580 static void DeleteFp(FiniteField** Fp) { DeleteFiniteField(Fp); } 581 static void DeleteFq(FiniteField** Fq) { DeleteFiniteField(Fq); } 582 static void DeleteFq2(FiniteField** Fq2) { DeleteFiniteField(Fq2); } 583 static void DeleteFq6(FiniteField** Fq6) { DeleteFiniteField(Fq6); } 584 static void DeleteG1(EcGroup** G1) { DeleteEcGroup(G1); } 585 static void DeleteG2(EcGroup** G2) { DeleteEcGroup(G2); } 586 static void DeleteGT(FiniteField** GT) { DeleteFiniteField(GT); } 587