nrverify.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*############################################################################
  2. # Copyright 2016 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. * \file
  18. * \brief NrVerfy implementation.
  19. */
  20. #include "epid/common/src/memory.h"
  21. #include "epid/verifier/api.h"
  22. #include "epid/verifier/src/context.h"
  23. /// Handle SDK Error with Break
  24. #define BREAK_ON_EPID_ERROR(ret) \
  25. if (kEpidNoErr != (ret)) { \
  26. break; \
  27. }
  28. #pragma pack(1)
  29. /// Storage for values to create commitment in NrVerify algorithm
  30. typedef struct NrVerifyCommitValues {
  31. BigNumStr p; //!< A large prime (256-bit)
  32. G1ElemStr g1; //!< Generator of G1 (512-bit)
  33. G1ElemStr b; //!< (element of G1): part of basic signature Sigma0
  34. G1ElemStr k; //!< (element of G1): part of basic signature Sigma0
  35. G1ElemStr bp; //!< (element of G1): one entry in SigRL
  36. G1ElemStr kp; //!< (element of G1): one entry in SigRL
  37. G1ElemStr t; //!< element of G1
  38. G1ElemStr r1; //!< element of G1
  39. G1ElemStr r2; //!< element of G1
  40. uint8_t msg[1]; //!< message
  41. } NrVerifyCommitValues;
  42. #pragma pack()
  43. EpidStatus EpidNrVerify(VerifierCtx const* ctx, BasicSignature const* sig,
  44. void const* msg, size_t msg_len,
  45. SigRlEntry const* sigrl_entry, NrProof const* proof) {
  46. size_t const cv_header_len = sizeof(NrVerifyCommitValues) - sizeof(uint8_t);
  47. EpidStatus sts = kEpidErr;
  48. NrVerifyCommitValues* commit_values = NULL;
  49. size_t const commit_len = sizeof(*commit_values) + msg_len - 1;
  50. EcPoint* t_pt = NULL;
  51. EcPoint* k_pt = NULL;
  52. EcPoint* b_pt = NULL;
  53. EcPoint* kp_pt = NULL;
  54. EcPoint* bp_pt = NULL;
  55. EcPoint* r1_pt = NULL;
  56. EcPoint* r2_pt = NULL;
  57. FfElement* c_el = NULL;
  58. FfElement* nc_el = NULL;
  59. FfElement* smu_el = NULL;
  60. FfElement* snu_el = NULL;
  61. FfElement* commit_hash = NULL;
  62. if (!ctx || !sig || !proof || !sigrl_entry) {
  63. return kEpidBadArgErr;
  64. }
  65. if (!msg && (0 != msg_len)) {
  66. return kEpidBadArgErr;
  67. }
  68. if (msg_len > (SIZE_MAX - cv_header_len)) {
  69. return kEpidBadArgErr;
  70. }
  71. if (!ctx->epid2_params || !ctx->epid2_params->G1 || !ctx->epid2_params->Fp) {
  72. return kEpidBadArgErr;
  73. }
  74. do {
  75. EcGroup* G1 = ctx->epid2_params->G1;
  76. FiniteField* Fp = ctx->epid2_params->Fp;
  77. G1ElemStr const* b = &sig->B;
  78. G1ElemStr const* k = &sig->K;
  79. G1ElemStr const* bp = &sigrl_entry->b;
  80. G1ElemStr const* kp = &sigrl_entry->k;
  81. EcPoint const* r1p[2];
  82. FpElemStr const* r1b[2];
  83. EcPoint const* r2p[3];
  84. FpElemStr const* r2b[3];
  85. FpElemStr nc_str;
  86. bool t_is_identity;
  87. bool c_is_equal;
  88. commit_values = SAFE_ALLOC(commit_len);
  89. if (commit_values == NULL) {
  90. sts = kEpidMemAllocErr;
  91. break;
  92. }
  93. // allocate local memory
  94. sts = NewEcPoint(G1, &t_pt);
  95. BREAK_ON_EPID_ERROR(sts);
  96. sts = NewEcPoint(G1, &k_pt);
  97. BREAK_ON_EPID_ERROR(sts);
  98. sts = NewEcPoint(G1, &b_pt);
  99. BREAK_ON_EPID_ERROR(sts);
  100. sts = NewEcPoint(G1, &kp_pt);
  101. BREAK_ON_EPID_ERROR(sts);
  102. sts = NewEcPoint(G1, &bp_pt);
  103. BREAK_ON_EPID_ERROR(sts);
  104. sts = NewEcPoint(G1, &r1_pt);
  105. BREAK_ON_EPID_ERROR(sts);
  106. sts = NewEcPoint(G1, &r2_pt);
  107. BREAK_ON_EPID_ERROR(sts);
  108. sts = NewFfElement(Fp, &c_el);
  109. BREAK_ON_EPID_ERROR(sts);
  110. sts = NewFfElement(Fp, &nc_el);
  111. BREAK_ON_EPID_ERROR(sts);
  112. sts = NewFfElement(Fp, &smu_el);
  113. BREAK_ON_EPID_ERROR(sts);
  114. sts = NewFfElement(Fp, &snu_el);
  115. BREAK_ON_EPID_ERROR(sts);
  116. sts = NewFfElement(Fp, &commit_hash);
  117. BREAK_ON_EPID_ERROR(sts);
  118. // 1. The verifier verifies that G1.inGroup(T) = true.
  119. sts = ReadEcPoint(G1, &proof->T, sizeof(proof->T), t_pt);
  120. if (kEpidNoErr != sts) {
  121. sts = kEpidBadArgErr;
  122. break;
  123. }
  124. // 2. The verifier verifies that G1.isIdentity(T) = false.
  125. sts = EcIsIdentity(G1, t_pt, &t_is_identity);
  126. BREAK_ON_EPID_ERROR(sts);
  127. if (t_is_identity) {
  128. sts = kEpidBadArgErr;
  129. break;
  130. }
  131. // 3. The verifier verifies that c, smu, snu in [0, p-1].
  132. sts = ReadFfElement(Fp, &proof->c, sizeof(proof->c), c_el);
  133. BREAK_ON_EPID_ERROR(sts);
  134. sts = ReadFfElement(Fp, &proof->smu, sizeof(proof->smu), smu_el);
  135. BREAK_ON_EPID_ERROR(sts);
  136. sts = ReadFfElement(Fp, &proof->snu, sizeof(proof->snu), snu_el);
  137. BREAK_ON_EPID_ERROR(sts);
  138. // 4. The verifier computes nc = (- c) mod p.
  139. sts = FfNeg(Fp, c_el, nc_el);
  140. BREAK_ON_EPID_ERROR(sts);
  141. sts = WriteFfElement(Fp, nc_el, &nc_str, sizeof(nc_str));
  142. BREAK_ON_EPID_ERROR(sts);
  143. // 5. The verifier computes R1 = G1.multiExp(K, smu, B, snu).
  144. sts = ReadEcPoint(G1, k, sizeof(*k), k_pt);
  145. if (kEpidNoErr != sts) {
  146. sts = kEpidBadArgErr;
  147. break;
  148. }
  149. sts = ReadEcPoint(G1, b, sizeof(*b), b_pt);
  150. if (kEpidNoErr != sts) {
  151. sts = kEpidBadArgErr;
  152. break;
  153. }
  154. r1p[0] = k_pt;
  155. r1p[1] = b_pt;
  156. r1b[0] = &proof->smu;
  157. r1b[1] = &proof->snu;
  158. sts = EcMultiExp(G1, r1p, (const BigNumStr**)r1b, 2, r1_pt);
  159. BREAK_ON_EPID_ERROR(sts);
  160. // 6. The verifier computes R2 = G1.multiExp(K', smu, B', snu, T, nc).
  161. sts = ReadEcPoint(G1, kp, sizeof(*kp), kp_pt);
  162. if (kEpidNoErr != sts) {
  163. sts = kEpidBadArgErr;
  164. break;
  165. }
  166. sts = ReadEcPoint(G1, bp, sizeof(*bp), bp_pt);
  167. if (kEpidNoErr != sts) {
  168. sts = kEpidBadArgErr;
  169. break;
  170. }
  171. r2p[0] = kp_pt;
  172. r2p[1] = bp_pt;
  173. r2p[2] = t_pt;
  174. r2b[0] = &proof->smu;
  175. r2b[1] = &proof->snu;
  176. r2b[2] = &nc_str;
  177. sts = EcMultiExp(G1, r2p, (const BigNumStr**)r2b, 3, r2_pt);
  178. BREAK_ON_EPID_ERROR(sts);
  179. // 7. The verifier verifies c = Fp.hash(p || g1 || B || K ||
  180. // B' || K' || T || R1 || R2 || m).
  181. // Refer to Section 7.1 for hash operation over a prime field.
  182. // commit_values is allocated such that there are msg_len bytes available
  183. // starting at commit_values->msg
  184. if (msg) {
  185. // Memory copy is used to copy a message of variable length
  186. if (0 != memcpy_S(&commit_values->msg[0], msg_len, msg, msg_len)) {
  187. sts = kEpidBadArgErr;
  188. break;
  189. }
  190. }
  191. commit_values->p = ctx->commit_values.p;
  192. commit_values->g1 = ctx->commit_values.g1;
  193. commit_values->b = sig->B;
  194. commit_values->k = sig->K;
  195. commit_values->bp = sigrl_entry->b;
  196. commit_values->kp = sigrl_entry->k;
  197. commit_values->t = proof->T;
  198. sts =
  199. WriteEcPoint(G1, r1_pt, &commit_values->r1, sizeof(commit_values->r1));
  200. BREAK_ON_EPID_ERROR(sts);
  201. sts =
  202. WriteEcPoint(G1, r2_pt, &commit_values->r2, sizeof(commit_values->r2));
  203. BREAK_ON_EPID_ERROR(sts);
  204. sts = FfHash(Fp, commit_values, commit_len, ctx->hash_alg, commit_hash);
  205. BREAK_ON_EPID_ERROR(sts);
  206. sts = FfIsEqual(Fp, c_el, commit_hash, &c_is_equal);
  207. BREAK_ON_EPID_ERROR(sts);
  208. if (!c_is_equal) {
  209. sts = kEpidBadArgErr;
  210. break;
  211. }
  212. sts = kEpidNoErr;
  213. } while (0);
  214. SAFE_FREE(commit_values);
  215. DeleteFfElement(&commit_hash);
  216. DeleteFfElement(&snu_el);
  217. DeleteFfElement(&smu_el);
  218. DeleteFfElement(&nc_el);
  219. DeleteFfElement(&c_el);
  220. DeleteEcPoint(&r2_pt);
  221. DeleteEcPoint(&r1_pt);
  222. DeleteEcPoint(&bp_pt);
  223. DeleteEcPoint(&kp_pt);
  224. DeleteEcPoint(&b_pt);
  225. DeleteEcPoint(&k_pt);
  226. DeleteEcPoint(&t_pt);
  227. return sts;
  228. }