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(¶ms_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(¶ms_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(¶ms_str.p, &_params->Fp);
84 BREAK_ON_EPID_ERROR(result);
85 // FiniteField* Fq;
86 result = NewFiniteField(¶ms_str.q, &_params->Fq);
87 BREAK_ON_EPID_ERROR(result);
88 // FiniteField* Fp_tick;
89 result = NewFiniteField(¶ms_str.p_tick, &_params->Fp_tick);
90 BREAK_ON_EPID_ERROR(result);
91 // FiniteField* Fq_tick;
92 result = NewFiniteField(¶ms_str.q_tick, &_params->Fq_tick);
93 BREAK_ON_EPID_ERROR(result);
94 // FiniteField* Fqd;
95 result = NewFqd(¶ms_str, _params->Fq, &_params->Fqd);
96 BREAK_ON_EPID_ERROR(result);
97
98 // EcGroup* G1;
99 result = NewG1(¶ms_str, _params->Fq, &_params->G1);
100 BREAK_ON_EPID_ERROR(result);
101 // EcGroup* G2;
102 result = NewG2(¶ms_str, _params->Fq, _params->Fqd, &_params->G2);
103 BREAK_ON_EPID_ERROR(result);
104 // EcGroup* G3;
105 result = NewG3(¶ms_str, _params->Fq_tick, &_params->G3);
106 BREAK_ON_EPID_ERROR(result);
107 // FiniteField* GT;
108 result = NewFqk(¶ms_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, ¶ms_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, ¶ms_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, ¶ms_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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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(¶ms->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(¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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(¶ms->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(¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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(¶ms->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(¶ms->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