EpidStatus Tpm2CreatePrimary(Tpm2Ctx* ctx, G1ElemStr* p_str) { EpidStatus sts = kEpidErr; FfElement* ff_elem; FpElemStr ff_elem_str; if (!ctx || !ctx->epid2_params) { return kEpidBadArgErr; } (void)p_str; do { const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; FiniteField* Fp = ctx->epid2_params->Fp; sts = NewFfElement(Fp, &ff_elem); BREAK_ON_EPID_ERROR(sts); sts = FfGetRandom(Fp, &kOne, ctx->rnd_func, ctx->rnd_param, ff_elem); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(Fp, ff_elem, &ff_elem_str, sizeof(ff_elem_str)); BREAK_ON_EPID_ERROR(sts); } while (0); DeleteFfElement(&ff_elem); if (kEpidNoErr == sts) { sts = Tpm2LoadExternal(ctx, &ff_elem_str); } return sts; }
EpidStatus EpidComputePreSig(MemberCtx const* ctx, PreComputedSignature* precompsig) { EpidStatus res = kEpidNotImpl; EcPoint* B = NULL; EcPoint* K = NULL; EcPoint* T = NULL; EcPoint* R1 = NULL; FfElement* R2 = NULL; FfElement* a = NULL; FfElement* b = NULL; FfElement* rx = NULL; FfElement* rf = NULL; FfElement* ra = NULL; FfElement* rb = NULL; FfElement* t1 = NULL; FfElement* t2 = NULL; FfElement* f = NULL; if (!ctx || !precompsig) return kEpidBadArgErr; if (!ctx->epid2_params || !ctx->pub_key || !ctx->priv_key) return kEpidBadArgErr; do { // handy shorthands: EcGroup* G1 = ctx->epid2_params->G1; FiniteField* GT = ctx->epid2_params->GT; FiniteField* Fp = ctx->epid2_params->Fp; EcPoint* h2 = ctx->pub_key->h2; EcPoint* A = ctx->priv_key->A; FfElement* x = ctx->priv_key->x; BigNumStr f_str = {0}; BigNumStr a_str = {0}; BigNumStr t1_str = {0}; BigNumStr rf_str = {0}; BigNumStr t2_str = {0}; BigNumStr ra_str = {0}; static const BigNumStr one = { {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}; if (!G1 || !GT || !Fp || !h2 || !A || !x || !ctx->priv_key->f || !ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->ea2) { res = kEpidBadArgErr; BREAK_ON_EPID_ERROR(res); } f = ctx->priv_key->f; // The following variables B, K, T, R1 (elements of G1), R2 // (elements of GT), a, b, rx, rf, ra, rb, t1, t2 (256-bit // integers) are used. res = NewEcPoint(G1, &B); BREAK_ON_EPID_ERROR(res); res = NewEcPoint(G1, &K); BREAK_ON_EPID_ERROR(res); res = NewEcPoint(G1, &T); BREAK_ON_EPID_ERROR(res); res = NewEcPoint(G1, &R1); BREAK_ON_EPID_ERROR(res); res = NewFfElement(GT, &R2); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &a); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &b); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &rx); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &rf); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &ra); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &rb); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &t1); BREAK_ON_EPID_ERROR(res); res = NewFfElement(Fp, &t2); BREAK_ON_EPID_ERROR(res); // 1. The member expects the pre-computation is done (e12, e22, e2w, // ea2). Refer to Section 3.5 for the computation of these // values. // 2. The member verifies gid in public key matches gid in private // key. // 3. The member computes B = G1.getRandom(). res = EcGetRandom(G1, ctx->rnd_func, ctx->rnd_param, B); BREAK_ON_EPID_ERROR(res); // 4. The member computes K = G1.sscmExp(B, f). res = WriteFfElement(Fp, f, &f_str, sizeof(f_str)); BREAK_ON_EPID_ERROR(res); res = EcExp(G1, B, &f_str, K); BREAK_ON_EPID_ERROR(res); // 5. The member chooses randomly an integers a from [1, p-1]. res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, a); BREAK_ON_EPID_ERROR(res); // 6. The member computes T = G1.sscmExp(h2, a). res = WriteFfElement(Fp, a, &a_str, sizeof(a_str)); BREAK_ON_EPID_ERROR(res); res = EcExp(G1, h2, &a_str, T); BREAK_ON_EPID_ERROR(res); // 7. The member computes T = G1.mul(T, A). res = EcMul(G1, T, A, T); BREAK_ON_EPID_ERROR(res); // 8. The member computes b = (a * x) mod p. res = FfMul(Fp, a, x, b); BREAK_ON_EPID_ERROR(res); // 9. The member chooses rx, rf, ra, rb randomly from [1, p-1]. res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rx); BREAK_ON_EPID_ERROR(res); res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rf); BREAK_ON_EPID_ERROR(res); res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, ra); BREAK_ON_EPID_ERROR(res); res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rb); BREAK_ON_EPID_ERROR(res); // 10. The member computes t1 = (- rx) mod p. res = FfNeg(Fp, rx, t1); BREAK_ON_EPID_ERROR(res); // 11. The member computes t2 = (rb - a * rx) mod p. res = FfMul(Fp, a, rx, t2); BREAK_ON_EPID_ERROR(res); res = FfNeg(Fp, t2, t2); BREAK_ON_EPID_ERROR(res); res = FfAdd(Fp, rb, t2, t2); BREAK_ON_EPID_ERROR(res); // 12. The member computes R1 = G1.sscmExp(B, rf). res = WriteFfElement(Fp, rf, &rf_str, sizeof(rf_str)); BREAK_ON_EPID_ERROR(res); res = EcExp(G1, B, &rf_str, R1); BREAK_ON_EPID_ERROR(res); // 13. The member computes R2 = GT.sscmMultiExp(ea2, t1, e12, rf, // e22, t2, e2w, ra). res = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, ra, &ra_str, sizeof(ra_str)); BREAK_ON_EPID_ERROR(res); { FfElement const* points[4]; BigNumStr const* exponents[4]; points[0] = ctx->ea2; points[1] = ctx->e12; points[2] = ctx->e22; points[3] = ctx->e2w; exponents[0] = &t1_str; exponents[1] = &rf_str; exponents[2] = &t2_str; exponents[3] = &ra_str; res = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2); BREAK_ON_EPID_ERROR(res); } // 14. The member sets and outputs pre-sigma = (B, K, T, a, b, rx, // rf, ra, rb, R1, R2). res = WriteEcPoint(G1, B, &precompsig->B, sizeof(precompsig->B)); BREAK_ON_EPID_ERROR(res); res = WriteEcPoint(G1, K, &precompsig->K, sizeof(precompsig->K)); BREAK_ON_EPID_ERROR(res); res = WriteEcPoint(G1, T, &precompsig->T, sizeof(precompsig->T)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, a, &precompsig->a, sizeof(precompsig->a)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, b, &precompsig->b, sizeof(precompsig->b)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, rx, &precompsig->rx, sizeof(precompsig->rx)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, rf, &precompsig->rf, sizeof(precompsig->rf)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, ra, &precompsig->ra, sizeof(precompsig->ra)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(Fp, rb, &precompsig->rb, sizeof(precompsig->rb)); BREAK_ON_EPID_ERROR(res); res = WriteEcPoint(G1, R1, &precompsig->R1, sizeof(precompsig->R1)); BREAK_ON_EPID_ERROR(res); res = WriteFfElement(GT, R2, &precompsig->R2, sizeof(precompsig->R2)); BREAK_ON_EPID_ERROR(res); // 15. The member stores pre-sigma in the secure storage of the // member. res = kEpidNoErr; } while (0); f = NULL; DeleteEcPoint(&B); DeleteEcPoint(&K); DeleteEcPoint(&T); DeleteEcPoint(&R1); DeleteFfElement(&R2); DeleteFfElement(&a); DeleteFfElement(&b); DeleteFfElement(&rx); DeleteFfElement(&rf); DeleteFfElement(&ra); DeleteFfElement(&rb); DeleteFfElement(&t1); DeleteFfElement(&t2); return (res); }
EpidStatus EpidRequestJoin(GroupPubKey const* pub_key, IssuerNonce const* ni, FpElemStr const* f, BitSupplier rnd_func, void* rnd_param, HashAlg hash_alg, JoinRequest* join_request) { EpidStatus sts; static const BigNumStr one = { {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}; BigNumStr r_str; JoinPCommitValues commit_values; Epid2Params_* params = NULL; FfElement* r_el = NULL; FfElement* f_el = NULL; FfElement* c_el = NULL; FfElement* cf_el = NULL; FfElement* s_el = NULL; EcPoint* f_pt = NULL; EcPoint* r_pt = NULL; EcPoint* h1_pt = NULL; if (!pub_key || !ni || !f || !rnd_func || !join_request) { return kEpidBadArgErr; } if (kSha256 != hash_alg && kSha384 != hash_alg && kSha512 != hash_alg) { return kEpidBadArgErr; } do { sts = CreateEpid2Params(¶ms); BREAK_ON_EPID_ERROR(sts); if (!params->Fp || !params->G1) { sts = kEpidBadArgErr; break; } sts = NewFfElement(params->Fp, &r_el); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(params->Fp, &f_el); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(params->Fp, &c_el); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(params->Fp, &cf_el); BREAK_ON_EPID_ERROR(sts); sts = NewFfElement(params->Fp, &s_el); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(params->G1, &f_pt); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(params->G1, &h1_pt); BREAK_ON_EPID_ERROR(sts); sts = NewEcPoint(params->G1, &r_pt); BREAK_ON_EPID_ERROR(sts); sts = ReadFfElement(params->Fp, (uint8_t const*)f, sizeof(*f), f_el); BREAK_ON_EPID_ERROR(sts); sts = ReadEcPoint(params->G1, (uint8_t*)&pub_key->h1, sizeof(pub_key->h1), h1_pt); BREAK_ON_EPID_ERROR(sts); // Step 1. The member chooses a random integer r from [1, p-1]. sts = FfGetRandom(params->Fp, &one, rnd_func, rnd_param, r_el); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(params->Fp, r_el, (uint8_t*)&r_str, sizeof(r_str)); // Step 2. The member computes F = G1.sscmExp(h1, f). sts = EcExp(params->G1, h1_pt, (BigNumStr const*)f, f_pt); BREAK_ON_EPID_ERROR(sts); // Step 3. The member computes R = G1.sscmExp(h1, r). sts = EcExp(params->G1, h1_pt, (BigNumStr const*)&r_str, r_pt); BREAK_ON_EPID_ERROR(sts); // Step 4. The member computes c = Fp.hash(p || g1 || g2 || h1 || h2 || w || // F || R || NI). Refer to Section 7.1 for hash operation over a prime // field. sts = WriteBigNum(params->p, sizeof(commit_values.p), (uint8_t*)&commit_values.p); BREAK_ON_EPID_ERROR(sts); sts = WriteEcPoint(params->G1, params->g1, (uint8_t*)&commit_values.g1, sizeof(commit_values.g1)); BREAK_ON_EPID_ERROR(sts); sts = WriteEcPoint(params->G2, params->g2, (uint8_t*)&commit_values.g2, sizeof(commit_values.g2)); BREAK_ON_EPID_ERROR(sts); commit_values.h1 = pub_key->h1; commit_values.h2 = pub_key->h2; commit_values.w = pub_key->w; sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&commit_values.F, sizeof(commit_values.F)); BREAK_ON_EPID_ERROR(sts); sts = WriteEcPoint(params->G1, r_pt, (uint8_t*)&commit_values.R, sizeof(commit_values.R)); BREAK_ON_EPID_ERROR(sts); commit_values.NI = *ni; sts = FfHash(params->Fp, (uint8_t*)&commit_values, sizeof(commit_values), hash_alg, c_el); BREAK_ON_EPID_ERROR(sts); // Step 5. The member computes s = (r + c * f) mod p. sts = FfMul(params->Fp, c_el, f_el, cf_el); BREAK_ON_EPID_ERROR(sts); sts = FfAdd(params->Fp, r_el, cf_el, s_el); BREAK_ON_EPID_ERROR(sts); // Step 6. The output join request is (F, c, s). sts = WriteFfElement(params->Fp, c_el, (uint8_t*)&join_request->c, sizeof(join_request->c)); BREAK_ON_EPID_ERROR(sts); sts = WriteFfElement(params->Fp, s_el, (uint8_t*)&join_request->s, sizeof(join_request->s)); BREAK_ON_EPID_ERROR(sts); sts = WriteEcPoint(params->G1, f_pt, (uint8_t*)&join_request->F, sizeof(join_request->F)); BREAK_ON_EPID_ERROR(sts); sts = kEpidNoErr; } while (0); DeleteEcPoint(&h1_pt); DeleteEcPoint(&r_pt); DeleteEcPoint(&f_pt); DeleteFfElement(&s_el); DeleteFfElement(&cf_el); DeleteFfElement(&c_el); DeleteFfElement(&f_el); DeleteFfElement(&r_el); DeleteEpid2Params(¶ms); return sts; }