123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- /*############################################################################
- # Copyright 2016 Intel Corporation
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- ############################################################################*/
- /*!
- * \file
- * \brief EpidNrProve implementation.
- */
- #include "epid/common/src/memory.h"
- #include "epid/member/api.h"
- #include "epid/member/src/context.h"
- /// Handle SDK Error with Break
- #define BREAK_ON_EPID_ERROR(ret) \
- if (kEpidNoErr != (ret)) { \
- break; \
- }
- /// Count of elements in array
- #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
- #pragma pack(1)
- /// Storage for values to create commitment in NrProve algorithm
- typedef struct NrVerifyCommitValues {
- BigNumStr p; //!< A large prime (256-bit)
- G1ElemStr g1; //!< Generator of G1 (512-bit)
- G1ElemStr b; //!< (element of G1): part of basic signature Sigma0
- G1ElemStr k; //!< (element of G1): part of basic signature Sigma0
- G1ElemStr bp; //!< (element of G1): one entry in SigRL
- G1ElemStr kp; //!< (element of G1): one entry in SigRL
- G1ElemStr t; //!< element of G1
- G1ElemStr r1; //!< element of G1
- G1ElemStr r2; //!< element of G1
- uint8_t msg[1]; //!< message
- } NrVerifyCommitValues;
- #pragma pack()
- EpidStatus EpidNrProve(MemberCtx const* ctx, void const* msg, size_t msg_len,
- BasicSignature const* sig, SigRlEntry const* sigrl_entry,
- NrProof* proof) {
- EpidStatus res = kEpidErr;
- NrVerifyCommitValues* commit_values = NULL;
- size_t const commit_len = sizeof(*commit_values) - 1 + msg_len;
- EcPoint* T = NULL;
- EcPoint* R1 = NULL;
- EcPoint* R2 = NULL;
- FfElement* mu = NULL;
- FfElement* nu = NULL;
- FfElement* rmu = NULL;
- FfElement* rnu = NULL;
- FfElement* c = NULL;
- FfElement* smu = NULL;
- FfElement* snu = NULL;
- EcPoint* B = NULL;
- EcPoint* K = NULL;
- EcPoint* rlB = NULL;
- EcPoint* rlK = NULL;
- FfElement const* f = NULL;
- if (!ctx || (0 != msg_len && !msg) || !sig || !sigrl_entry || !proof)
- return kEpidBadArgErr;
- if (msg_len > ((SIZE_MAX - sizeof(*commit_values)) + 1))
- return kEpidBadArgErr;
- if (!ctx->epid2_params || !ctx->priv_key) return kEpidBadArgErr;
- do {
- bool is_identity = false;
- BigNumStr mu_str = {0};
- BigNumStr nu_str = {0};
- BigNumStr rmu_str = {0};
- BigNumStr rnu_str = {0};
- BitSupplier rnd_func = ctx->rnd_func;
- void* rnd_param = ctx->rnd_param;
- FiniteField* Fp = ctx->epid2_params->Fp;
- EcGroup* G1 = ctx->epid2_params->G1;
- static const BigNumStr one = {
- {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
- // Check required parameters
- if (!ctx->priv_key->f || !rnd_func || !Fp || !G1) return kEpidBadArgErr;
- f = ctx->priv_key->f;
- commit_values = SAFE_ALLOC(commit_len);
- if (!commit_values) {
- res = kEpidMemAllocErr;
- break;
- }
- // The following variables T, R1, R2 (elements of G1), and mu, nu,
- // rmu, rnu, c, smu, snu (256-bit integers) are used.
- res = NewEcPoint(G1, &T);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &R1);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &R2);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &mu);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &nu);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &rmu);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &rnu);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &c);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &smu);
- BREAK_ON_EPID_ERROR(res);
- res = NewFfElement(Fp, &snu);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &B);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &K);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &rlB);
- BREAK_ON_EPID_ERROR(res);
- res = NewEcPoint(G1, &rlK);
- BREAK_ON_EPID_ERROR(res);
- res = ReadEcPoint(G1, (const uint8_t*)&(sig->B), sizeof(sig->B), B);
- BREAK_ON_EPID_ERROR(res);
- res = ReadEcPoint(G1, (const uint8_t*)&(sig->K), sizeof(sig->K), K);
- BREAK_ON_EPID_ERROR(res);
- res = ReadEcPoint(G1, (const uint8_t*)&(sigrl_entry->b),
- sizeof(sigrl_entry->b), rlB);
- BREAK_ON_EPID_ERROR(res);
- res = ReadEcPoint(G1, (const uint8_t*)&(sigrl_entry->k),
- sizeof(sigrl_entry->k), rlK);
- BREAK_ON_EPID_ERROR(res);
- // 1. The member chooses random mu from [1, p-1].
- res = FfGetRandom(Fp, &one, rnd_func, rnd_param, mu);
- BREAK_ON_EPID_ERROR(res);
- // 2. The member computes nu = (- f * mu) mod p.
- res = FfMul(Fp, mu, f, nu);
- BREAK_ON_EPID_ERROR(res);
- res = FfNeg(Fp, nu, nu);
- BREAK_ON_EPID_ERROR(res);
- // 3. The member computes T = G1.sscmMultiExp(K', mu, B', nu).
- res = WriteFfElement(Fp, mu, (uint8_t*)&mu_str, sizeof(mu_str));
- BREAK_ON_EPID_ERROR(res);
- res = WriteFfElement(Fp, nu, (uint8_t*)&nu_str, sizeof(nu_str));
- BREAK_ON_EPID_ERROR(res);
- {
- EcPoint const* points[2];
- BigNumStr const* exponents[2];
- points[0] = rlK;
- points[1] = rlB;
- exponents[0] = &mu_str;
- exponents[1] = &nu_str;
- res = EcSscmMultiExp(G1, points, exponents, COUNT_OF(points), T);
- BREAK_ON_EPID_ERROR(res);
- }
- // 4. The member chooses rmu, rnu randomly from [1, p-1].
- res = FfGetRandom(Fp, &one, rnd_func, rnd_param, rmu);
- BREAK_ON_EPID_ERROR(res);
- res = FfGetRandom(Fp, &one, rnd_func, rnd_param, rnu);
- BREAK_ON_EPID_ERROR(res);
- // 5. The member computes R1 = G1.sscmMultiExp(K, rmu, B, rnu).
- res = WriteFfElement(Fp, rmu, (uint8_t*)&rmu_str, sizeof(rmu_str));
- BREAK_ON_EPID_ERROR(res);
- res = WriteFfElement(Fp, rnu, (uint8_t*)&rnu_str, sizeof(rnu_str));
- BREAK_ON_EPID_ERROR(res);
- {
- EcPoint const* points[2];
- BigNumStr const* exponents[2];
- points[0] = K;
- points[1] = B;
- exponents[0] = &rmu_str;
- exponents[1] = &rnu_str;
- res = EcSscmMultiExp(G1, points, exponents, COUNT_OF(points), R1);
- BREAK_ON_EPID_ERROR(res);
- }
- // 6. The member computes R2 = G1.sscmMultiExp(K', rmu, B', rnu).
- {
- EcPoint const* points[2];
- BigNumStr const* exponents[2];
- points[0] = rlK;
- points[1] = rlB;
- exponents[0] = &rmu_str;
- exponents[1] = &rnu_str;
- res = EcSscmMultiExp(G1, points, exponents, COUNT_OF(points), R2);
- BREAK_ON_EPID_ERROR(res);
- }
- // 7. The member computes c = Fp.hash(p || g1 || B || K || B' ||
- // K' || T || R1 || R2 || m). Refer to Section 7.1 for hash
- // operation over a prime field.
- // commit_values is allocated such that there are msg_len bytes available
- // starting at commit_values->msg
- if (msg) {
- // Memory copy is used to copy a message of variable length
- if (0 != memcpy_S(&commit_values->msg[0], msg_len, msg, msg_len)) {
- res = kEpidBadArgErr;
- break;
- }
- }
- commit_values->p = ctx->commit_values.p;
- commit_values->g1 = ctx->commit_values.g1;
- commit_values->b = sig->B;
- commit_values->k = sig->K;
- commit_values->bp = sigrl_entry->b;
- commit_values->kp = sigrl_entry->k;
- res = WriteEcPoint(G1, T, (uint8_t*)&commit_values->t,
- sizeof(commit_values->t));
- BREAK_ON_EPID_ERROR(res);
- res = WriteEcPoint(G1, R1, (uint8_t*)&commit_values->r1,
- sizeof(commit_values->r1));
- BREAK_ON_EPID_ERROR(res);
- res = WriteEcPoint(G1, R2, (uint8_t*)&commit_values->r2,
- sizeof(commit_values->r2));
- BREAK_ON_EPID_ERROR(res);
- res = FfHash(Fp, (uint8_t*)commit_values, commit_len, ctx->hash_alg, c);
- BREAK_ON_EPID_ERROR(res);
- // 8. The member computes smu = (rmu + c * mu) mod p.
- res = FfMul(Fp, c, mu, smu);
- BREAK_ON_EPID_ERROR(res);
- res = FfAdd(Fp, rmu, smu, smu);
- BREAK_ON_EPID_ERROR(res);
- // 9. The member computes snu = (rnu + c * nu) mod p.
- res = FfMul(Fp, c, nu, snu);
- BREAK_ON_EPID_ERROR(res);
- res = FfAdd(Fp, rnu, snu, snu);
- BREAK_ON_EPID_ERROR(res);
- // 10. The member outputs sigma = (T, c, smu, snu), a non-revoked
- // proof. If G1.is_identity(T) = true, the member also outputs
- // "failed".
- proof->T = commit_values->t;
- res = WriteFfElement(Fp, c, (uint8_t*)&proof->c, sizeof(proof->c));
- BREAK_ON_EPID_ERROR(res);
- res = WriteFfElement(Fp, smu, (uint8_t*)&proof->smu, sizeof(proof->smu));
- BREAK_ON_EPID_ERROR(res);
- res = WriteFfElement(Fp, snu, (uint8_t*)&proof->snu, sizeof(proof->snu));
- BREAK_ON_EPID_ERROR(res);
- res = EcIsIdentity(G1, T, &is_identity);
- BREAK_ON_EPID_ERROR(res);
- if (is_identity) {
- res = kEpidSigRevokedInSigRl;
- BREAK_ON_EPID_ERROR(res);
- }
- res = kEpidNoErr;
- } while (0);
- f = NULL;
- SAFE_FREE(commit_values)
- DeleteEcPoint(&T);
- DeleteEcPoint(&R1);
- DeleteEcPoint(&R2);
- DeleteFfElement(&mu);
- DeleteFfElement(&nu);
- DeleteFfElement(&rmu);
- DeleteFfElement(&rnu);
- DeleteFfElement(&c);
- DeleteFfElement(&smu);
- DeleteFfElement(&snu);
- DeleteEcPoint(&B);
- DeleteEcPoint(&K);
- DeleteEcPoint(&rlB);
- DeleteEcPoint(&rlK);
- return res;
- }
|