1 /*******************************************************************************
2 * Copyright 2016-2018 Intel Corporation
3 * All Rights Reserved.
4 *
5 * If this software was obtained under the Intel Simplified Software License,
6 * the following terms apply:
7 *
8 * The source code, information and material ("Material") contained herein is
9 * owned by Intel Corporation or its suppliers or licensors, and title to such
10 * Material remains with Intel Corporation or its suppliers or licensors. The
11 * Material contains proprietary information of Intel or its suppliers and
12 * licensors. The Material is protected by worldwide copyright laws and treaty
13 * provisions. No part of the Material may be used, copied, reproduced,
14 * modified, published, uploaded, posted, transmitted, distributed or disclosed
15 * in any way without Intel's prior express written permission. No license under
16 * any patent, copyright or other intellectual property rights in the Material
17 * is granted to or conferred upon you, either expressly, by implication,
18 * inducement, estoppel or otherwise. Any license under such intellectual
19 * property rights must be express and approved by Intel in writing.
20 *
21 * Unless otherwise agreed by Intel in writing, you may not remove or alter this
22 * notice or any other notice embedded in Materials by Intel or Intel's
23 * suppliers or licensors in any way.
24 *
25 *
26 * If this software was obtained under the Apache License, Version 2.0 (the
27 * "License"), the following terms apply:
28 *
29 * You may not use this file except in compliance with the License. You may
30 * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
31 *
32 *
33 * Unless required by applicable law or agreed to in writing, software
34 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
35 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36 *
37 * See the License for the specific language governing permissions and
38 * limitations under the License.
39 *******************************************************************************/
40
41 /*
42 // Intel(R) Integrated Performance Primitives. Cryptography Primitives.
43 // GF(p^d) methods, if binomial generator
44 //
45 */
46 #include "owncp.h"
47
48 #include "pcpgfpxstuff.h"
49 #include "pcpgfpxmethod_com.h"
50 #include "pcpgfpxmethod_binom_epid2.h"
51
52 //tbcd: temporary excluded: #include <assert.h>
53
54 /*
55 // Intel(R) Enhanced Privacy ID (Intel(R) EPID) 2.0 specific.
56 //
57 // Intel(R) EPID 2.0 uses the following finite field hierarchy:
58 //
59 // 1) prime field GF(p),
60 // p = 0xFFFFFFFFFFFCF0CD46E5F25EEE71A49F0CDC65FB12980A82D3292DDBAED33013
61 //
62 // 2) 2-degree extension of GF(p): GF(p^2) == GF(p)[x]/g(x), g(x) = x^2 -beta,
63 // beta =-1 mod p, so "beta" represents as {1}
64 //
65 // 3) 3-degree extension of GF(p^2) ~ GF(p^6): GF((p^2)^3) == GF(p)[v]/g(v), g(v) = v^3 -xi,
66 // xi belongs GF(p^2), xi=x+2, so "xi" represents as {2,1} ---- "2" is low- and "1" is high-order coefficients
67 //
68 // 4) 2-degree extension of GF((p^2)^3) ~ GF(p^12): GF(((p^2)^3)^2) == GF(p)[w]/g(w), g(w) = w^2 -vi,
69 // psi belongs GF((p^2)^3), vi=0*v^2 +1*v +0, so "vi" represents as {0,1,0}---- "0", '1" and "0" are low-, middle- and high-order coefficients
70 //
71 // See representations in t_gfpparam.cpp
72 //
73 */
74
75 /*
76 // Multiplication case: mul(a, vi) over GF((p^2)^3),
77 // where:
78 // a, belongs to GF((p^2)^3)
79 // xi belongs to GF((p^2)^3), vi={0,1,0}
80 //
81 // The case is important in GF(((p^2)^3)^2) arithmetic for Intel(R) EPID 2.0.
82 //
83 */
cpFq6Mul_vi(BNU_CHUNK_T * pR,const BNU_CHUNK_T * pA,gsEngine * pGFEx)84 __INLINE BNU_CHUNK_T* cpFq6Mul_vi(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)
85 {
86 gsEngine* pGroundGFE = GFP_PARENT(pGFEx);
87 int termLen = GFP_FELEN(pGroundGFE);
88
89 const BNU_CHUNK_T* pA0 = pA;
90 const BNU_CHUNK_T* pA1 = pA+termLen;
91 const BNU_CHUNK_T* pA2 = pA+termLen*2;
92 BNU_CHUNK_T* pR0 = pR;
93 BNU_CHUNK_T* pR1 = pR+termLen;
94 BNU_CHUNK_T* pR2 = pR+termLen*2;
95
96 BNU_CHUNK_T* t = cpGFpGetPool(1, pGroundGFE);
97 //tbcd: temporary excluded: assert(NULL!=t);
98
99 cpFq2Mul_xi(t, pA2, pGroundGFE);
100 cpGFpElementCopy(pR2, pA1, termLen);
101 cpGFpElementCopy(pR1, pA0, termLen);
102 cpGFpElementCopy(pR0, t, termLen);
103
104 cpGFpReleasePool(1, pGroundGFE);
105
106 return pR;
107 }
108
109 /*
110 // Intel(R) EPID 2.0 specific
111 // ~~~~~~~~~~~~~~~
112 //
113 // Multiplication over GF(p^2)
114 // - field polynomial: g(x) = x^2 - beta => binominal with specific value of "beta"
115 // - beta = p-1
116 //
117 // Multiplication over GF(((p^2)^3)^2) ~ GF(p^12)
118 // - field polynomial: g(w) = w^2 - vi => binominal with specific value of "vi"
119 // - vi = 0*v^2 + 1*v + 0 - i.e vi={0,1,0} belongs to GF((p^2)^3)
120 */
cpGFpxMul_p2_binom_epid2(BNU_CHUNK_T * pR,const BNU_CHUNK_T * pA,const BNU_CHUNK_T * pB,gsEngine * pGFEx)121 static BNU_CHUNK_T* cpGFpxMul_p2_binom_epid2(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)
122 {
123 gsEngine* pGroundGFE = GFP_PARENT(pGFEx);
124 mod_mul mulF = GFP_METHOD(pGroundGFE)->mul;
125 mod_add addF = GFP_METHOD(pGroundGFE)->add;
126 mod_sub subF = GFP_METHOD(pGroundGFE)->sub;
127
128 int groundElemLen = GFP_FELEN(pGroundGFE);
129
130 const BNU_CHUNK_T* pA0 = pA;
131 const BNU_CHUNK_T* pA1 = pA+groundElemLen;
132
133 const BNU_CHUNK_T* pB0 = pB;
134 const BNU_CHUNK_T* pB1 = pB+groundElemLen;
135
136 BNU_CHUNK_T* pR0 = pR;
137 BNU_CHUNK_T* pR1 = pR+groundElemLen;
138
139 BNU_CHUNK_T* t0 = cpGFpGetPool(4, pGroundGFE);
140 BNU_CHUNK_T* t1 = t0+groundElemLen;
141 BNU_CHUNK_T* t2 = t1+groundElemLen;
142 BNU_CHUNK_T* t3 = t2+groundElemLen;
143 //tbcd: temporary excluded: assert(NULL!=t0);
144
145 mulF(t0, pA0, pB0, pGroundGFE); /* t0 = a[0]*b[0] */
146 mulF(t1, pA1, pB1, pGroundGFE); /* t1 = a[1]*b[1] */
147 addF(t2, pA0, pA1, pGroundGFE); /* t2 = a[0]+a[1] */
148 addF(t3, pB0, pB1, pGroundGFE); /* t3 = b[0]+b[1] */
149
150 mulF(pR1, t2, t3, pGroundGFE); /* r[1] = (a[0]+a[1]) * (b[0]+b[1]) */
151 subF(pR1, pR1, t0, pGroundGFE); /* r[1] -= a[0]*b[0]) + a[1]*b[1] */
152 subF(pR1, pR1, t1, pGroundGFE);
153
154 /* Intel(R) EPID 2.0 specific */
155 {
156 int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx);
157
158 /* deal with GF(p^2) */
159 if(basicExtDegree==2) {
160 subF(pR0, t0, t1, pGroundGFE);
161 }
162 /* deal with GF(p^6^2) */
163 else if(basicExtDegree==12) {
164 cpFq6Mul_vi(t1, t1, pGroundGFE);
165 addF(pR0, t0, t1, pGroundGFE);
166 }
167 /* deal with GF(p^x^2) - it's not Intel(R) EPID 2.0 case, just a case */
168 else {
169 cpGFpxMul_G0(t1, t1, pGFEx);
170 subF(pR0, t0, t1, pGroundGFE);
171 }
172 }
173
174 cpGFpReleasePool(4, pGroundGFE);
175 return pR;
176 }
177
178 /*
179 // Intel(R) EPID 2.0 specific
180 // ~~~~~~~~~~~~~~~
181 //
182 // Squaring over GF(p^2)
183 // - field polynomial: g(x) = x^2 - beta => binominal with specific value of "beta"
184 // - beta = p-1
185 //
186 // Squaring in GF(((p^2)^3)^2) ~ GF(p^12)
187 // - field polynomial: g(w) = w^2 - vi => binominal with specific value of "vi"
188 // - vi = 0*v^2 + 1*v + 0 - i.e vi={0,1,0} belongs to GF((p^2)^3)
189 */
cpGFpxSqr_p2_binom_epid2(BNU_CHUNK_T * pR,const BNU_CHUNK_T * pA,gsEngine * pGFEx)190 static BNU_CHUNK_T* cpGFpxSqr_p2_binom_epid2(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)
191 {
192 gsEngine* pGroundGFE = GFP_PARENT(pGFEx);
193 mod_mul mulF = GFP_METHOD(pGroundGFE)->mul;
194 mod_sqr sqrF = GFP_METHOD(pGroundGFE)->sqr;
195 mod_add addF = GFP_METHOD(pGroundGFE)->add;
196 mod_sub subF = GFP_METHOD(pGroundGFE)->sub;
197
198 int groundElemLen = GFP_FELEN(pGroundGFE);
199
200 const BNU_CHUNK_T* pA0 = pA;
201 const BNU_CHUNK_T* pA1 = pA+groundElemLen;
202
203 BNU_CHUNK_T* pR0 = pR;
204 BNU_CHUNK_T* pR1 = pR+groundElemLen;
205
206 BNU_CHUNK_T* t0 = cpGFpGetPool(3, pGroundGFE);
207 BNU_CHUNK_T* t1 = t0+groundElemLen;
208 BNU_CHUNK_T* u0 = t1+groundElemLen;
209 //tbcd: temporary excluded: assert(NULL!=t0);
210
211 mulF(u0, pA0, pA1, pGroundGFE); /* u0 = a[0]*a[1] */
212
213 /* Intel(R) EPID 2.0 specific */
214 {
215 int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx);
216
217 /* deal with GF(p^2) */
218 if(basicExtDegree==2) {
219 addF(t0, pA0, pA1, pGroundGFE);
220 subF(t1, pA0, pA1, pGroundGFE);
221 mulF(pR0, t0, t1, pGroundGFE);
222 addF(pR1, u0, u0, pGroundGFE); /* r[1] = 2*a[0]*a[1] */
223 }
224 /* deal with GF(p^6^2) */
225 else if(basicExtDegree==12) {
226 subF(t0, pA0, pA1, pGroundGFE);
227 cpFq6Mul_vi(t1, pA1, pGroundGFE);
228 subF(t1, pA0, t1, pGroundGFE);
229 mulF(t0, t0, t1, pGroundGFE);
230 addF(t0, t0, u0, pGroundGFE);
231 cpFq6Mul_vi(t1, u0, pGroundGFE);
232 addF(pR0, t0, t1, pGroundGFE);
233 addF(pR1, u0, u0, pGroundGFE);
234 }
235 /* just a case */
236 else {
237 sqrF(t0, pA0, pGroundGFE); /* t0 = a[0]*a[0] */
238 sqrF(t1, pA1, pGroundGFE); /* t1 = a[1]*a[1] */
239 cpGFpxMul_G0(t1, t1, pGFEx);
240 subF(pR0, t0, t1, pGroundGFE);
241 addF(pR1, u0, u0, pGroundGFE); /* r[1] = 2*a[0]*a[1] */
242 }
243 }
244
245 cpGFpReleasePool(3, pGroundGFE);
246 return pR;
247 }
248
249 /*
250 // return specific polynomi alarith methods
251 // polynomial - deg 2 binomial (Intel(R) EPID 2.0)
252 */
gsPolyArith_binom2_epid2(void)253 static gsModMethod* gsPolyArith_binom2_epid2(void)
254 {
255 static gsModMethod m = {
256 cpGFpxEncode_com,
257 cpGFpxDecode_com,
258 cpGFpxMul_p2_binom_epid2,
259 cpGFpxSqr_p2_binom_epid2,
260 NULL,
261 cpGFpxAdd_com,
262 cpGFpxSub_com,
263 cpGFpxNeg_com,
264 cpGFpxDiv2_com,
265 cpGFpxMul2_com,
266 cpGFpxMul3_com,
267 //cpGFpxInv
268 };
269 return &m;
270 }
271
272 /*F*
273 // Name: ippsGFpxMethod_binom2_epid2
274 //
275 // Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd).
276 //
277 // Returns: pointer to a structure containing
278 // an implementation of arithmetic operations over GF(pd)
279 // g(x) = x^2 - a0, a0 from GF(q), a0 = 1
280 // g(w) = w^2 - V0, v0 from GF((q^2)^3), V0 = 0*s^2 + v + 0
281 //
282 //
283 *F*/
284
285 IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom2_epid2, (void) )
286 {
287 static IppsGFpMethod method = {
288 cpID_Binom2_epid20,
289 2,
290 NULL,
291 NULL
292 };
293 method.arith = gsPolyArith_binom2_epid2();
294 return &method;
295 }
296
297