• 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 1.1 constant parameters implementation.
20 */
21 #include "epid/common/1.1/src/epid11params.h"
22 #include "epid/common/math/tatepairing.h"
23 #include "epid/common/src/memory.h"
24 
25 /// Handle SDK Error with Break
26 #define BREAK_ON_EPID_ERROR(ret) \
27   if (kEpidNoErr != (ret)) {     \
28     break;                       \
29   }
30 
31 /// Count of elements in array
32 #define COUNT_OF(a) (sizeof(a) / sizeof((a)[0]))
33 
34 /// create a new Finite Field Fqd
35 static EpidStatus NewFqd(Epid11Params const* params, FiniteField* Fq,
36                          FiniteField** Fqd);
37 
38 /// create a new Finite Field Fqk
39 EpidStatus NewFqk(Epid11Params const* params, FiniteField* Fq, FiniteField* Fqd,
40                   FiniteField** Fqk);
41 
42 /// create a new Elliptic curve group G1 over Fq
43 static EpidStatus NewG1(Epid11Params const* params, FiniteField* Fq,
44                         EcGroup** G1);
45 
46 /// create a new Elliptic curve group G2 over Fqd
47 static EpidStatus NewG2(Epid11Params const* params, FiniteField* Fq,
48                         FiniteField* Fqd, EcGroup** G2);
49 
50 /// create a new Elliptic curve group G3 over Fq'
51 static EpidStatus NewG3(Epid11Params const* params, FiniteField* Fq_tick,
52                         EcGroup** G3);
53 
CreateEpid11Params(Epid11Params_ ** params)54 EpidStatus CreateEpid11Params(Epid11Params_** params) {
55   EpidStatus result = kEpidErr;
56   Epid11Params_* _params = NULL;
57   Epid11Params params_str = {
58 #include "epid/common/1.1/src/epid11params_tate.inc"
59   };
60 
61   if (!params) return kEpidBadArgErr;
62 
63   do {
64     _params = SAFE_ALLOC(sizeof(Epid11Params_));
65     if (!_params) {
66       result = kEpidMemAllocErr;
67       break;
68     }
69 
70     // BigNum* p;
71     result = NewBigNum(sizeof(params_str.p), &_params->p);
72     BREAK_ON_EPID_ERROR(result);
73     result = ReadBigNum(&params_str.p, sizeof(params_str.p), _params->p);
74     BREAK_ON_EPID_ERROR(result);
75     // BigNum* p_tick;
76     result = NewBigNum(sizeof(params_str.p_tick), &_params->p_tick);
77     BREAK_ON_EPID_ERROR(result);
78     result = ReadBigNum(&params_str.p_tick, sizeof(params_str.p_tick),
79                         _params->p_tick);
80     BREAK_ON_EPID_ERROR(result);
81 
82     // FiniteField* Fp;
83     result = NewFiniteField(&params_str.p, &_params->Fp);
84     BREAK_ON_EPID_ERROR(result);
85     // FiniteField* Fq;
86     result = NewFiniteField(&params_str.q, &_params->Fq);
87     BREAK_ON_EPID_ERROR(result);
88     // FiniteField* Fp_tick;
89     result = NewFiniteField(&params_str.p_tick, &_params->Fp_tick);
90     BREAK_ON_EPID_ERROR(result);
91     // FiniteField* Fq_tick;
92     result = NewFiniteField(&params_str.q_tick, &_params->Fq_tick);
93     BREAK_ON_EPID_ERROR(result);
94     // FiniteField* Fqd;
95     result = NewFqd(&params_str, _params->Fq, &_params->Fqd);
96     BREAK_ON_EPID_ERROR(result);
97 
98     // EcGroup* G1;
99     result = NewG1(&params_str, _params->Fq, &_params->G1);
100     BREAK_ON_EPID_ERROR(result);
101     // EcGroup* G2;
102     result = NewG2(&params_str, _params->Fq, _params->Fqd, &_params->G2);
103     BREAK_ON_EPID_ERROR(result);
104     // EcGroup* G3;
105     result = NewG3(&params_str, _params->Fq_tick, &_params->G3);
106     BREAK_ON_EPID_ERROR(result);
107     // FiniteField* GT;
108     result = NewFqk(&params_str, _params->Fq, _params->Fqd, &_params->GT);
109     BREAK_ON_EPID_ERROR(result);
110 
111     // EcPoint* g1;
112     result = NewEcPoint(_params->G1, &_params->g1);
113     BREAK_ON_EPID_ERROR(result);
114     result = ReadEcPoint(_params->G1, &params_str.g1, sizeof(params_str.g1),
115                          _params->g1);
116     BREAK_ON_EPID_ERROR(result);
117     // EcPoint* g2;
118     result = NewEcPoint(_params->G2, &_params->g2);
119     BREAK_ON_EPID_ERROR(result);
120     result = ReadEcPoint(_params->G2, &params_str.g2, sizeof(params_str.g2),
121                          _params->g2);
122     BREAK_ON_EPID_ERROR(result);
123     // EcPoint* g3;
124     result = NewEcPoint(_params->G3, &_params->g3);
125     BREAK_ON_EPID_ERROR(result);
126     result = ReadEcPoint(_params->G3, &params_str.g3, sizeof(params_str.g3),
127                          _params->g3);
128     BREAK_ON_EPID_ERROR(result);
129 
130     // Epid11PairingState* pairing_state;
131     result = NewEpid11PairingState(_params->G1, _params->G2, _params->GT,
132                                    &_params->pairing_state);
133     BREAK_ON_EPID_ERROR(result);
134 
135     *params = _params;
136     result = kEpidNoErr;
137   } while (0);
138 
139   if (kEpidNoErr != result && _params) {
140     DeleteEpid11PairingState(&_params->pairing_state);
141 
142     DeleteBigNum(&_params->p);
143     DeleteBigNum(&_params->p_tick);
144     DeleteEcPoint(&_params->g1);
145     DeleteEcPoint(&_params->g2);
146     DeleteEcPoint(&_params->g3);
147 
148     DeleteFiniteField(&_params->Fp);
149     DeleteFiniteField(&_params->Fq);
150     DeleteFiniteField(&_params->Fp_tick);
151     DeleteFiniteField(&_params->Fq_tick);
152     DeleteFiniteField(&_params->Fqd);
153     DeleteFiniteField(&_params->GT);
154 
155     DeleteEcGroup(&_params->G1);
156     DeleteEcGroup(&_params->G2);
157     DeleteEcGroup(&_params->G3);
158     SAFE_FREE(_params);
159   }
160   return result;
161 }
162 
DeleteEpid11Params(Epid11Params_ ** params)163 void DeleteEpid11Params(Epid11Params_** params) {
164   if (params && *params) {
165     DeleteEpid11PairingState(&(*params)->pairing_state);
166 
167     DeleteBigNum(&(*params)->p);
168     DeleteBigNum(&(*params)->p_tick);
169     DeleteEcPoint(&(*params)->g1);
170     DeleteEcPoint(&(*params)->g2);
171     DeleteEcPoint(&(*params)->g3);
172 
173     DeleteFiniteField(&(*params)->Fp);
174     DeleteFiniteField(&(*params)->Fq);
175     DeleteFiniteField(&(*params)->Fp_tick);
176     DeleteFiniteField(&(*params)->Fq_tick);
177     DeleteFiniteField(&(*params)->Fqd);
178     DeleteFiniteField(&(*params)->GT);
179 
180     DeleteEcGroup(&(*params)->G1);
181     DeleteEcGroup(&(*params)->G2);
182     DeleteEcGroup(&(*params)->G3);
183 
184     SAFE_FREE(*params);
185   }
186 }
187 
NewFqd(Epid11Params const * params,FiniteField * Fq,FiniteField ** Fqd)188 EpidStatus NewFqd(Epid11Params const* params, FiniteField* Fq,
189                   FiniteField** Fqd) {
190   if (!params || !Fq || !Fqd) return kEpidBadArgErr;
191 
192   return NewFiniteFieldViaPolynomialExtension(Fq, params->coeff, 3, Fqd);
193 }
194 
NewFqk(Epid11Params const * params,FiniteField * Fq,FiniteField * Fqd,FiniteField ** Fqk)195 EpidStatus NewFqk(Epid11Params const* params, FiniteField* Fq, FiniteField* Fqd,
196                   FiniteField** Fqk) {
197   EpidStatus result = kEpidNoErr;
198   FfElement* qnr = NULL;
199   FfElement* neg_qnr = NULL;
200   FfElement* ground_element = NULL;
201   Fq3ElemStr ground_element_str = {0};
202 
203   if (!params || !Fq || !Fqd || !Fqk) return kEpidBadArgErr;
204 
205   do {
206     result = NewFfElement(Fq, &qnr);
207     BREAK_ON_EPID_ERROR(result);
208 
209     result = ReadFfElement(Fq, &(params->qnr), sizeof(params->qnr), qnr);
210     BREAK_ON_EPID_ERROR(result);
211 
212     result = NewFfElement(Fq, &neg_qnr);
213     BREAK_ON_EPID_ERROR(result);
214 
215     result = FfNeg(Fq, qnr, neg_qnr);
216     BREAK_ON_EPID_ERROR(result);
217 
218     result = WriteFfElement(Fq, neg_qnr, &ground_element_str.a[0],
219                             sizeof(ground_element_str.a[0]));
220     BREAK_ON_EPID_ERROR(result);
221 
222     result = NewFfElement(Fqd, &ground_element);
223     BREAK_ON_EPID_ERROR(result);
224 
225     result = ReadFfElement(Fqd, &(ground_element_str),
226                            sizeof(ground_element_str), ground_element);
227     BREAK_ON_EPID_ERROR(result);
228 
229     result = NewFiniteFieldViaBinomalExtension(Fqd, ground_element, 2, Fqk);
230     BREAK_ON_EPID_ERROR(result);
231   } while (0);
232 
233   DeleteFfElement(&qnr);
234   DeleteFfElement(&neg_qnr);
235   DeleteFfElement(&ground_element);
236 
237   return result;
238 }
239 
NewG1(Epid11Params const * params,FiniteField * Fq,EcGroup ** G1)240 EpidStatus NewG1(Epid11Params const* params, FiniteField* Fq, EcGroup** G1) {
241   EpidStatus result = kEpidErr;
242   EcGroup* ec = NULL;
243   FfElement* fq_a = NULL;
244   FfElement* fq_b = NULL;
245   FfElement* g1_x = NULL;
246   FfElement* g1_y = NULL;
247   BigNum* order = NULL;
248   BigNum* h = NULL;
249 
250   if (!params || !Fq || !G1) return kEpidBadArgErr;
251 
252   do {
253     // Create G1
254     // G1 is an elliptic curve group E(Fq).It can be initialized as follows:
255     //   1. Set G1 = E(Fq).init(p, q, h, a, b, g1.x, g1.y).
256     // a
257     result = NewFfElement(Fq, &fq_a);
258     BREAK_ON_EPID_ERROR(result);
259     result = ReadFfElement(Fq, &params->a, sizeof(params->a), fq_a);
260     BREAK_ON_EPID_ERROR(result);
261     // b
262     result = NewFfElement(Fq, &fq_b);
263     BREAK_ON_EPID_ERROR(result);
264     result = ReadFfElement(Fq, &params->b, sizeof(params->b), fq_b);
265     BREAK_ON_EPID_ERROR(result);
266     // g1.x
267     result = NewFfElement(Fq, &g1_x);
268     BREAK_ON_EPID_ERROR(result);
269     result = ReadFfElement(Fq, &params->g1.x, sizeof(params->g1.x), g1_x);
270     BREAK_ON_EPID_ERROR(result);
271     // g1.y
272     result = NewFfElement(Fq, &g1_y);
273     BREAK_ON_EPID_ERROR(result);
274     result = ReadFfElement(Fq, &params->g1.y, sizeof(params->g1.y), g1_y);
275     BREAK_ON_EPID_ERROR(result);
276     // order
277     result = NewBigNum(sizeof(BigNumStr), &order);
278     BREAK_ON_EPID_ERROR(result);
279     result = ReadBigNum(&params->p, sizeof(params->p), order);
280     BREAK_ON_EPID_ERROR(result);
281     // h
282     result = NewBigNum(sizeof(BigNumStr), &h);
283     BREAK_ON_EPID_ERROR(result);
284     result = ReadBigNum(&params->h, sizeof(params->h), h);
285     BREAK_ON_EPID_ERROR(result);
286 
287     result = NewEcGroup(Fq, fq_a, fq_b, g1_x, g1_y, order, h, &ec);
288     BREAK_ON_EPID_ERROR(result);
289     *G1 = ec;
290     result = kEpidNoErr;
291   } while (0);
292 
293   DeleteBigNum(&h);
294   DeleteBigNum(&order);
295   DeleteFfElement(&g1_y);
296   DeleteFfElement(&g1_x);
297   DeleteFfElement(&fq_b);
298   DeleteFfElement(&fq_a);
299 
300   return result;
301 }
302 
NewG3(Epid11Params const * params,FiniteField * Fq_dash,EcGroup ** G3)303 EpidStatus NewG3(Epid11Params const* params, FiniteField* Fq_dash,
304                  EcGroup** G3) {
305   EpidStatus result = kEpidErr;
306   EcGroup* ec = NULL;
307   FfElement* fq_a = NULL;
308   FfElement* fq_b = NULL;
309   FfElement* g3_x = NULL;
310   FfElement* g3_y = NULL;
311   BigNum* order = NULL;
312   BigNum* h_tick = NULL;
313 
314   if (!params || !Fq_dash || !G3) return kEpidBadArgErr;
315 
316   do {
317     // Create G3
318     // G3 is an elliptic curve group E(Fq').It can be initialized as follows:
319     //   1. Set G3 = E(Fq').init(p', q', h', a', b', g3.x, g3.y).
320     // a'
321     result = NewFfElement(Fq_dash, &fq_a);
322     BREAK_ON_EPID_ERROR(result);
323     result =
324         ReadFfElement(Fq_dash, &params->a_tick, sizeof(params->a_tick), fq_a);
325     BREAK_ON_EPID_ERROR(result);
326     // b'
327     result = NewFfElement(Fq_dash, &fq_b);
328     BREAK_ON_EPID_ERROR(result);
329     result =
330         ReadFfElement(Fq_dash, &params->b_tick, sizeof(params->b_tick), fq_b);
331     BREAK_ON_EPID_ERROR(result);
332     // g3.x
333     result = NewFfElement(Fq_dash, &g3_x);
334     BREAK_ON_EPID_ERROR(result);
335     result = ReadFfElement(Fq_dash, &params->g3.x, sizeof(params->g3.x), g3_x);
336     BREAK_ON_EPID_ERROR(result);
337     // g3.y
338     result = NewFfElement(Fq_dash, &g3_y);
339     BREAK_ON_EPID_ERROR(result);
340     result = ReadFfElement(Fq_dash, &params->g3.y, sizeof(params->g3.y), g3_y);
341     BREAK_ON_EPID_ERROR(result);
342     // order
343     result = NewBigNum(sizeof(BigNumStr), &order);
344     BREAK_ON_EPID_ERROR(result);
345     result = ReadBigNum(&params->p_tick, sizeof(params->p_tick), order);
346     BREAK_ON_EPID_ERROR(result);
347     // h'
348     result = NewBigNum(sizeof(BigNumStr), &h_tick);
349     BREAK_ON_EPID_ERROR(result);
350     result = ReadBigNum(&params->h_tick, sizeof(params->h_tick), h_tick);
351     BREAK_ON_EPID_ERROR(result);
352 
353     result = NewEcGroup(Fq_dash, fq_a, fq_b, g3_x, g3_y, order, h_tick, &ec);
354     BREAK_ON_EPID_ERROR(result);
355     *G3 = ec;
356     result = kEpidNoErr;
357   } while (0);
358 
359   DeleteBigNum(&h_tick);
360   DeleteBigNum(&order);
361   DeleteFfElement(&g3_y);
362   DeleteFfElement(&g3_x);
363   DeleteFfElement(&fq_b);
364   DeleteFfElement(&fq_a);
365 
366   return result;
367 }
368 
NewG2(Epid11Params const * params,FiniteField * Fq,FiniteField * Fqd,EcGroup ** G2)369 EpidStatus NewG2(Epid11Params const* params, FiniteField* Fq, FiniteField* Fqd,
370                  EcGroup** G2) {
371   EpidStatus result = kEpidErr;
372   EcGroup* ec = NULL;
373   FfElement* fq_twista = NULL;
374   FfElement* fq_twistb = NULL;
375   FfElement* fqd_twista = NULL;
376   FfElement* fqd_twistb = NULL;
377   FfElement* g2_x = NULL;
378   FfElement* g2_y = NULL;
379   FfElement* qnr = NULL;
380   BigNum* order = NULL;
381   BigNum* h = NULL;
382   Fq3ElemStr tmp_Fq3_str = {0};
383 
384   if (!params || !Fq || !Fqd || !G2) return kEpidBadArgErr;
385 
386   do {
387     // Create G2
388     // G2 is an elliptic curve group E(Fqd).It can be initialized as follows:
389     // 2. Set g2.x = (g2.x[0], g2.x[1], g2.x[2]) an element of Fqd
390     result = NewFfElement(Fqd, &g2_x);
391     BREAK_ON_EPID_ERROR(result);
392     result = ReadFfElement(Fqd, &params->g2.x, sizeof(params->g2.x), g2_x);
393     BREAK_ON_EPID_ERROR(result);
394     // 3. Set g2.y = (g2.y[0], g2.y[1], g2.y[2]) an element of Fqd
395     result = NewFfElement(Fqd, &g2_y);
396     BREAK_ON_EPID_ERROR(result);
397     result = ReadFfElement(Fqd, &params->g2.y, sizeof(params->g2.y), g2_y);
398     BREAK_ON_EPID_ERROR(result);
399     // qnr
400     result = NewFfElement(Fq, &qnr);
401     BREAK_ON_EPID_ERROR(result);
402     result = ReadFfElement(Fq, &params->qnr, sizeof(params->qnr), qnr);
403     BREAK_ON_EPID_ERROR(result);
404     // 4. twista = (a * qnr * qnr) mod q
405     result = NewFfElement(Fq, &fq_twista);
406     BREAK_ON_EPID_ERROR(result);
407     result = ReadFfElement(Fq, &params->a, sizeof(params->a), fq_twista);
408     BREAK_ON_EPID_ERROR(result);
409     result = FfMul(Fq, fq_twista, qnr, fq_twista);
410     BREAK_ON_EPID_ERROR(result);
411     result = FfMul(Fq, fq_twista, qnr, fq_twista);
412     BREAK_ON_EPID_ERROR(result);
413     // twista = {twista, 0, 0}
414     result = WriteFfElement(Fq, fq_twista, &(tmp_Fq3_str.a[0]),
415                             sizeof(tmp_Fq3_str.a[0]));
416     BREAK_ON_EPID_ERROR(result);
417     result = NewFfElement(Fqd, &fqd_twista);
418     BREAK_ON_EPID_ERROR(result);
419     result = ReadFfElement(Fqd, &tmp_Fq3_str, sizeof(tmp_Fq3_str), fqd_twista);
420     BREAK_ON_EPID_ERROR(result);
421     // 5. twistb = (b * qnr * qnr * qnr) mod q
422     result = NewFfElement(Fq, &fq_twistb);
423     BREAK_ON_EPID_ERROR(result);
424     result = ReadFfElement(Fq, &params->b, sizeof(params->b), fq_twistb);
425     BREAK_ON_EPID_ERROR(result);
426     result = FfMul(Fq, fq_twistb, qnr, fq_twistb);
427     BREAK_ON_EPID_ERROR(result);
428     result = FfMul(Fq, fq_twistb, qnr, fq_twistb);
429     BREAK_ON_EPID_ERROR(result);
430     result = FfMul(Fq, fq_twistb, qnr, fq_twistb);
431     BREAK_ON_EPID_ERROR(result);
432     // twistb = {twistb, 0, 0}
433     result = WriteFfElement(Fq, fq_twistb, &(tmp_Fq3_str.a[0]),
434                             sizeof(tmp_Fq3_str.a[0]));
435     BREAK_ON_EPID_ERROR(result);
436     result = NewFfElement(Fqd, &fqd_twistb);
437     BREAK_ON_EPID_ERROR(result);
438     result = ReadFfElement(Fqd, &tmp_Fq3_str, sizeof(tmp_Fq3_str), fqd_twistb);
439     BREAK_ON_EPID_ERROR(result);
440     // order
441     result = NewBigNum(3 * sizeof(BigNumStr), &order);
442     BREAK_ON_EPID_ERROR(result);
443     result = ReadBigNum(&params->orderG2, sizeof(params->orderG2), order);
444     BREAK_ON_EPID_ERROR(result);
445     // h
446     result = NewBigNum(sizeof(BigNumStr), &h);
447     BREAK_ON_EPID_ERROR(result);
448     result = ReadBigNum(&params->h, sizeof(params->h), h);
449     BREAK_ON_EPID_ERROR(result);
450 
451     // 6. Set G2 = E(Fqd).init(orderG2, param(Fqd), twista, twistb, g2.x, g2.y)
452     result = NewEcGroup(Fqd, fqd_twista, fqd_twistb, g2_x, g2_y, order, h, &ec);
453     BREAK_ON_EPID_ERROR(result);
454     *G2 = ec;
455     result = kEpidNoErr;
456   } while (0);
457 
458   DeleteBigNum(&h);
459   DeleteBigNum(&order);
460   DeleteFfElement(&qnr);
461   DeleteFfElement(&fqd_twistb);
462   DeleteFfElement(&fq_twistb);
463   DeleteFfElement(&fqd_twista);
464   DeleteFfElement(&fq_twista);
465   DeleteFfElement(&g2_y);
466   DeleteFfElement(&g2_x);
467 
468   return result;
469 }
470