epid2params.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  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. * \file
  18. * \brief Intel(R) EPID 2.0 constant parameters implementation.
  19. */
  20. #include "epid/common/src/epid2params.h"
  21. #include "epid/common/src/memory.h"
  22. /// create a new Finite Field Fp
  23. static EpidStatus NewFp(Epid2Params const* param, FiniteField** Fp);
  24. /// create a new Finite Field Fq
  25. static EpidStatus NewFq(Epid2Params const* param, FiniteField** Fq);
  26. /// create a new Finite Field Fq2
  27. static EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq,
  28. FiniteField** Fq2);
  29. /// create a new Finite Field Fq6
  30. EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi,
  31. FiniteField** Fq6);
  32. /// create a new Elliptic curve group G1 over Fq
  33. static EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq,
  34. EcGroup** G1);
  35. /// create a new Elliptic curve group G2 over Fq2
  36. static EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q,
  37. FiniteField* Fq, FiniteField* Fq2, EcGroup** G2);
  38. /// create a new Finite Field Fq12
  39. static EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT);
  40. /// create a new pairing state
  41. /// Deallocate Finite Field Fp
  42. static void DeleteFp(FiniteField** Fp);
  43. /// Deallocate Finite Field Fq
  44. static void DeleteFq(FiniteField** Fq);
  45. /// Deallocate Finite Field Fq2
  46. static void DeleteFq2(FiniteField** Fq2);
  47. /// Deallocate Finite Field Fq6
  48. static void DeleteFq6(FiniteField** Fq6);
  49. /// Deallocate Elliptic curve group G1 over Fq
  50. static void DeleteG1(EcGroup** G1);
  51. /// Deallocate Elliptic curve group G2 over Fq2
  52. static void DeleteG2(EcGroup** G2);
  53. /// Deallocate Finite Field Fq12
  54. static void DeleteGT(FiniteField** GT);
  55. EpidStatus CreateEpid2Params(Epid2Params_** params) {
  56. EpidStatus result = kEpidErr;
  57. Epid2Params_* internal_param = NULL;
  58. BigNumStr t_str = {0};
  59. Epid2Params params_str = {
  60. #include "epid/common/src/epid2params_ate.inc"
  61. };
  62. if (!params) {
  63. return kEpidBadArgErr;
  64. }
  65. do {
  66. internal_param = SAFE_ALLOC(sizeof(Epid2Params_));
  67. if (!internal_param) {
  68. result = kEpidMemAllocErr;
  69. break;
  70. }
  71. result = NewBigNum(sizeof(params_str.p), &internal_param->p);
  72. if (kEpidNoErr != result) {
  73. break;
  74. }
  75. result = ReadBigNum(&params_str.p, sizeof(params_str.p), internal_param->p);
  76. if (kEpidNoErr != result) {
  77. break;
  78. }
  79. result = NewBigNum(sizeof(params_str.q), &internal_param->q);
  80. if (kEpidNoErr != result) {
  81. break;
  82. }
  83. result = ReadBigNum(&params_str.q, sizeof(params_str.q), internal_param->q);
  84. if (kEpidNoErr != result) {
  85. break;
  86. }
  87. result = NewBigNum(sizeof(params_str.t), &internal_param->t);
  88. if (kEpidNoErr != result) {
  89. break;
  90. }
  91. result = ReadBigNum(&params_str.t, sizeof(params_str.t), internal_param->t);
  92. if (kEpidNoErr != result) {
  93. break;
  94. }
  95. internal_param->neg = (params_str.neg.data[0]) ? true : false;
  96. result = NewFp(&params_str, &internal_param->Fp);
  97. if (kEpidNoErr != result) {
  98. break;
  99. }
  100. result = NewFq(&params_str, &internal_param->Fq);
  101. if (kEpidNoErr != result) {
  102. break;
  103. }
  104. result = NewFq2(&params_str, internal_param->Fq, &internal_param->Fq2);
  105. if (kEpidNoErr != result) {
  106. break;
  107. }
  108. result = NewFfElement(internal_param->Fq, &internal_param->b);
  109. if (kEpidNoErr != result) {
  110. break;
  111. }
  112. result = ReadFfElement(internal_param->Fq, &params_str.b,
  113. sizeof(params_str.b), internal_param->b);
  114. if (kEpidNoErr != result) {
  115. break;
  116. }
  117. result = NewFfElement(internal_param->Fq2, &internal_param->xi);
  118. if (kEpidNoErr != result) {
  119. break;
  120. }
  121. result = ReadFfElement(internal_param->Fq2, &params_str.xi,
  122. sizeof(params_str.xi), internal_param->xi);
  123. if (kEpidNoErr != result) {
  124. break;
  125. }
  126. result = NewFq6(&params_str, internal_param->Fq2, internal_param->xi,
  127. &internal_param->Fq6);
  128. if (kEpidNoErr != result) {
  129. break;
  130. }
  131. result = NewGT(internal_param->Fq6, &internal_param->GT);
  132. if (kEpidNoErr != result) {
  133. break;
  134. }
  135. result = NewG1(&params_str, internal_param->Fq, &internal_param->G1);
  136. if (kEpidNoErr != result) {
  137. break;
  138. }
  139. result = NewEcPoint(internal_param->G1, &internal_param->g1);
  140. if (kEpidNoErr != result) {
  141. break;
  142. }
  143. result = ReadEcPoint(internal_param->G1, &params_str.g1,
  144. sizeof(params_str.g1), internal_param->g1);
  145. if (kEpidNoErr != result) {
  146. break;
  147. }
  148. result =
  149. NewG2(&params_str, internal_param->p, internal_param->q,
  150. internal_param->Fq, internal_param->Fq2, &internal_param->G2);
  151. if (kEpidNoErr != result) {
  152. break;
  153. }
  154. result = NewEcPoint(internal_param->G2, &internal_param->g2);
  155. if (kEpidNoErr != result) {
  156. break;
  157. }
  158. result = ReadEcPoint(internal_param->G2, &params_str.g2,
  159. sizeof(params_str.g2), internal_param->g2);
  160. if (kEpidNoErr != result) {
  161. break;
  162. }
  163. result = WriteBigNum(internal_param->t, sizeof(t_str), &t_str);
  164. if (kEpidNoErr != result) {
  165. break;
  166. }
  167. result = NewPairingState(internal_param->G1, internal_param->G2,
  168. internal_param->GT, &t_str, internal_param->neg,
  169. &internal_param->pairing_state);
  170. if (kEpidNoErr != result) {
  171. break;
  172. }
  173. *params = internal_param;
  174. result = kEpidNoErr;
  175. } while (0);
  176. if (kEpidNoErr != result && internal_param) {
  177. DeletePairingState(&internal_param->pairing_state);
  178. DeleteEcPoint(&internal_param->g2);
  179. DeleteEcPoint(&internal_param->g1);
  180. DeleteBigNum(&internal_param->p);
  181. DeleteBigNum(&internal_param->q);
  182. DeleteFfElement(&internal_param->b);
  183. DeleteBigNum(&internal_param->t);
  184. DeleteFp(&internal_param->Fp);
  185. DeleteFq(&internal_param->Fq);
  186. DeleteFq2(&internal_param->Fq2);
  187. DeleteFq6(&internal_param->Fq6);
  188. DeleteGT(&internal_param->GT);
  189. DeleteG1(&internal_param->G1);
  190. DeleteG2(&internal_param->G2);
  191. SAFE_FREE(internal_param);
  192. }
  193. return result;
  194. }
  195. void DeleteEpid2Params(Epid2Params_** epid_params) {
  196. if (epid_params && *epid_params) {
  197. DeletePairingState(&(*epid_params)->pairing_state);
  198. DeleteBigNum(&(*epid_params)->p);
  199. DeleteBigNum(&(*epid_params)->q);
  200. DeleteFfElement(&(*epid_params)->b);
  201. DeleteBigNum(&(*epid_params)->t);
  202. DeleteFfElement(&(*epid_params)->xi);
  203. DeleteEcPoint(&(*epid_params)->g1);
  204. DeleteEcPoint(&(*epid_params)->g2);
  205. DeleteFp(&(*epid_params)->Fp);
  206. DeleteFq(&(*epid_params)->Fq);
  207. DeleteFq2(&(*epid_params)->Fq2);
  208. DeleteFq6(&(*epid_params)->Fq6);
  209. DeleteGT(&(*epid_params)->GT);
  210. DeleteG1(&(*epid_params)->G1);
  211. DeleteG2(&(*epid_params)->G2);
  212. SAFE_FREE(*epid_params);
  213. }
  214. }
  215. static EpidStatus NewFp(Epid2Params const* param, FiniteField** Fp) {
  216. EpidStatus result = kEpidErr;
  217. if (!param || !Fp) {
  218. return kEpidBadArgErr;
  219. }
  220. result = NewFiniteField(&param->p, Fp);
  221. if (kEpidNoErr != result) {
  222. return result;
  223. }
  224. return kEpidNoErr;
  225. }
  226. static EpidStatus NewFq(Epid2Params const* param, FiniteField** Fq) {
  227. EpidStatus result = kEpidErr;
  228. if (!param || !Fq) {
  229. return kEpidBadArgErr;
  230. }
  231. result = NewFiniteField(&param->q, Fq);
  232. if (kEpidNoErr != result) {
  233. return result;
  234. }
  235. return kEpidNoErr;
  236. }
  237. EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq,
  238. FiniteField** Fq2) {
  239. EpidStatus result = kEpidErr;
  240. FiniteField* Ff = NULL;
  241. FfElement* beta = NULL;
  242. FfElement* neg_beta = NULL;
  243. if (!param || !Fq || !Fq2) {
  244. return kEpidBadArgErr;
  245. }
  246. do {
  247. result = NewFfElement(Fq, &beta);
  248. if (kEpidNoErr != result) {
  249. break;
  250. }
  251. result = NewFfElement(Fq, &neg_beta);
  252. if (kEpidNoErr != result) {
  253. break;
  254. }
  255. result = ReadFfElement(Fq, &param->beta, sizeof(param->beta), beta);
  256. if (kEpidNoErr != result) {
  257. break;
  258. }
  259. result = FfNeg(Fq, beta, neg_beta);
  260. if (kEpidNoErr != result) {
  261. break;
  262. }
  263. result = NewFiniteFieldViaBinomalExtension(Fq, neg_beta, 2, &Ff);
  264. if (kEpidNoErr != result) {
  265. break;
  266. }
  267. *Fq2 = Ff;
  268. result = kEpidNoErr;
  269. } while (0);
  270. DeleteFfElement(&neg_beta);
  271. DeleteFfElement(&beta);
  272. return result;
  273. }
  274. EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi,
  275. FiniteField** Fq6) {
  276. EpidStatus result = kEpidErr;
  277. FiniteField* Ff = NULL;
  278. FfElement* neg_xi = NULL;
  279. if (!param || !Fq2 || !Fq6) {
  280. return kEpidBadArgErr;
  281. }
  282. do {
  283. result = NewFfElement(Fq2, &neg_xi);
  284. if (kEpidNoErr != result) {
  285. break;
  286. }
  287. result = FfNeg(Fq2, xi, neg_xi);
  288. if (kEpidNoErr != result) {
  289. break;
  290. }
  291. result = NewFiniteFieldViaBinomalExtension(Fq2, neg_xi, 3, &Ff);
  292. if (kEpidNoErr != result) {
  293. break;
  294. }
  295. *Fq6 = Ff;
  296. result = kEpidNoErr;
  297. } while (0);
  298. DeleteFfElement(&neg_xi);
  299. return result;
  300. }
  301. EpidStatus NewG1(Epid2Params const* param, FiniteField* Fq, EcGroup** G1) {
  302. EpidStatus result = kEpidErr;
  303. EcGroup* ec = NULL;
  304. FfElement* fq_a = NULL;
  305. FfElement* fq_b = NULL;
  306. FfElement* g1_x = NULL;
  307. FfElement* g1_y = NULL;
  308. BigNum* order = NULL;
  309. BigNum* cofactor = NULL;
  310. // h = 1;
  311. const BigNumStr h1 = {
  312. {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  313. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  314. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}};
  315. if (!param || !Fq || !G1) {
  316. return kEpidBadArgErr;
  317. }
  318. do {
  319. // Create G1
  320. // G1 is an elliptic curve group E(Fq).It can be initialized as follows :
  321. // 1. Set G1 = E(Fq).init(p, q, n = p, h = 1, a = 0, b, g1.x, g1.y).
  322. // a = 0
  323. // NewFfelement is Identidy
  324. result = NewFfElement(Fq, &fq_a);
  325. if (kEpidNoErr != result) {
  326. break;
  327. }
  328. // b
  329. result = NewFfElement(Fq, &fq_b);
  330. if (kEpidNoErr != result) {
  331. break;
  332. }
  333. result = ReadFfElement(Fq, &param->b, sizeof(param->b), fq_b);
  334. if (kEpidNoErr != result) {
  335. break;
  336. }
  337. // g1.x
  338. result = NewFfElement(Fq, &g1_x);
  339. if (kEpidNoErr != result) {
  340. break;
  341. }
  342. result = ReadFfElement(Fq, &param->g1.x, sizeof(param->g1.x), g1_x);
  343. if (kEpidNoErr != result) {
  344. break;
  345. }
  346. // g1.y
  347. result = NewFfElement(Fq, &g1_y);
  348. if (kEpidNoErr != result) {
  349. break;
  350. }
  351. result = ReadFfElement(Fq, &param->g1.y, sizeof(param->g1.y), g1_y);
  352. if (kEpidNoErr != result) {
  353. break;
  354. }
  355. // order
  356. result = NewBigNum(sizeof(BigNumStr), &order);
  357. if (kEpidNoErr != result) {
  358. break;
  359. }
  360. result = ReadBigNum(&param->p, sizeof(param->p), order);
  361. if (kEpidNoErr != result) {
  362. break;
  363. }
  364. // cofactor
  365. result = NewBigNum(sizeof(BigNumStr), &cofactor);
  366. if (kEpidNoErr != result) {
  367. break;
  368. }
  369. result = ReadBigNum(&h1, sizeof(h1), cofactor);
  370. if (kEpidNoErr != result) {
  371. break;
  372. }
  373. result = NewEcGroup(Fq, fq_a, fq_b, g1_x, g1_y, order, cofactor, &ec);
  374. if (kEpidNoErr != result) {
  375. break;
  376. }
  377. *G1 = ec;
  378. result = kEpidNoErr;
  379. } while (0);
  380. DeleteBigNum(&cofactor);
  381. DeleteBigNum(&order);
  382. DeleteFfElement(&g1_y);
  383. DeleteFfElement(&g1_x);
  384. DeleteFfElement(&fq_b);
  385. DeleteFfElement(&fq_a);
  386. return result;
  387. }
  388. EpidStatus NewG2(Epid2Params const* param, BigNum* p, BigNum* q,
  389. FiniteField* Fq, FiniteField* Fq2, EcGroup** G2) {
  390. EpidStatus result = kEpidErr;
  391. EcGroup* ec = NULL;
  392. FfElement* a = NULL;
  393. FfElement* b = NULL;
  394. FfElement* fq_param_b = NULL;
  395. FfElement* x = NULL;
  396. FfElement* y = NULL;
  397. BigNum* order = NULL;
  398. BigNum* cofactor = NULL;
  399. if (!param || !Fq || !Fq2 || !G2) {
  400. return kEpidBadArgErr;
  401. }
  402. do {
  403. // 2. Set xi = (xi0, xi1) an element of Fq2.
  404. // 3. Let b', xi' be a temporary variable in Fq2.
  405. // 4. Compute xi' = Fq2.inverse(xi).
  406. // 5. Compute b' = Fq2.mul(xi', b).
  407. result = NewFfElement(Fq2, &b);
  408. if (kEpidNoErr != result) {
  409. break;
  410. }
  411. result = ReadFfElement(Fq2, &param->xi, sizeof(param->xi), b);
  412. if (kEpidNoErr != result) {
  413. break;
  414. }
  415. result = FfInv(Fq2, b, b);
  416. if (kEpidNoErr != result) {
  417. break;
  418. }
  419. result = NewFfElement(Fq, &fq_param_b);
  420. if (kEpidNoErr != result) {
  421. break;
  422. }
  423. result = ReadFfElement(Fq, &param->b, sizeof(param->b), fq_param_b);
  424. if (kEpidNoErr != result) {
  425. break;
  426. }
  427. result = FfMul(Fq2, b, fq_param_b, b); // ??? overflow fq2*fq
  428. if (kEpidNoErr != result) {
  429. break;
  430. }
  431. // 6. Set g2.x = (g2.x[0], g2.x[1]) an element of Fq2.
  432. // 7. Set g2.y = (g2.y[0], g2.y[1]) an element of Fq2.
  433. result = NewFfElement(Fq2, &x);
  434. if (kEpidNoErr != result) {
  435. break;
  436. }
  437. result = ReadFfElement(Fq2, &param->g2.x, sizeof(param->g2.x), x);
  438. if (kEpidNoErr != result) {
  439. break;
  440. }
  441. result = NewFfElement(Fq2, &y);
  442. if (kEpidNoErr != result) {
  443. break;
  444. }
  445. result = ReadFfElement(Fq2, &param->g2.y, sizeof(param->g2.y), y);
  446. if (kEpidNoErr != result) {
  447. break;
  448. }
  449. // 8. set h = 2q - p, aka cofactor
  450. result = NewBigNum(2 * sizeof(param->q), &cofactor);
  451. if (kEpidNoErr != result) {
  452. break;
  453. }
  454. result = BigNumAdd(q, q, cofactor);
  455. if (kEpidNoErr != result) {
  456. break;
  457. }
  458. result = BigNumSub(cofactor, p, cofactor);
  459. if (kEpidNoErr != result) {
  460. break;
  461. }
  462. // 9. set n = p * h, AKA order
  463. result = NewBigNum(2 * sizeof(param->q), &order);
  464. if (kEpidNoErr != result) {
  465. break;
  466. }
  467. result = BigNumMul(p, cofactor, order);
  468. if (kEpidNoErr != result) {
  469. break;
  470. }
  471. // set a to identity, NewFfElement does it by default
  472. result = NewFfElement(Fq2, &a);
  473. if (kEpidNoErr != result) {
  474. break;
  475. }
  476. // 10. Set G2 = E(Fq2).init(p, param(Fq2), n, h, 0, b', g2.x, g2.y)
  477. result = NewEcGroup(Fq2, a, b, x, y, order, cofactor, &ec);
  478. if (kEpidNoErr != result) {
  479. break;
  480. }
  481. *G2 = ec;
  482. result = kEpidNoErr;
  483. } while (0);
  484. DeleteBigNum(&cofactor);
  485. DeleteBigNum(&order);
  486. DeleteFfElement(&y);
  487. DeleteFfElement(&x);
  488. DeleteFfElement(&b);
  489. DeleteFfElement(&a);
  490. DeleteFfElement(&fq_param_b);
  491. return result;
  492. }
  493. EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT) {
  494. EpidStatus result = kEpidErr;
  495. FiniteField* Ff = NULL;
  496. FfElement* v = NULL;
  497. FfElement* neg_v = NULL;
  498. const Fq6ElemStr v_str = {
  499. {{{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  500. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  501. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
  502. {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  503. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  504. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
  505. {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  506. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  507. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
  508. {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  509. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  510. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
  511. {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  512. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  513. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
  514. {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  515. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  516. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}}};
  517. if (!Fq6 || !GT) {
  518. return kEpidBadArgErr;
  519. }
  520. do {
  521. result = NewFfElement(Fq6, &v);
  522. if (kEpidNoErr != result) {
  523. break;
  524. }
  525. result = NewFfElement(Fq6, &neg_v);
  526. if (kEpidNoErr != result) {
  527. break;
  528. }
  529. result = ReadFfElement(Fq6, &v_str, sizeof(v_str), v);
  530. if (kEpidNoErr != result) {
  531. break;
  532. }
  533. result = FfNeg(Fq6, v, neg_v);
  534. if (kEpidNoErr != result) {
  535. break;
  536. }
  537. result = NewFiniteFieldViaBinomalExtension(Fq6, neg_v, 2, &Ff);
  538. if (kEpidNoErr != result) {
  539. break;
  540. }
  541. *GT = Ff;
  542. result = kEpidNoErr;
  543. } while (0);
  544. DeleteFfElement(&v);
  545. DeleteFfElement(&neg_v);
  546. return result;
  547. }
  548. static void DeleteFp(FiniteField** Fp) { DeleteFiniteField(Fp); }
  549. static void DeleteFq(FiniteField** Fq) { DeleteFiniteField(Fq); }
  550. static void DeleteFq2(FiniteField** Fq2) { DeleteFiniteField(Fq2); }
  551. static void DeleteFq6(FiniteField** Fq6) { DeleteFiniteField(Fq6); }
  552. static void DeleteG1(EcGroup** G1) { DeleteEcGroup(G1); }
  553. static void DeleteG2(EcGroup** G2) { DeleteEcGroup(G2); }
  554. static void DeleteGT(FiniteField** GT) { DeleteFiniteField(GT); }