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 Verifier context implementation. 20 */ 21 #include "epid/verifier/src/context.h" 22 #include <string.h> 23 #include "epid/common/math/pairing.h" 24 #include "epid/common/src/endian_convert.h" 25 #include "epid/common/src/epid2params.h" 26 #include "epid/common/src/memory.h" 27 #include "epid/common/src/sigrlvalid.h" 28 #include "epid/verifier/api.h" 29 30 /// Handle SDK Error with Break 31 #define BREAK_ON_EPID_ERROR(ret) \ 32 if (kEpidNoErr != (ret)) { \ 33 break; \ 34 } 35 /// create Verifier precomp of the VerifierCtx 36 static EpidStatus DoPrecomputation(VerifierCtx* ctx); 37 38 /// Read Verifier precomp 39 static EpidStatus ReadPrecomputation(VerifierPrecomp const* precomp_str, 40 VerifierCtx* ctx); 41 42 /// Internal function to prove if group based revocation list is valid 43 static bool IsGroupRlValid(GroupRl const* group_rl, size_t grp_rl_size) { 44 const size_t kMinGroupRlSize = sizeof(GroupRl) - sizeof(GroupId); 45 size_t input_grp_rl_size = 0; 46 47 if (!group_rl || grp_rl_size < kMinGroupRlSize) { 48 return false; 49 } 50 if (ntohl(group_rl->n3) > (SIZE_MAX - kMinGroupRlSize) / sizeof(GroupId)) { 51 return false; 52 } 53 input_grp_rl_size = kMinGroupRlSize + (ntohl(group_rl->n3) * sizeof(GroupId)); 54 if (input_grp_rl_size != grp_rl_size) { 55 return false; 56 } 57 return true; 58 } 59 60 /// Internal function to verify if private key based revocation list is valid 61 static bool IsPrivRlValid(GroupId const* gid, PrivRl const* priv_rl, 62 size_t priv_rl_size) { 63 const size_t kMinPrivRlSize = sizeof(PrivRl) - sizeof(FpElemStr); 64 size_t input_priv_rl_size = 0; 65 66 if (!gid || !priv_rl || kMinPrivRlSize > priv_rl_size) { 67 return false; 68 } 69 if (ntohl(priv_rl->n1) > 70 (SIZE_MAX - kMinPrivRlSize) / sizeof(priv_rl->f[0])) { 71 return false; 72 } 73 // sanity check of input PrivRl size 74 input_priv_rl_size = 75 kMinPrivRlSize + ntohl(priv_rl->n1) * sizeof(priv_rl->f[0]); 76 if (input_priv_rl_size != priv_rl_size) { 77 return false; 78 } 79 // verify that gid given and gid in PrivRl match 80 if (0 != memcmp(gid, &priv_rl->gid, sizeof(*gid))) { 81 return false; 82 } 83 return true; 84 } 85 86 /// Internal function to verify if verifier revocation list is valid 87 static bool IsVerifierRlValid(GroupId const* gid, VerifierRl const* ver_rl, 88 size_t ver_rl_size) { 89 const size_t kMinVerifierRlSize = sizeof(VerifierRl) - sizeof(G1ElemStr); 90 size_t expected_verifier_rl_size = 0; 91 92 if (!gid || !ver_rl || kMinVerifierRlSize > ver_rl_size) { 93 return false; 94 } 95 if (ntohl(ver_rl->n4) > 96 (SIZE_MAX - kMinVerifierRlSize) / sizeof(ver_rl->K[0])) { 97 return false; 98 } 99 // sanity check of input VerifierRl size 100 expected_verifier_rl_size = 101 kMinVerifierRlSize + ntohl(ver_rl->n4) * sizeof(ver_rl->K[0]); 102 if (expected_verifier_rl_size != ver_rl_size) { 103 return false; 104 } 105 106 // verify that gid in public key and gid in SigRl match 107 if (0 != memcmp(gid, &ver_rl->gid, sizeof(*gid))) { 108 return false; 109 } 110 111 return true; 112 } 113 114 EpidStatus EpidVerifierCreate(GroupPubKey const* pubkey, 115 VerifierPrecomp const* precomp, 116 VerifierCtx** ctx) { 117 EpidStatus result = kEpidErr; 118 VerifierCtx* verifier_ctx = NULL; 119 if (!pubkey || !ctx) { 120 return kEpidBadArgErr; 121 } 122 do { 123 // Allocate memory for VerifierCtx 124 verifier_ctx = SAFE_ALLOC(sizeof(VerifierCtx)); 125 if (!verifier_ctx) { 126 result = kEpidMemAllocErr; 127 break; 128 } 129 130 // set the default hash algorithm 131 verifier_ctx->hash_alg = kSha512; 132 #ifdef TPM_TSS // if build for TSS, make Sha256 default 133 verifier_ctx->hash_alg = kSha256; 134 #endif 135 136 // Internal representation of Epid2Params 137 result = CreateEpid2Params(&verifier_ctx->epid2_params); 138 if (kEpidNoErr != result) { 139 break; 140 } 141 // Internal representation of Group Pub Key 142 result = CreateGroupPubKey(pubkey, verifier_ctx->epid2_params->G1, 143 verifier_ctx->epid2_params->G2, 144 &verifier_ctx->pub_key); 145 if (kEpidNoErr != result) { 146 break; 147 } 148 // Store group public key strings for later use 149 result = SetKeySpecificCommitValues(pubkey, &verifier_ctx->commit_values); 150 if (kEpidNoErr != result) { 151 break; 152 } 153 // Allocate verifier_ctx->e12 154 result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e12); 155 if (kEpidNoErr != result) { 156 break; 157 } 158 // Allocate verifier_ctx->e22 159 result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e22); 160 if (kEpidNoErr != result) { 161 break; 162 } 163 // Allocate verifier_ctx->e2w 164 result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->e2w); 165 if (kEpidNoErr != result) { 166 break; 167 } 168 // Allocate verifier_ctx->eg12 169 result = NewFfElement(verifier_ctx->epid2_params->GT, &verifier_ctx->eg12); 170 if (kEpidNoErr != result) { 171 break; 172 } 173 // precomputation 174 if (precomp != NULL) { 175 result = ReadPrecomputation(precomp, verifier_ctx); 176 } else { 177 result = DoPrecomputation(verifier_ctx); 178 } 179 if (kEpidNoErr != result) { 180 break; 181 } 182 verifier_ctx->sig_rl = NULL; 183 verifier_ctx->group_rl = NULL; 184 verifier_ctx->priv_rl = NULL; 185 verifier_ctx->verifier_rl = NULL; 186 verifier_ctx->was_verifier_rl_updated = false; 187 verifier_ctx->basename_hash = NULL; 188 verifier_ctx->basename = NULL; 189 verifier_ctx->basename_len = 0; 190 *ctx = verifier_ctx; 191 result = kEpidNoErr; 192 } while (0); 193 194 if (kEpidNoErr != result && verifier_ctx) { 195 DeleteFfElement(&verifier_ctx->eg12); 196 DeleteFfElement(&verifier_ctx->e2w); 197 DeleteFfElement(&verifier_ctx->e22); 198 DeleteFfElement(&verifier_ctx->e12); 199 DeleteEpid2Params(&verifier_ctx->epid2_params); 200 DeleteGroupPubKey(&verifier_ctx->pub_key); 201 SAFE_FREE(verifier_ctx); 202 } 203 return result; 204 } 205 206 void EpidVerifierDelete(VerifierCtx** ctx) { 207 if (ctx && *ctx) { 208 DeleteFfElement(&(*ctx)->eg12); 209 DeleteFfElement(&(*ctx)->e2w); 210 DeleteFfElement(&(*ctx)->e22); 211 DeleteFfElement(&(*ctx)->e12); 212 DeleteGroupPubKey(&(*ctx)->pub_key); 213 DeleteEpid2Params(&(*ctx)->epid2_params); 214 (*ctx)->priv_rl = NULL; 215 (*ctx)->sig_rl = NULL; 216 (*ctx)->group_rl = NULL; 217 SAFE_FREE((*ctx)->verifier_rl); 218 DeleteEcPoint(&(*ctx)->basename_hash); 219 SAFE_FREE((*ctx)->basename); 220 (*ctx)->basename_len = 0; 221 SAFE_FREE(*ctx); 222 } 223 } 224 225 EpidStatus EpidVerifierWritePrecomp(VerifierCtx const* ctx, 226 VerifierPrecomp* precomp) { 227 EpidStatus result = kEpidErr; 228 FfElement* e12 = NULL; // an element in GT 229 FfElement* e22 = NULL; // an element in GT 230 FfElement* e2w = NULL; // an element in GT 231 FfElement* eg12 = NULL; // an element in GT 232 FiniteField* GT = NULL; // Finite field GT(Fq12 ) 233 if (!ctx) { 234 return kEpidBadArgErr; 235 } 236 if (!precomp) { 237 return kEpidBadArgErr; 238 } 239 if (!ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->eg12 || !ctx->epid2_params || 240 !ctx->epid2_params->GT || !ctx->pub_key) { 241 return kEpidBadArgErr; 242 } 243 e12 = ctx->e12; 244 e22 = ctx->e22; 245 e2w = ctx->e2w; 246 eg12 = ctx->eg12; 247 GT = ctx->epid2_params->GT; 248 precomp->gid = ctx->pub_key->gid; 249 result = WriteFfElement(GT, e12, &(precomp->e12), sizeof(precomp->e12)); 250 if (kEpidNoErr != result) { 251 return result; 252 } 253 result = WriteFfElement(GT, e22, &(precomp->e22), sizeof(precomp->e22)); 254 if (kEpidNoErr != result) { 255 return result; 256 } 257 result = WriteFfElement(GT, e2w, &(precomp->e2w), sizeof(precomp->e2w)); 258 if (kEpidNoErr != result) { 259 return result; 260 } 261 result = WriteFfElement(GT, eg12, &(precomp->eg12), sizeof(precomp->eg12)); 262 if (kEpidNoErr != result) { 263 return result; 264 } 265 return result; 266 } 267 268 EpidStatus EpidVerifierSetPrivRl(VerifierCtx* ctx, PrivRl const* priv_rl, 269 size_t priv_rl_size) { 270 if (!ctx || !priv_rl || !ctx->pub_key) { 271 return kEpidBadArgErr; 272 } 273 if (!IsPrivRlValid(&ctx->pub_key->gid, priv_rl, priv_rl_size)) { 274 return kEpidBadArgErr; 275 } 276 // Do not set an older version of priv rl 277 if (ctx->priv_rl) { 278 unsigned int current_ver = 0; 279 unsigned int incoming_ver = 0; 280 current_ver = ntohl(ctx->priv_rl->version); 281 incoming_ver = ntohl(priv_rl->version); 282 if (current_ver >= incoming_ver) { 283 return kEpidBadArgErr; 284 } 285 } 286 ctx->priv_rl = priv_rl; 287 return kEpidNoErr; 288 } 289 290 EpidStatus EpidVerifierSetSigRl(VerifierCtx* ctx, SigRl const* sig_rl, 291 size_t sig_rl_size) { 292 if (!ctx || !sig_rl || !ctx->pub_key) { 293 return kEpidBadArgErr; 294 } 295 if (!IsSigRlValid(&ctx->pub_key->gid, sig_rl, sig_rl_size)) { 296 return kEpidBadArgErr; 297 } 298 // Do not set an older version of sig rl 299 if (ctx->sig_rl) { 300 unsigned int current_ver = 0; 301 unsigned int incoming_ver = 0; 302 current_ver = ntohl(ctx->sig_rl->version); 303 incoming_ver = ntohl(sig_rl->version); 304 if (current_ver >= incoming_ver) { 305 return kEpidBadArgErr; 306 } 307 } 308 ctx->sig_rl = sig_rl; 309 310 return kEpidNoErr; 311 } 312 313 EpidStatus EpidVerifierSetGroupRl(VerifierCtx* ctx, GroupRl const* grp_rl, 314 size_t grp_rl_size) { 315 if (!ctx || !grp_rl || !ctx->pub_key) { 316 return kEpidBadArgErr; 317 } 318 if (!IsGroupRlValid(grp_rl, grp_rl_size)) { 319 return kEpidBadArgErr; 320 } 321 // Do not set an older version of group rl 322 if (ctx->group_rl) { 323 unsigned int current_ver = 0; 324 unsigned int incoming_ver = 0; 325 current_ver = ntohl(ctx->group_rl->version); 326 incoming_ver = ntohl(grp_rl->version); 327 if (current_ver >= incoming_ver) { 328 return kEpidBadArgErr; 329 } 330 } 331 ctx->group_rl = grp_rl; 332 333 return kEpidNoErr; 334 } 335 336 EpidStatus EpidVerifierSetVerifierRl(VerifierCtx* ctx, VerifierRl const* ver_rl, 337 size_t ver_rl_size) { 338 VerifierRl* verifier_rl = NULL; 339 EpidStatus res = kEpidErr; 340 EcPoint* B = NULL; 341 bool cmp_result = false; 342 EcGroup* G1 = NULL; 343 if (!ctx || !ver_rl || !ctx->pub_key || !ctx->epid2_params || 344 !ctx->epid2_params->G1) { 345 return kEpidBadArgErr; 346 } 347 if (!IsVerifierRlValid(&ctx->pub_key->gid, ver_rl, ver_rl_size)) { 348 return kEpidBadArgErr; 349 } 350 // if random basename 351 if (!ctx->basename_hash) { 352 return kEpidInconsistentBasenameSetErr; 353 } 354 // Do not set an older version of verifier rl 355 if (ctx->verifier_rl) { 356 unsigned int current_ver = 0; 357 unsigned int incoming_ver = 0; 358 current_ver = ntohl(ctx->verifier_rl->version); 359 incoming_ver = ntohl(ver_rl->version); 360 if (current_ver >= incoming_ver) { 361 return kEpidBadArgErr; 362 } 363 } 364 do { 365 G1 = ctx->epid2_params->G1; 366 res = NewEcPoint(G1, &B); 367 BREAK_ON_EPID_ERROR(res); 368 res = ReadEcPoint(G1, &(ver_rl->B), sizeof(ver_rl->B), B); 369 BREAK_ON_EPID_ERROR(res); 370 // verify B = G1.hash(bsn) 371 res = EcIsEqual(G1, ctx->basename_hash, B, &cmp_result); 372 BREAK_ON_EPID_ERROR(res); 373 if (true != cmp_result) { 374 res = kEpidBadArgErr; 375 break; 376 } 377 verifier_rl = SAFE_ALLOC(ver_rl_size); 378 if (!verifier_rl) { 379 res = kEpidMemAllocErr; 380 break; 381 } 382 if (0 != memcpy_S(verifier_rl, ver_rl_size, ver_rl, ver_rl_size)) { 383 res = kEpidBadArgErr; 384 break; 385 } 386 res = kEpidNoErr; 387 } while (0); 388 DeleteEcPoint(&B); 389 SAFE_FREE(ctx->verifier_rl); 390 if (kEpidNoErr == res) { 391 ctx->verifier_rl = verifier_rl; 392 ctx->was_verifier_rl_updated = false; 393 } 394 return res; 395 } 396 397 size_t EpidGetVerifierRlSize(VerifierCtx const* ctx) { 398 size_t empty_size = 0; 399 if (!ctx || !ctx->basename_hash) return 0; 400 empty_size = sizeof(VerifierRl) - sizeof(((VerifierRl*)0)->K[0]); 401 if (!ctx->verifier_rl) return empty_size; 402 return empty_size + 403 ntohl(ctx->verifier_rl->n4) * sizeof(ctx->verifier_rl->K[0]); 404 } 405 406 EpidStatus EpidWriteVerifierRl(VerifierCtx const* ctx, VerifierRl* ver_rl, 407 size_t ver_rl_size) { 408 EpidStatus res = kEpidErr; 409 size_t real_ver_rl_size = 0; 410 if (!ctx || !ver_rl || !ctx->pub_key || !ctx->epid2_params || 411 !ctx->epid2_params->G1) { 412 return kEpidBadArgErr; 413 } 414 real_ver_rl_size = EpidGetVerifierRlSize(ctx); 415 if (real_ver_rl_size == 0) { 416 return kEpidErr; 417 } 418 if (real_ver_rl_size != ver_rl_size) { 419 return kEpidBadArgErr; 420 } 421 if (ctx->verifier_rl) { 422 // serialize 423 if (0 != 424 memcpy_S(ver_rl, ver_rl_size, ctx->verifier_rl, real_ver_rl_size)) { 425 return kEpidBadArgErr; 426 } 427 // update rl version if it has changed 428 if (ctx->was_verifier_rl_updated) { 429 uint32_t prior_rl_version = ntohl(ver_rl->version); 430 *((uint32_t*)(&ver_rl->version)) = htonl(prior_rl_version + 1); 431 ((VerifierCtx*)ctx)->was_verifier_rl_updated = false; 432 } 433 } else { 434 // write empty rl 435 res = WriteEcPoint(ctx->epid2_params->G1, ctx->basename_hash, &(ver_rl->B), 436 sizeof(ver_rl->B)); 437 if (kEpidNoErr != res) { 438 return res; 439 } 440 ver_rl->gid = ctx->pub_key->gid; 441 memset(&ver_rl->version, 0, sizeof(ver_rl->version)); 442 memset(&ver_rl->n4, 0, sizeof(ver_rl->n4)); 443 } 444 return kEpidNoErr; 445 } 446 447 EpidStatus EpidBlacklistSig(VerifierCtx* ctx, EpidSignature const* sig, 448 size_t sig_len, void const* msg, size_t msg_len) { 449 EpidStatus result = kEpidErr; 450 VerifierRl* ver_rl = NULL; 451 if (!ctx || !sig || (!msg && msg_len > 0) || !ctx->epid2_params || 452 !ctx->epid2_params->G1) { 453 return kEpidBadArgErr; 454 } 455 if (sig_len < sizeof(EpidSignature) - sizeof(((EpidSignature*)0)->sigma[0])) { 456 return kEpidBadArgErr; 457 } 458 if (!ctx->basename_hash) { 459 return kEpidInconsistentBasenameSetErr; 460 } 461 462 do { 463 EcGroup* G1 = ctx->epid2_params->G1; 464 uint32_t n4 = 0; 465 result = EpidVerify(ctx, sig, sig_len, msg, msg_len); 466 BREAK_ON_EPID_ERROR(result); 467 468 if (!ctx->verifier_rl) { 469 ver_rl = SAFE_ALLOC(sizeof(VerifierRl)); 470 if (!ver_rl) { 471 result = kEpidMemAllocErr; 472 break; 473 } 474 // write empty rl 475 ver_rl->gid = ctx->pub_key->gid; 476 result = 477 WriteEcPoint(G1, ctx->basename_hash, &(ver_rl->B), sizeof(ver_rl->B)); 478 BREAK_ON_EPID_ERROR(result); 479 } else { 480 uint32_t prior_rl_version = ntohl(ctx->verifier_rl->version); 481 n4 = ntohl(ctx->verifier_rl->n4); 482 483 if (prior_rl_version == UINT32_MAX || n4 == UINT32_MAX) { 484 result = kEpidBadArgErr; 485 break; 486 } 487 ver_rl = SAFE_REALLOC( 488 ctx->verifier_rl, 489 EpidGetVerifierRlSize(ctx) + sizeof(((VerifierRl*)0)->K[0])); 490 if (!ver_rl) { 491 result = kEpidMemAllocErr; 492 break; 493 } 494 } 495 496 ctx->was_verifier_rl_updated = true; 497 ++n4; 498 ver_rl->K[n4 - 1] = sig->sigma0.K; 499 500 *((uint32_t*)(&ver_rl->n4)) = htonl(n4); 501 ctx->verifier_rl = ver_rl; 502 result = kEpidNoErr; 503 } while (0); 504 if (kEpidNoErr != result) SAFE_FREE(ver_rl); 505 return result; 506 } 507 508 EpidStatus EpidVerifierSetHashAlg(VerifierCtx* ctx, HashAlg hash_alg) { 509 EpidStatus result = kEpidErr; 510 if (!ctx) { 511 return kEpidBadArgErr; 512 } 513 if (kSha256 != hash_alg && kSha384 != hash_alg && kSha512 != hash_alg && 514 kSha512_256 != hash_alg) 515 return kEpidBadArgErr; 516 517 if (ctx->hash_alg != hash_alg) { 518 HashAlg previous_hash_alg = ctx->hash_alg; 519 ctx->hash_alg = hash_alg; 520 521 result = EpidVerifierSetBasename(ctx, ctx->basename, ctx->basename_len); 522 if (kEpidNoErr != result) { 523 ctx->hash_alg = previous_hash_alg; 524 return result; 525 } 526 } 527 result = kEpidNoErr; 528 return result; 529 } 530 531 EpidStatus EpidVerifierSetBasename(VerifierCtx* ctx, void const* basename, 532 size_t basename_len) { 533 EpidStatus result = kEpidErr; 534 EcPoint* basename_hash = NULL; 535 uint8_t* basename_buffer = NULL; 536 537 if (!ctx || !ctx->epid2_params || !ctx->epid2_params->G1) { 538 return kEpidBadArgErr; 539 } 540 if (!basename && basename_len > 0) { 541 return kEpidBadArgErr; 542 } 543 544 if (!basename) { 545 DeleteEcPoint(&ctx->basename_hash); 546 ctx->basename_hash = NULL; 547 ctx->was_verifier_rl_updated = false; 548 SAFE_FREE(ctx->basename); 549 ctx->basename_len = 0; 550 return kEpidNoErr; 551 } 552 553 do { 554 size_t i = 0; 555 EcGroup* G1 = ctx->epid2_params->G1; 556 result = NewEcPoint(G1, &basename_hash); 557 if (kEpidNoErr != result) { 558 break; 559 } 560 561 result = 562 EcHash(G1, basename, basename_len, ctx->hash_alg, basename_hash, NULL); 563 if (kEpidNoErr != result) { 564 break; 565 } 566 567 if (basename_len > 0) { 568 basename_buffer = SAFE_ALLOC(basename_len); 569 if (!basename_buffer) { 570 result = kEpidMemAllocErr; 571 break; 572 } 573 } 574 575 SAFE_FREE(ctx->verifier_rl); 576 577 DeleteEcPoint(&ctx->basename_hash); 578 ctx->basename_hash = basename_hash; 579 SAFE_FREE(ctx->basename); 580 ctx->basename = basename_buffer; 581 ctx->basename_len = basename_len; 582 for (i = 0; i < basename_len; i++) { 583 ctx->basename[i] = ((uint8_t*)basename)[i]; 584 } 585 result = kEpidNoErr; 586 } while (0); 587 588 if (kEpidNoErr != result) { 589 DeleteEcPoint(&basename_hash); 590 SAFE_FREE(basename_buffer); 591 } 592 return result; 593 } 594 595 static EpidStatus DoPrecomputation(VerifierCtx* ctx) { 596 EpidStatus result = kEpidErr; 597 FfElement* e12 = NULL; 598 FfElement* e22 = NULL; 599 FfElement* e2w = NULL; 600 FfElement* eg12 = NULL; 601 Epid2Params_* params = NULL; 602 GroupPubKey_* pub_key = NULL; 603 PairingState* ps_ctx = NULL; 604 if (!ctx) { 605 return kEpidBadArgErr; 606 } 607 if (!ctx->epid2_params || !ctx->epid2_params->GT || 608 !ctx->epid2_params->pairing_state || !ctx->pub_key || !ctx->e12 || 609 !ctx->e22 || !ctx->e2w || !ctx->eg12) { 610 return kEpidBadArgErr; 611 } 612 pub_key = ctx->pub_key; 613 params = ctx->epid2_params; 614 e12 = ctx->e12; 615 e22 = ctx->e22; 616 e2w = ctx->e2w; 617 eg12 = ctx->eg12; 618 ps_ctx = params->pairing_state; 619 // do precomputation 620 // 1. The verifier computes e12 = pairing(h1, g2). 621 result = Pairing(ps_ctx, pub_key->h1, params->g2, e12); 622 if (kEpidNoErr != result) { 623 return result; 624 } 625 // 2. The verifier computes e22 = pairing(h2, g2). 626 result = Pairing(ps_ctx, pub_key->h2, params->g2, e22); 627 if (kEpidNoErr != result) { 628 return result; 629 } 630 // 3. The verifier computes e2w = pairing(h2, w). 631 result = Pairing(ps_ctx, pub_key->h2, pub_key->w, e2w); 632 if (kEpidNoErr != result) { 633 return result; 634 } 635 // 4. The verifier computes eg12 = pairing(g1, g2). 636 result = Pairing(ps_ctx, params->g1, params->g2, eg12); 637 if (kEpidNoErr != result) { 638 return result; 639 } 640 return kEpidNoErr; 641 } 642 static EpidStatus ReadPrecomputation(VerifierPrecomp const* precomp_str, 643 VerifierCtx* ctx) { 644 EpidStatus result = kEpidErr; 645 FfElement* e12 = NULL; 646 FfElement* e22 = NULL; 647 FfElement* e2w = NULL; 648 FfElement* eg12 = NULL; 649 FiniteField* GT = NULL; 650 Epid2Params_* params = NULL; 651 if (!ctx) { 652 return kEpidBadArgErr; 653 } 654 if (!ctx->epid2_params || !ctx->epid2_params->GT || !ctx->e12 || !ctx->e22 || 655 !ctx->e2w || !ctx->eg12 || !ctx->pub_key) { 656 return kEpidBadArgErr; 657 } 658 if (0 != 659 memcmp(&precomp_str->gid, &ctx->pub_key->gid, sizeof(precomp_str->gid))) { 660 return kEpidBadArgErr; 661 } 662 params = ctx->epid2_params; 663 GT = params->GT; 664 e12 = ctx->e12; 665 e22 = ctx->e22; 666 e2w = ctx->e2w; 667 eg12 = ctx->eg12; 668 669 result = ReadFfElement(GT, &precomp_str->e12, sizeof(precomp_str->e12), e12); 670 if (kEpidNoErr != result) { 671 return result; 672 } 673 result = ReadFfElement(GT, &precomp_str->e22, sizeof(precomp_str->e22), e22); 674 if (kEpidNoErr != result) { 675 return result; 676 } 677 result = ReadFfElement(GT, &precomp_str->e2w, sizeof(precomp_str->e2w), e2w); 678 if (kEpidNoErr != result) { 679 return result; 680 } 681 result = 682 ReadFfElement(GT, &precomp_str->eg12, sizeof(precomp_str->eg12), eg12); 683 if (kEpidNoErr != result) { 684 return result; 685 } 686 return kEpidNoErr; 687 } 688