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