Home | History | Annotate | Download | only in src
      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