summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_gf2m.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/bn/bn_gf2m.c1150
1 files changed, 678 insertions, 472 deletions
diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c
index a75c98ac0e..669f8c403e 100644
--- a/src/lib/libcrypto/bn/bn_gf2m.c
+++ b/src/lib/libcrypto/bn/bn_gf2m.c
@@ -42,7 +42,7 @@
42 * are met: 42 * are met:
43 * 43 *
44 * 1. Redistributions of source code must retain the above copyright 44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer. 45 * notice, this list of conditions and the following disclaimer.
46 * 46 *
47 * 2. Redistributions in binary form must reproduce the above copyright 47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in 48 * notice, this list of conditions and the following disclaimer in
@@ -100,8 +100,8 @@
100#define MAX_ITERATIONS 50 100#define MAX_ITERATIONS 50
101 101
102static const BN_ULONG SQR_tb[16] = 102static const BN_ULONG SQR_tb[16] =
103 { 0, 1, 4, 5, 16, 17, 20, 21, 103 { 0, 1, 4, 5, 16, 17, 20, 21,
104 64, 65, 68, 69, 80, 81, 84, 85 }; 10464, 65, 68, 69, 80, 81, 84, 85 };
105/* Platform-specific macros to accelerate squaring. */ 105/* Platform-specific macros to accelerate squaring. */
106#ifdef _LP64 106#ifdef _LP64
107#define SQR1(w) \ 107#define SQR1(w) \
@@ -129,126 +129,225 @@ static const BN_ULONG SQR_tb[16] =
129 * The caller MUST ensure that the variables have the right amount 129 * The caller MUST ensure that the variables have the right amount
130 * of space allocated. 130 * of space allocated.
131 */ 131 */
132static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) 132static void
133 { 133bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
134{
134#ifndef _LP64 135#ifndef _LP64
135 register BN_ULONG h, l, s; 136 register BN_ULONG h, l, s;
136 BN_ULONG tab[8], top2b = a >> 30; 137 BN_ULONG tab[8], top2b = a >> 30;
137 register BN_ULONG a1, a2, a4; 138 register BN_ULONG a1, a2, a4;
138 139
139 a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1; 140 a1 = a & (0x3FFFFFFF);
140 141 a2 = a1 << 1;
141 tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; 142 a4 = a2 << 1;
142 tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4; 143
143 144 tab[0] = 0;
144 s = tab[b & 0x7]; l = s; 145 tab[1] = a1;
145 s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29; 146 tab[2] = a2;
146 s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26; 147 tab[3] = a1 ^ a2;
147 s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23; 148 tab[4] = a4;
148 s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20; 149 tab[5] = a1 ^ a4;
149 s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17; 150 tab[6] = a2 ^ a4;
150 s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14; 151 tab[7] = a1 ^ a2 ^ a4;
151 s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11; 152
152 s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8; 153 s = tab[b & 0x7];
153 s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5; 154 l = s;
154 s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2; 155 s = tab[b >> 3 & 0x7];
156 l ^= s << 3;
157 h = s >> 29;
158 s = tab[b >> 6 & 0x7];
159 l ^= s << 6;
160 h ^= s >> 26;
161 s = tab[b >> 9 & 0x7];
162 l ^= s << 9;
163 h ^= s >> 23;
164 s = tab[b >> 12 & 0x7];
165 l ^= s << 12;
166 h ^= s >> 20;
167 s = tab[b >> 15 & 0x7];
168 l ^= s << 15;
169 h ^= s >> 17;
170 s = tab[b >> 18 & 0x7];
171 l ^= s << 18;
172 h ^= s >> 14;
173 s = tab[b >> 21 & 0x7];
174 l ^= s << 21;
175 h ^= s >> 11;
176 s = tab[b >> 24 & 0x7];
177 l ^= s << 24;
178 h ^= s >> 8;
179 s = tab[b >> 27 & 0x7];
180 l ^= s << 27;
181 h ^= s >> 5;
182 s = tab[b >> 30];
183 l ^= s << 30;
184 h ^= s >> 2;
155 185
156 /* compensate for the top two bits of a */ 186 /* compensate for the top two bits of a */
187 if (top2b & 01) {
188 l ^= b << 30;
189 h ^= b >> 2;
190 }
191 if (top2b & 02) {
192 l ^= b << 31;
193 h ^= b >> 1;
194 }
157 195
158 if (top2b & 01) { l ^= b << 30; h ^= b >> 2; } 196 *r1 = h;
159 if (top2b & 02) { l ^= b << 31; h ^= b >> 1; } 197 *r0 = l;
160
161 *r1 = h; *r0 = l;
162#else 198#else
163 register BN_ULONG h, l, s; 199 register BN_ULONG h, l, s;
164 BN_ULONG tab[16], top3b = a >> 61; 200 BN_ULONG tab[16], top3b = a >> 61;
165 register BN_ULONG a1, a2, a4, a8; 201 register BN_ULONG a1, a2, a4, a8;
166 202
167 a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1; 203 a1 = a & (0x1FFFFFFFFFFFFFFFULL);
168 204 a2 = a1 << 1;
169 tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2; 205 a4 = a2 << 1;
170 tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4; 206 a8 = a4 << 1;
171 tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8; 207
172 tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8; 208 tab[0] = 0;
173 209 tab[1] = a1;
174 s = tab[b & 0xF]; l = s; 210 tab[2] = a2;
175 s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60; 211 tab[3] = a1 ^ a2;
176 s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56; 212 tab[4] = a4;
177 s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52; 213 tab[5] = a1 ^ a4;
178 s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48; 214 tab[6] = a2 ^ a4;
179 s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44; 215 tab[7] = a1 ^ a2 ^ a4;
180 s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40; 216 tab[8] = a8;
181 s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36; 217 tab[9] = a1 ^ a8;
182 s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32; 218 tab[10] = a2 ^ a8;
183 s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28; 219 tab[11] = a1 ^ a2 ^ a8;
184 s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24; 220 tab[12] = a4 ^ a8;
185 s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20; 221 tab[13] = a1 ^ a4 ^ a8;
186 s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16; 222 tab[14] = a2 ^ a4 ^ a8;
187 s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12; 223 tab[15] = a1 ^ a2 ^ a4 ^ a8;
188 s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8; 224
189 s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4; 225 s = tab[b & 0xF];
226 l = s;
227 s = tab[b >> 4 & 0xF];
228 l ^= s << 4;
229 h = s >> 60;
230 s = tab[b >> 8 & 0xF];
231 l ^= s << 8;
232 h ^= s >> 56;
233 s = tab[b >> 12 & 0xF];
234 l ^= s << 12;
235 h ^= s >> 52;
236 s = tab[b >> 16 & 0xF];
237 l ^= s << 16;
238 h ^= s >> 48;
239 s = tab[b >> 20 & 0xF];
240 l ^= s << 20;
241 h ^= s >> 44;
242 s = tab[b >> 24 & 0xF];
243 l ^= s << 24;
244 h ^= s >> 40;
245 s = tab[b >> 28 & 0xF];
246 l ^= s << 28;
247 h ^= s >> 36;
248 s = tab[b >> 32 & 0xF];
249 l ^= s << 32;
250 h ^= s >> 32;
251 s = tab[b >> 36 & 0xF];
252 l ^= s << 36;
253 h ^= s >> 28;
254 s = tab[b >> 40 & 0xF];
255 l ^= s << 40;
256 h ^= s >> 24;
257 s = tab[b >> 44 & 0xF];
258 l ^= s << 44;
259 h ^= s >> 20;
260 s = tab[b >> 48 & 0xF];
261 l ^= s << 48;
262 h ^= s >> 16;
263 s = tab[b >> 52 & 0xF];
264 l ^= s << 52;
265 h ^= s >> 12;
266 s = tab[b >> 56 & 0xF];
267 l ^= s << 56;
268 h ^= s >> 8;
269 s = tab[b >> 60];
270 l ^= s << 60;
271 h ^= s >> 4;
190 272
191 /* compensate for the top three bits of a */ 273 /* compensate for the top three bits of a */
274 if (top3b & 01) {
275 l ^= b << 61;
276 h ^= b >> 3;
277 }
278 if (top3b & 02) {
279 l ^= b << 62;
280 h ^= b >> 2;
281 }
282 if (top3b & 04) {
283 l ^= b << 63;
284 h ^= b >> 1;
285 }
192 286
193 if (top3b & 01) { l ^= b << 61; h ^= b >> 3; } 287 *r1 = h;
194 if (top3b & 02) { l ^= b << 62; h ^= b >> 2; } 288 *r0 = l;
195 if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
196
197 *r1 = h; *r0 = l;
198#endif 289#endif
199 } 290}
200 291
201/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1, 292/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
202 * result is a polynomial r with degree < 4 * BN_BITS2 - 1 293 * result is a polynomial r with degree < 4 * BN_BITS2 - 1
203 * The caller MUST ensure that the variables have the right amount 294 * The caller MUST ensure that the variables have the right amount
204 * of space allocated. 295 * of space allocated.
205 */ 296 */
206static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, const BN_ULONG b1, const BN_ULONG b0) 297static void
207 { 298bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0,
299 const BN_ULONG b1, const BN_ULONG b0)
300{
208 BN_ULONG m1, m0; 301 BN_ULONG m1, m0;
302
209 /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ 303 /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
210 bn_GF2m_mul_1x1(r+3, r+2, a1, b1); 304 bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1);
211 bn_GF2m_mul_1x1(r+1, r, a0, b0); 305 bn_GF2m_mul_1x1(r + 1, r, a0, b0);
212 bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); 306 bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
213 /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ 307 /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
214 r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ 308 r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
215 r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ 309 r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
216 } 310}
217#else 311#else
218void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0); 312void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
219#endif 313 BN_ULONG b0);
314#endif
220 315
221/* Add polynomials a and b and store result in r; r could be a or b, a and b 316/* Add polynomials a and b and store result in r; r could be a or b, a and b
222 * could be equal; r is the bitwise XOR of a and b. 317 * could be equal; r is the bitwise XOR of a and b.
223 */ 318 */
224int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 319int
225 { 320BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
321{
226 int i; 322 int i;
227 const BIGNUM *at, *bt; 323 const BIGNUM *at, *bt;
228 324
229 bn_check_top(a); 325 bn_check_top(a);
230 bn_check_top(b); 326 bn_check_top(b);
231 327
232 if (a->top < b->top) { at = b; bt = a; } 328 if (a->top < b->top) {
233 else { at = a; bt = b; } 329 at = b;
330 bt = a;
331 } else {
332 at = a;
333 bt = b;
334 }
234 335
235 if(bn_wexpand(r, at->top) == NULL) 336 if (bn_wexpand(r, at->top) == NULL)
236 return 0; 337 return 0;
237 338
238 for (i = 0; i < bt->top; i++) 339 for (i = 0; i < bt->top; i++) {
239 {
240 r->d[i] = at->d[i] ^ bt->d[i]; 340 r->d[i] = at->d[i] ^ bt->d[i];
241 } 341 }
242 for (; i < at->top; i++) 342 for (; i < at->top; i++) {
243 {
244 r->d[i] = at->d[i]; 343 r->d[i] = at->d[i];
245 } 344 }
246 345
247 r->top = at->top; 346 r->top = at->top;
248 bn_correct_top(r); 347 bn_correct_top(r);
249 348
250 return 1; 349 return 1;
251 } 350}
252 351
253 352
254/* Some functions allow for representation of the irreducible polynomials 353/* Some functions allow for representation of the irreducible polynomials
@@ -259,70 +358,73 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
259 358
260 359
261/* Performs modular reduction of a and store result in r. r could be a. */ 360/* Performs modular reduction of a and store result in r. r could be a. */
262int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) 361int
263 { 362BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
363{
264 int j, k; 364 int j, k;
265 int n, dN, d0, d1; 365 int n, dN, d0, d1;
266 BN_ULONG zz, *z; 366 BN_ULONG zz, *z;
267 367
268 bn_check_top(a); 368 bn_check_top(a);
269 369
270 if (!p[0]) 370 if (!p[0]) {
271 {
272 /* reduction mod 1 => return 0 */ 371 /* reduction mod 1 => return 0 */
273 BN_zero(r); 372 BN_zero(r);
274 return 1; 373 return 1;
275 } 374 }
276 375
277 /* Since the algorithm does reduction in the r value, if a != r, copy 376 /* Since the algorithm does reduction in the r value, if a != r, copy
278 * the contents of a into r so we can do reduction in r. 377 * the contents of a into r so we can do reduction in r.
279 */ 378 */
280 if (a != r) 379 if (a != r) {
281 { 380 if (!bn_wexpand(r, a->top))
282 if (!bn_wexpand(r, a->top)) return 0; 381 return 0;
283 for (j = 0; j < a->top; j++) 382 for (j = 0; j < a->top; j++) {
284 {
285 r->d[j] = a->d[j]; 383 r->d[j] = a->d[j];
286 }
287 r->top = a->top;
288 } 384 }
385 r->top = a->top;
386 }
289 z = r->d; 387 z = r->d;
290 388
291 /* start reduction */ 389 /* start reduction */
292 dN = p[0] / BN_BITS2; 390 dN = p[0] / BN_BITS2;
293 for (j = r->top - 1; j > dN;) 391 for (j = r->top - 1; j > dN; ) {
294 {
295 zz = z[j]; 392 zz = z[j];
296 if (z[j] == 0) { j--; continue; } 393 if (z[j] == 0) {
394 j--;
395 continue;
396 }
297 z[j] = 0; 397 z[j] = 0;
298 398
299 for (k = 1; p[k] != 0; k++) 399 for (k = 1; p[k] != 0; k++) {
300 {
301 /* reducing component t^p[k] */ 400 /* reducing component t^p[k] */
302 n = p[0] - p[k]; 401 n = p[0] - p[k];
303 d0 = n % BN_BITS2; d1 = BN_BITS2 - d0; 402 d0 = n % BN_BITS2;
304 n /= BN_BITS2; 403 d1 = BN_BITS2 - d0;
305 z[j-n] ^= (zz>>d0); 404 n /= BN_BITS2;
306 if (d0) z[j-n-1] ^= (zz<<d1); 405 z[j - n] ^= (zz >> d0);
307 } 406 if (d0)
407 z[j - n - 1] ^= (zz << d1);
408 }
308 409
309 /* reducing component t^0 */ 410 /* reducing component t^0 */
310 n = dN; 411 n = dN;
311 d0 = p[0] % BN_BITS2; 412 d0 = p[0] % BN_BITS2;
312 d1 = BN_BITS2 - d0; 413 d1 = BN_BITS2 - d0;
313 z[j-n] ^= (zz >> d0); 414 z[j - n] ^= (zz >> d0);
314 if (d0) z[j-n-1] ^= (zz << d1); 415 if (d0)
315 } 416 z[j - n - 1] ^= (zz << d1);
417 }
316 418
317 /* final round of reduction */ 419 /* final round of reduction */
318 while (j == dN) 420 while (j == dN) {
319 {
320 421
321 d0 = p[0] % BN_BITS2; 422 d0 = p[0] % BN_BITS2;
322 zz = z[dN] >> d0; 423 zz = z[dN] >> d0;
323 if (zz == 0) break; 424 if (zz == 0)
425 break;
324 d1 = BN_BITS2 - d0; 426 d1 = BN_BITS2 - d0;
325 427
326 /* clear up the top d1 bits */ 428 /* clear up the top d1 bits */
327 if (d0) 429 if (d0)
328 z[dN] = (z[dN] << d1) >> d1; 430 z[dN] = (z[dN] << d1) >> d1;
@@ -330,56 +432,58 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
330 z[dN] = 0; 432 z[dN] = 0;
331 z[0] ^= zz; /* reduction t^0 component */ 433 z[0] ^= zz; /* reduction t^0 component */
332 434
333 for (k = 1; p[k] != 0; k++) 435 for (k = 1; p[k] != 0; k++) {
334 {
335 BN_ULONG tmp_ulong; 436 BN_ULONG tmp_ulong;
336 437
337 /* reducing component t^p[k]*/ 438 /* reducing component t^p[k]*/
338 n = p[k] / BN_BITS2; 439 n = p[k] / BN_BITS2;
339 d0 = p[k] % BN_BITS2; 440 d0 = p[k] % BN_BITS2;
340 d1 = BN_BITS2 - d0; 441 d1 = BN_BITS2 - d0;
341 z[n] ^= (zz << d0); 442 z[n] ^= (zz << d0);
342 tmp_ulong = zz >> d1; 443 tmp_ulong = zz >> d1;
343 if (d0 && tmp_ulong) 444 if (d0 && tmp_ulong)
344 z[n+1] ^= tmp_ulong; 445 z[n + 1] ^= tmp_ulong;
345 }
346
347
348 } 446 }
349 447
448
449 }
450
350 bn_correct_top(r); 451 bn_correct_top(r);
351 return 1; 452 return 1;
352 } 453}
353 454
354/* Performs modular reduction of a by p and store result in r. r could be a. 455/* Performs modular reduction of a by p and store result in r. r could be a.
355 * 456 *
356 * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper 457 * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
357 * function is only provided for convenience; for best performance, use the 458 * function is only provided for convenience; for best performance, use the
358 * BN_GF2m_mod_arr function. 459 * BN_GF2m_mod_arr function.
359 */ 460 */
360int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) 461int
361 { 462BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
463{
362 int ret = 0; 464 int ret = 0;
363 int arr[6]; 465 int arr[6];
466
364 bn_check_top(a); 467 bn_check_top(a);
365 bn_check_top(p); 468 bn_check_top(p);
366 ret = BN_GF2m_poly2arr(p, arr, sizeof(arr)/sizeof(arr[0])); 469 ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0]));
367 if (!ret || ret > (int)(sizeof(arr)/sizeof(arr[0]))) 470 if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) {
368 { 471 BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
369 BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
370 return 0; 472 return 0;
371 } 473 }
372 ret = BN_GF2m_mod_arr(r, a, arr); 474 ret = BN_GF2m_mod_arr(r, a, arr);
373 bn_check_top(r); 475 bn_check_top(r);
374 return ret; 476 return ret;
375 } 477}
376 478
377 479
378/* Compute the product of two polynomials a and b, reduce modulo p, and store 480/* Compute the product of two polynomials a and b, reduce modulo p, and store
379 * the result in r. r could be a or b; a could be b. 481 * the result in r. r could be a or b; a could be b.
380 */ 482 */
381int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx) 483int
382 { 484BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[],
485 BN_CTX *ctx)
486{
383 int zlen, i, j, k, ret = 0; 487 int zlen, i, j, k, ret = 0;
384 BIGNUM *s; 488 BIGNUM *s;
385 BN_ULONG x1, x0, y1, y0, zz[4]; 489 BN_ULONG x1, x0, y1, y0, zz[4];
@@ -387,32 +491,33 @@ int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p
387 bn_check_top(a); 491 bn_check_top(a);
388 bn_check_top(b); 492 bn_check_top(b);
389 493
390 if (a == b) 494 if (a == b) {
391 {
392 return BN_GF2m_mod_sqr_arr(r, a, p, ctx); 495 return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
393 } 496 }
394 497
395 BN_CTX_start(ctx); 498 BN_CTX_start(ctx);
396 if ((s = BN_CTX_get(ctx)) == NULL) goto err; 499 if ((s = BN_CTX_get(ctx)) == NULL)
397 500 goto err;
501
398 zlen = a->top + b->top + 4; 502 zlen = a->top + b->top + 4;
399 if (!bn_wexpand(s, zlen)) goto err; 503 if (!bn_wexpand(s, zlen))
504 goto err;
400 s->top = zlen; 505 s->top = zlen;
401 506
402 for (i = 0; i < zlen; i++) s->d[i] = 0; 507 for (i = 0; i < zlen; i++)
508 s->d[i] = 0;
403 509
404 for (j = 0; j < b->top; j += 2) 510 for (j = 0; j < b->top; j += 2) {
405 {
406 y0 = b->d[j]; 511 y0 = b->d[j];
407 y1 = ((j+1) == b->top) ? 0 : b->d[j+1]; 512 y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1];
408 for (i = 0; i < a->top; i += 2) 513 for (i = 0; i < a->top; i += 2) {
409 {
410 x0 = a->d[i]; 514 x0 = a->d[i];
411 x1 = ((i+1) == a->top) ? 0 : a->d[i+1]; 515 x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1];
412 bn_GF2m_mul_2x2(zz, x1, x0, y1, y0); 516 bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
413 for (k = 0; k < 4; k++) s->d[i+j+k] ^= zz[k]; 517 for (k = 0; k < 4; k++)
414 } 518 s->d[i + j + k] ^= zz[k];
415 } 519 }
520 }
416 521
417 bn_correct_top(s); 522 bn_correct_top(s);
418 if (BN_GF2m_mod_arr(r, s, p)) 523 if (BN_GF2m_mod_arr(r, s, p))
@@ -422,101 +527,114 @@ int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p
422err: 527err:
423 BN_CTX_end(ctx); 528 BN_CTX_end(ctx);
424 return ret; 529 return ret;
425 } 530}
426 531
427/* Compute the product of two polynomials a and b, reduce modulo p, and store 532/* Compute the product of two polynomials a and b, reduce modulo p, and store
428 * the result in r. r could be a or b; a could equal b. 533 * the result in r. r could be a or b; a could equal b.
429 * 534 *
430 * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper 535 * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper
431 * function is only provided for convenience; for best performance, use the 536 * function is only provided for convenience; for best performance, use the
432 * BN_GF2m_mod_mul_arr function. 537 * BN_GF2m_mod_mul_arr function.
433 */ 538 */
434int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) 539int
435 { 540BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p,
541 BN_CTX *ctx)
542{
436 int ret = 0; 543 int ret = 0;
437 const int max = BN_num_bits(p) + 1; 544 const int max = BN_num_bits(p) + 1;
438 int *arr=NULL; 545 int *arr = NULL;
546
439 bn_check_top(a); 547 bn_check_top(a);
440 bn_check_top(b); 548 bn_check_top(b);
441 bn_check_top(p); 549 bn_check_top(p);
442 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL) goto err; 550 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL)
551 goto err;
443 ret = BN_GF2m_poly2arr(p, arr, max); 552 ret = BN_GF2m_poly2arr(p, arr, max);
444 if (!ret || ret > max) 553 if (!ret || ret > max) {
445 { 554 BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH);
446 BNerr(BN_F_BN_GF2M_MOD_MUL,BN_R_INVALID_LENGTH);
447 goto err; 555 goto err;
448 } 556 }
449 ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); 557 ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
450 bn_check_top(r); 558 bn_check_top(r);
559
451err: 560err:
452 if (arr) free(arr); 561 if (arr)
562 free(arr);
453 return ret; 563 return ret;
454 } 564}
455 565
456 566
457/* Square a, reduce the result mod p, and store it in a. r could be a. */ 567/* Square a, reduce the result mod p, and store it in a. r could be a. */
458int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx) 568int
459 { 569BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
570{
460 int i, ret = 0; 571 int i, ret = 0;
461 BIGNUM *s; 572 BIGNUM *s;
462 573
463 bn_check_top(a); 574 bn_check_top(a);
464 BN_CTX_start(ctx); 575 BN_CTX_start(ctx);
465 if ((s = BN_CTX_get(ctx)) == NULL) return 0; 576 if ((s = BN_CTX_get(ctx)) == NULL)
466 if (!bn_wexpand(s, 2 * a->top)) goto err; 577 return 0;
578 if (!bn_wexpand(s, 2 * a->top))
579 goto err;
467 580
468 for (i = a->top - 1; i >= 0; i--) 581 for (i = a->top - 1; i >= 0; i--) {
469 { 582 s->d[2 * i + 1] = SQR1(a->d[i]);
470 s->d[2*i+1] = SQR1(a->d[i]); 583 s->d[2 * i] = SQR0(a->d[i]);
471 s->d[2*i ] = SQR0(a->d[i]); 584 }
472 }
473 585
474 s->top = 2 * a->top; 586 s->top = 2 * a->top;
475 bn_correct_top(s); 587 bn_correct_top(s);
476 if (!BN_GF2m_mod_arr(r, s, p)) goto err; 588 if (!BN_GF2m_mod_arr(r, s, p))
589 goto err;
477 bn_check_top(r); 590 bn_check_top(r);
478 ret = 1; 591 ret = 1;
592
479err: 593err:
480 BN_CTX_end(ctx); 594 BN_CTX_end(ctx);
481 return ret; 595 return ret;
482 } 596}
483 597
484/* Square a, reduce the result mod p, and store it in a. r could be a. 598/* Square a, reduce the result mod p, and store it in a. r could be a.
485 * 599 *
486 * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper 600 * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper
487 * function is only provided for convenience; for best performance, use the 601 * function is only provided for convenience; for best performance, use the
488 * BN_GF2m_mod_sqr_arr function. 602 * BN_GF2m_mod_sqr_arr function.
489 */ 603 */
490int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 604int
491 { 605BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
606{
492 int ret = 0; 607 int ret = 0;
493 const int max = BN_num_bits(p) + 1; 608 const int max = BN_num_bits(p) + 1;
494 int *arr=NULL; 609 int *arr = NULL;
495 610
496 bn_check_top(a); 611 bn_check_top(a);
497 bn_check_top(p); 612 bn_check_top(p);
498 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL) goto err; 613 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL)
614 goto err;
499 ret = BN_GF2m_poly2arr(p, arr, max); 615 ret = BN_GF2m_poly2arr(p, arr, max);
500 if (!ret || ret > max) 616 if (!ret || ret > max) {
501 { 617 BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
502 BNerr(BN_F_BN_GF2M_MOD_SQR,BN_R_INVALID_LENGTH);
503 goto err; 618 goto err;
504 } 619 }
505 ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); 620 ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
506 bn_check_top(r); 621 bn_check_top(r);
622
507err: 623err:
508 if (arr) free(arr); 624 if (arr)
625 free(arr);
509 return ret; 626 return ret;
510 } 627}
511 628
512 629
513/* Invert a, reduce modulo p, and store the result in r. r could be a. 630/* Invert a, reduce modulo p, and store the result in r. r could be a.
514 * Uses Modified Almost Inverse Algorithm (Algorithm 10) from 631 * Uses Modified Almost Inverse Algorithm (Algorithm 10) from
515 * Hankerson, D., Hernandez, J.L., and Menezes, A. "Software Implementation 632 * Hankerson, D., Hernandez, J.L., and Menezes, A. "Software Implementation
516 * of Elliptic Curve Cryptography Over Binary Fields". 633 * of Elliptic Curve Cryptography Over Binary Fields".
517 */ 634 */
518int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 635int
519 { 636BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
637{
520 BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp; 638 BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
521 int ret = 0; 639 int ret = 0;
522 640
@@ -524,161 +642,194 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
524 bn_check_top(p); 642 bn_check_top(p);
525 643
526 BN_CTX_start(ctx); 644 BN_CTX_start(ctx);
527
528 if ((b = BN_CTX_get(ctx))==NULL) goto err;
529 if ((c = BN_CTX_get(ctx))==NULL) goto err;
530 if ((u = BN_CTX_get(ctx))==NULL) goto err;
531 if ((v = BN_CTX_get(ctx))==NULL) goto err;
532 645
533 if (!BN_GF2m_mod(u, a, p)) goto err; 646 if ((b = BN_CTX_get(ctx)) == NULL)
534 if (BN_is_zero(u)) goto err; 647 goto err;
648 if ((c = BN_CTX_get(ctx)) == NULL)
649 goto err;
650 if ((u = BN_CTX_get(ctx)) == NULL)
651 goto err;
652 if ((v = BN_CTX_get(ctx)) == NULL)
653 goto err;
535 654
536 if (!BN_copy(v, p)) goto err; 655 if (!BN_GF2m_mod(u, a, p))
656 goto err;
657 if (BN_is_zero(u))
658 goto err;
659
660 if (!BN_copy(v, p))
661 goto err;
537#if 0 662#if 0
538 if (!BN_one(b)) goto err; 663 if (!BN_one(b))
539 664 goto err;
540 while (1) 665
541 { 666 while (1) {
542 while (!BN_is_odd(u)) 667 while (!BN_is_odd(u)) {
543 { 668 if (BN_is_zero(u))
544 if (BN_is_zero(u)) goto err; 669 goto err;
545 if (!BN_rshift1(u, u)) goto err; 670 if (!BN_rshift1(u, u))
546 if (BN_is_odd(b)) 671 goto err;
547 { 672 if (BN_is_odd(b)) {
548 if (!BN_GF2m_add(b, b, p)) goto err; 673 if (!BN_GF2m_add(b, b, p))
549 } 674 goto err;
550 if (!BN_rshift1(b, b)) goto err;
551 } 675 }
676 if (!BN_rshift1(b, b))
677 goto err;
678 }
552 679
553 if (BN_abs_is_word(u, 1)) break; 680 if (BN_abs_is_word(u, 1))
681 break;
554 682
555 if (BN_num_bits(u) < BN_num_bits(v)) 683 if (BN_num_bits(u) < BN_num_bits(v)) {
556 { 684 tmp = u;
557 tmp = u; u = v; v = tmp; 685 u = v;
558 tmp = b; b = c; c = tmp; 686 v = tmp;
559 } 687 tmp = b;
560 688 b = c;
561 if (!BN_GF2m_add(u, u, v)) goto err; 689 c = tmp;
562 if (!BN_GF2m_add(b, b, c)) goto err;
563 } 690 }
691
692 if (!BN_GF2m_add(u, u, v))
693 goto err;
694 if (!BN_GF2m_add(b, b, c))
695 goto err;
696 }
564#else 697#else
565 { 698 {
566 int i, ubits = BN_num_bits(u), 699 int i, ubits = BN_num_bits(u),
567 vbits = BN_num_bits(v), /* v is copy of p */ 700 vbits = BN_num_bits(v), /* v is copy of p */
568 top = p->top; 701 top = p->top;
569 BN_ULONG *udp,*bdp,*vdp,*cdp; 702 BN_ULONG *udp, *bdp, *vdp, *cdp;
570 703
571 bn_wexpand(u,top); udp = u->d; 704 bn_wexpand(u, top);
572 for (i=u->top;i<top;i++) udp[i] = 0; 705 udp = u->d;
573 u->top = top; 706 for (i = u->top; i < top; i++)
574 bn_wexpand(b,top); bdp = b->d; 707 udp[i] = 0;
575 bdp[0] = 1; 708 u->top = top;
576 for (i=1;i<top;i++) bdp[i] = 0; 709 bn_wexpand(b, top);
577 b->top = top; 710 bdp = b->d;
578 bn_wexpand(c,top); cdp = c->d; 711 bdp[0] = 1;
579 for (i=0;i<top;i++) cdp[i] = 0; 712 for (i = 1; i < top; i++)
580 c->top = top; 713 bdp[i] = 0;
581 vdp = v->d; /* It pays off to "cache" *->d pointers, because 714 b->top = top;
582 * it allows optimizer to be more aggressive. 715 bn_wexpand(c, top);
583 * But we don't have to "cache" p->d, because *p 716 cdp = c->d;
584 * is declared 'const'... */ 717 for (i = 0; i < top; i++)
585 while (1) 718 cdp[i] = 0;
586 { 719 c->top = top;
587 while (ubits && !(udp[0]&1)) 720 vdp = v->d; /* It pays off to "cache" *->d pointers, because
588 { 721 * it allows optimizer to be more aggressive.
589 BN_ULONG u0,u1,b0,b1,mask; 722 * But we don't have to "cache" p->d, because *p
590 723 * is declared 'const'... */
591 u0 = udp[0]; 724 while (1) {
592 b0 = bdp[0]; 725 while (ubits && !(udp[0]&1)) {
593 mask = (BN_ULONG)0-(b0&1); 726 BN_ULONG u0, u1, b0, b1, mask;
594 b0 ^= p->d[0]&mask; 727
595 for (i=0;i<top-1;i++) 728 u0 = udp[0];
596 { 729 b0 = bdp[0];
597 u1 = udp[i+1]; 730 mask = (BN_ULONG)0 - (b0 & 1);
598 udp[i] = ((u0>>1)|(u1<<(BN_BITS2-1)))&BN_MASK2; 731 b0 ^= p->d[0] & mask;
599 u0 = u1; 732 for (i = 0; i < top - 1; i++) {
600 b1 = bdp[i+1]^(p->d[i+1]&mask); 733 u1 = udp[i + 1];
601 bdp[i] = ((b0>>1)|(b1<<(BN_BITS2-1)))&BN_MASK2; 734 udp[i] = ((u0 >> 1) |
602 b0 = b1; 735 (u1 << (BN_BITS2 - 1))) & BN_MASK2;
736 u0 = u1;
737 b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
738 bdp[i] = ((b0 >> 1) |
739 (b1 << (BN_BITS2 - 1))) & BN_MASK2;
740 b0 = b1;
603 } 741 }
604 udp[i] = u0>>1; 742 udp[i] = u0 >> 1;
605 bdp[i] = b0>>1; 743 bdp[i] = b0 >> 1;
606 ubits--; 744 ubits--;
607 } 745 }
608 746
609 if (ubits<=BN_BITS2 && udp[0]==1) break; 747 if (ubits <= BN_BITS2 && udp[0] == 1)
610 748 break;
611 if (ubits<vbits) 749
612 { 750 if (ubits < vbits) {
613 i = ubits; ubits = vbits; vbits = i; 751 i = ubits;
614 tmp = u; u = v; v = tmp; 752 ubits = vbits;
615 tmp = b; b = c; c = tmp; 753 vbits = i;
616 udp = vdp; vdp = v->d; 754 tmp = u;
617 bdp = cdp; cdp = c->d; 755 u = v;
756 v = tmp;
757 tmp = b;
758 b = c;
759 c = tmp;
760 udp = vdp;
761 vdp = v->d;
762 bdp = cdp;
763 cdp = c->d;
618 } 764 }
619 for(i=0;i<top;i++) 765 for (i = 0; i < top; i++) {
620 { 766 udp[i] ^= vdp[i];
621 udp[i] ^= vdp[i]; 767 bdp[i] ^= cdp[i];
622 bdp[i] ^= cdp[i];
623 } 768 }
624 if (ubits==vbits) 769 if (ubits == vbits) {
625 { 770 BN_ULONG ul;
626 BN_ULONG ul; 771 int utop = (ubits - 1) / BN_BITS2;
627 int utop = (ubits-1)/BN_BITS2;
628 772
629 while ((ul=udp[utop])==0 && utop) utop--; 773 while ((ul = udp[utop]) == 0 && utop)
630 ubits = utop*BN_BITS2 + BN_num_bits_word(ul); 774 utop--;
775 ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
631 } 776 }
632 } 777 }
633 bn_correct_top(b); 778 bn_correct_top(b);
634 } 779 }
635#endif 780#endif
636 781
637 if (!BN_copy(r, b)) goto err; 782 if (!BN_copy(r, b))
783 goto err;
638 bn_check_top(r); 784 bn_check_top(r);
639 ret = 1; 785 ret = 1;
640 786
641err: 787err:
642#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */ 788#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */
643 bn_correct_top(c); 789 bn_correct_top(c);
644 bn_correct_top(u); 790 bn_correct_top(u);
645 bn_correct_top(v); 791 bn_correct_top(v);
646#endif 792#endif
647 BN_CTX_end(ctx); 793 BN_CTX_end(ctx);
648 return ret; 794 return ret;
649 } 795}
650 796
651/* Invert xx, reduce modulo p, and store the result in r. r could be xx. 797/* Invert xx, reduce modulo p, and store the result in r. r could be xx.
652 * 798 *
653 * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper 799 * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper
654 * function is only provided for convenience; for best performance, use the 800 * function is only provided for convenience; for best performance, use the
655 * BN_GF2m_mod_inv function. 801 * BN_GF2m_mod_inv function.
656 */ 802 */
657int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx) 803int
658 { 804BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], BN_CTX *ctx)
805{
659 BIGNUM *field; 806 BIGNUM *field;
660 int ret = 0; 807 int ret = 0;
661 808
662 bn_check_top(xx); 809 bn_check_top(xx);
663 BN_CTX_start(ctx); 810 BN_CTX_start(ctx);
664 if ((field = BN_CTX_get(ctx)) == NULL) goto err; 811 if ((field = BN_CTX_get(ctx)) == NULL)
665 if (!BN_GF2m_arr2poly(p, field)) goto err; 812 goto err;
666 813 if (!BN_GF2m_arr2poly(p, field))
814 goto err;
815
667 ret = BN_GF2m_mod_inv(r, xx, field, ctx); 816 ret = BN_GF2m_mod_inv(r, xx, field, ctx);
668 bn_check_top(r); 817 bn_check_top(r);
669 818
670err: 819err:
671 BN_CTX_end(ctx); 820 BN_CTX_end(ctx);
672 return ret; 821 return ret;
673 } 822}
674 823
675 824
676#ifndef OPENSSL_SUN_GF2M_DIV 825#ifndef OPENSSL_SUN_GF2M_DIV
677/* Divide y by x, reduce modulo p, and store the result in r. r could be x 826/* Divide y by x, reduce modulo p, and store the result in r. r could be x
678 * or y, x could equal y. 827 * or y, x could equal y.
679 */ 828 */
680int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx) 829int
681 { 830BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p,
831 BN_CTX *ctx)
832{
682 BIGNUM *xinv = NULL; 833 BIGNUM *xinv = NULL;
683 int ret = 0; 834 int ret = 0;
684 835
@@ -688,26 +839,31 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
688 839
689 BN_CTX_start(ctx); 840 BN_CTX_start(ctx);
690 xinv = BN_CTX_get(ctx); 841 xinv = BN_CTX_get(ctx);
691 if (xinv == NULL) goto err; 842 if (xinv == NULL)
692 843 goto err;
693 if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err; 844
694 if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err; 845 if (!BN_GF2m_mod_inv(xinv, x, p, ctx))
846 goto err;
847 if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx))
848 goto err;
695 bn_check_top(r); 849 bn_check_top(r);
696 ret = 1; 850 ret = 1;
697 851
698err: 852err:
699 BN_CTX_end(ctx); 853 BN_CTX_end(ctx);
700 return ret; 854 return ret;
701 } 855}
702#else 856#else
703/* Divide y by x, reduce modulo p, and store the result in r. r could be x 857/* Divide y by x, reduce modulo p, and store the result in r. r could be x
704 * or y, x could equal y. 858 * or y, x could equal y.
705 * Uses algorithm Modular_Division_GF(2^m) from 859 * Uses algorithm Modular_Division_GF(2^m) from
706 * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to 860 * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to
707 * the Great Divide". 861 * the Great Divide".
708 */ 862 */
709int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx) 863int
710 { 864BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p,
865 BN_CTX *ctx)
866{
711 BIGNUM *a, *b, *u, *v; 867 BIGNUM *a, *b, *u, *v;
712 int ret = 0; 868 int ret = 0;
713 869
@@ -716,72 +872,88 @@ int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p
716 bn_check_top(p); 872 bn_check_top(p);
717 873
718 BN_CTX_start(ctx); 874 BN_CTX_start(ctx);
719 875
720 a = BN_CTX_get(ctx); 876 a = BN_CTX_get(ctx);
721 b = BN_CTX_get(ctx); 877 b = BN_CTX_get(ctx);
722 u = BN_CTX_get(ctx); 878 u = BN_CTX_get(ctx);
723 v = BN_CTX_get(ctx); 879 v = BN_CTX_get(ctx);
724 if (v == NULL) goto err; 880 if (v == NULL)
881 goto err;
725 882
726 /* reduce x and y mod p */ 883 /* reduce x and y mod p */
727 if (!BN_GF2m_mod(u, y, p)) goto err; 884 if (!BN_GF2m_mod(u, y, p))
728 if (!BN_GF2m_mod(a, x, p)) goto err; 885 goto err;
729 if (!BN_copy(b, p)) goto err; 886 if (!BN_GF2m_mod(a, x, p))
730 887 goto err;
731 while (!BN_is_odd(a)) 888 if (!BN_copy(b, p))
732 { 889 goto err;
733 if (!BN_rshift1(a, a)) goto err;
734 if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
735 if (!BN_rshift1(u, u)) goto err;
736 }
737 890
738 do 891 while (!BN_is_odd(a)) {
739 { 892 if (!BN_rshift1(a, a))
740 if (BN_GF2m_cmp(b, a) > 0) 893 goto err;
741 { 894 if (BN_is_odd(u))
742 if (!BN_GF2m_add(b, b, a)) goto err; 895 if (!BN_GF2m_add(u, u, p))
743 if (!BN_GF2m_add(v, v, u)) goto err; 896 goto err;
744 do 897 if (!BN_rshift1(u, u))
745 { 898 goto err;
746 if (!BN_rshift1(b, b)) goto err; 899 }
747 if (BN_is_odd(v)) if (!BN_GF2m_add(v, v, p)) goto err; 900
748 if (!BN_rshift1(v, v)) goto err; 901 do {
749 } while (!BN_is_odd(b)); 902 if (BN_GF2m_cmp(b, a) > 0) {
750 } 903 if (!BN_GF2m_add(b, b, a))
751 else if (BN_abs_is_word(a, 1)) 904 goto err;
905 if (!BN_GF2m_add(v, v, u))
906 goto err;
907 do {
908 if (!BN_rshift1(b, b))
909 goto err;
910 if (BN_is_odd(v))
911 if (!BN_GF2m_add(v, v, p))
912 goto err;
913 if (!BN_rshift1(v, v))
914 goto err;
915 } while (!BN_is_odd(b));
916 } else if (BN_abs_is_word(a, 1))
752 break; 917 break;
753 else 918 else {
754 { 919 if (!BN_GF2m_add(a, a, b))
755 if (!BN_GF2m_add(a, a, b)) goto err; 920 goto err;
756 if (!BN_GF2m_add(u, u, v)) goto err; 921 if (!BN_GF2m_add(u, u, v))
757 do 922 goto err;
758 { 923 do {
759 if (!BN_rshift1(a, a)) goto err; 924 if (!BN_rshift1(a, a))
760 if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err; 925 goto err;
761 if (!BN_rshift1(u, u)) goto err; 926 if (BN_is_odd(u))
762 } while (!BN_is_odd(a)); 927 if (!BN_GF2m_add(u, u, p))
763 } 928 goto err;
764 } while (1); 929 if (!BN_rshift1(u, u))
930 goto err;
931 } while (!BN_is_odd(a));
932 }
933 } while (1);
765 934
766 if (!BN_copy(r, u)) goto err; 935 if (!BN_copy(r, u))
936 goto err;
767 bn_check_top(r); 937 bn_check_top(r);
768 ret = 1; 938 ret = 1;
769 939
770err: 940err:
771 BN_CTX_end(ctx); 941 BN_CTX_end(ctx);
772 return ret; 942 return ret;
773 } 943}
774#endif 944#endif
775 945
776/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx 946/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
777 * or yy, xx could equal yy. 947 * or yy, xx could equal yy.
778 * 948 *
779 * This function calls down to the BN_GF2m_mod_div implementation; this wrapper 949 * This function calls down to the BN_GF2m_mod_div implementation; this wrapper
780 * function is only provided for convenience; for best performance, use the 950 * function is only provided for convenience; for best performance, use the
781 * BN_GF2m_mod_div function. 951 * BN_GF2m_mod_div function.
782 */ 952 */
783int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int p[], BN_CTX *ctx) 953int
784 { 954BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx,
955 const int p[], BN_CTX *ctx)
956{
785 BIGNUM *field; 957 BIGNUM *field;
786 int ret = 0; 958 int ret = 0;
787 959
@@ -789,24 +961,28 @@ int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const int
789 bn_check_top(xx); 961 bn_check_top(xx);
790 962
791 BN_CTX_start(ctx); 963 BN_CTX_start(ctx);
792 if ((field = BN_CTX_get(ctx)) == NULL) goto err; 964 if ((field = BN_CTX_get(ctx)) == NULL)
793 if (!BN_GF2m_arr2poly(p, field)) goto err; 965 goto err;
794 966 if (!BN_GF2m_arr2poly(p, field))
967 goto err;
968
795 ret = BN_GF2m_mod_div(r, yy, xx, field, ctx); 969 ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
796 bn_check_top(r); 970 bn_check_top(r);
797 971
798err: 972err:
799 BN_CTX_end(ctx); 973 BN_CTX_end(ctx);
800 return ret; 974 return ret;
801 } 975}
802 976
803 977
804/* Compute the bth power of a, reduce modulo p, and store 978/* Compute the bth power of a, reduce modulo p, and store
805 * the result in r. r could be a. 979 * the result in r. r could be a.
806 * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363. 980 * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
807 */ 981 */
808int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[], BN_CTX *ctx) 982int
809 { 983BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p[],
984 BN_CTX *ctx)
985{
810 int ret = 0, i, n; 986 int ret = 0, i, n;
811 BIGNUM *u; 987 BIGNUM *u;
812 988
@@ -814,202 +990,230 @@ int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const int p
814 bn_check_top(b); 990 bn_check_top(b);
815 991
816 if (BN_is_zero(b)) 992 if (BN_is_zero(b))
817 return(BN_one(r)); 993 return (BN_one(r));
818 994
819 if (BN_abs_is_word(b, 1)) 995 if (BN_abs_is_word(b, 1))
820 return (BN_copy(r, a) != NULL); 996 return (BN_copy(r, a) != NULL);
821 997
822 BN_CTX_start(ctx); 998 BN_CTX_start(ctx);
823 if ((u = BN_CTX_get(ctx)) == NULL) goto err; 999 if ((u = BN_CTX_get(ctx)) == NULL)
824 1000 goto err;
825 if (!BN_GF2m_mod_arr(u, a, p)) goto err; 1001
826 1002 if (!BN_GF2m_mod_arr(u, a, p))
1003 goto err;
1004
827 n = BN_num_bits(b) - 1; 1005 n = BN_num_bits(b) - 1;
828 for (i = n - 1; i >= 0; i--) 1006 for (i = n - 1; i >= 0; i--) {
829 { 1007 if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx))
830 if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) goto err; 1008 goto err;
831 if (BN_is_bit_set(b, i)) 1009 if (BN_is_bit_set(b, i)) {
832 { 1010 if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx))
833 if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) goto err; 1011 goto err;
834 }
835 } 1012 }
836 if (!BN_copy(r, u)) goto err; 1013 }
1014 if (!BN_copy(r, u))
1015 goto err;
837 bn_check_top(r); 1016 bn_check_top(r);
838 ret = 1; 1017 ret = 1;
1018
839err: 1019err:
840 BN_CTX_end(ctx); 1020 BN_CTX_end(ctx);
841 return ret; 1021 return ret;
842 } 1022}
843 1023
844/* Compute the bth power of a, reduce modulo p, and store 1024/* Compute the bth power of a, reduce modulo p, and store
845 * the result in r. r could be a. 1025 * the result in r. r could be a.
846 * 1026 *
847 * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper 1027 * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper
848 * function is only provided for convenience; for best performance, use the 1028 * function is only provided for convenience; for best performance, use the
849 * BN_GF2m_mod_exp_arr function. 1029 * BN_GF2m_mod_exp_arr function.
850 */ 1030 */
851int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) 1031int
852 { 1032BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p,
1033 BN_CTX *ctx)
1034{
853 int ret = 0; 1035 int ret = 0;
854 const int max = BN_num_bits(p) + 1; 1036 const int max = BN_num_bits(p) + 1;
855 int *arr=NULL; 1037 int *arr = NULL;
1038
856 bn_check_top(a); 1039 bn_check_top(a);
857 bn_check_top(b); 1040 bn_check_top(b);
858 bn_check_top(p); 1041 bn_check_top(p);
859 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL) goto err; 1042 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL)
1043 goto err;
860 ret = BN_GF2m_poly2arr(p, arr, max); 1044 ret = BN_GF2m_poly2arr(p, arr, max);
861 if (!ret || ret > max) 1045 if (!ret || ret > max) {
862 { 1046 BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH);
863 BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH);
864 goto err; 1047 goto err;
865 } 1048 }
866 ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); 1049 ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
867 bn_check_top(r); 1050 bn_check_top(r);
1051
868err: 1052err:
869 if (arr) free(arr); 1053 if (arr)
1054 free(arr);
870 return ret; 1055 return ret;
871 } 1056}
872 1057
873/* Compute the square root of a, reduce modulo p, and store 1058/* Compute the square root of a, reduce modulo p, and store
874 * the result in r. r could be a. 1059 * the result in r. r could be a.
875 * Uses exponentiation as in algorithm A.4.1 from IEEE P1363. 1060 * Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
876 */ 1061 */
877int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx) 1062int
878 { 1063BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], BN_CTX *ctx)
1064{
879 int ret = 0; 1065 int ret = 0;
880 BIGNUM *u; 1066 BIGNUM *u;
881 1067
882 bn_check_top(a); 1068 bn_check_top(a);
883 1069
884 if (!p[0]) 1070 if (!p[0]) {
885 {
886 /* reduction mod 1 => return 0 */ 1071 /* reduction mod 1 => return 0 */
887 BN_zero(r); 1072 BN_zero(r);
888 return 1; 1073 return 1;
889 } 1074 }
890 1075
891 BN_CTX_start(ctx); 1076 BN_CTX_start(ctx);
892 if ((u = BN_CTX_get(ctx)) == NULL) goto err; 1077 if ((u = BN_CTX_get(ctx)) == NULL)
893 1078 goto err;
894 if (!BN_set_bit(u, p[0] - 1)) goto err; 1079
1080 if (!BN_set_bit(u, p[0] - 1))
1081 goto err;
895 ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx); 1082 ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
896 bn_check_top(r); 1083 bn_check_top(r);
897 1084
898err: 1085err:
899 BN_CTX_end(ctx); 1086 BN_CTX_end(ctx);
900 return ret; 1087 return ret;
901 } 1088}
902 1089
903/* Compute the square root of a, reduce modulo p, and store 1090/* Compute the square root of a, reduce modulo p, and store
904 * the result in r. r could be a. 1091 * the result in r. r could be a.
905 * 1092 *
906 * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper 1093 * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper
907 * function is only provided for convenience; for best performance, use the 1094 * function is only provided for convenience; for best performance, use the
908 * BN_GF2m_mod_sqrt_arr function. 1095 * BN_GF2m_mod_sqrt_arr function.
909 */ 1096 */
910int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 1097int
911 { 1098BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
1099{
912 int ret = 0; 1100 int ret = 0;
913 const int max = BN_num_bits(p) + 1; 1101 const int max = BN_num_bits(p) + 1;
914 int *arr=NULL; 1102 int *arr = NULL;
915 bn_check_top(a); 1103 bn_check_top(a);
916 bn_check_top(p); 1104 bn_check_top(p);
917 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL) goto err; 1105 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL)
1106 goto err;
918 ret = BN_GF2m_poly2arr(p, arr, max); 1107 ret = BN_GF2m_poly2arr(p, arr, max);
919 if (!ret || ret > max) 1108 if (!ret || ret > max) {
920 { 1109 BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
921 BNerr(BN_F_BN_GF2M_MOD_SQRT,BN_R_INVALID_LENGTH);
922 goto err; 1110 goto err;
923 } 1111 }
924 ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); 1112 ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
925 bn_check_top(r); 1113 bn_check_top(r);
1114
926err: 1115err:
927 if (arr) free(arr); 1116 if (arr)
1117 free(arr);
928 return ret; 1118 return ret;
929 } 1119}
930 1120
931/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. 1121/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0.
932 * Uses algorithms A.4.7 and A.4.6 from IEEE P1363. 1122 * Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
933 */ 1123 */
934int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CTX *ctx) 1124int
935 { 1125BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[],
1126 BN_CTX *ctx)
1127{
936 int ret = 0, count = 0, j; 1128 int ret = 0, count = 0, j;
937 BIGNUM *a, *z, *rho, *w, *w2, *tmp; 1129 BIGNUM *a, *z, *rho, *w, *w2, *tmp;
938 1130
939 bn_check_top(a_); 1131 bn_check_top(a_);
940 1132
941 if (!p[0]) 1133 if (!p[0]) {
942 {
943 /* reduction mod 1 => return 0 */ 1134 /* reduction mod 1 => return 0 */
944 BN_zero(r); 1135 BN_zero(r);
945 return 1; 1136 return 1;
946 } 1137 }
947 1138
948 BN_CTX_start(ctx); 1139 BN_CTX_start(ctx);
949 a = BN_CTX_get(ctx); 1140 a = BN_CTX_get(ctx);
950 z = BN_CTX_get(ctx); 1141 z = BN_CTX_get(ctx);
951 w = BN_CTX_get(ctx); 1142 w = BN_CTX_get(ctx);
952 if (w == NULL) goto err; 1143 if (w == NULL)
1144 goto err;
953 1145
954 if (!BN_GF2m_mod_arr(a, a_, p)) goto err; 1146 if (!BN_GF2m_mod_arr(a, a_, p))
955 1147 goto err;
956 if (BN_is_zero(a)) 1148
957 { 1149 if (BN_is_zero(a)) {
958 BN_zero(r); 1150 BN_zero(r);
959 ret = 1; 1151 ret = 1;
960 goto err; 1152 goto err;
961 } 1153 }
962 1154
963 if (p[0] & 0x1) /* m is odd */ 1155 if (p[0] & 0x1) /* m is odd */
964 { 1156 {
965 /* compute half-trace of a */ 1157 /* compute half-trace of a */
966 if (!BN_copy(z, a)) goto err; 1158 if (!BN_copy(z, a))
967 for (j = 1; j <= (p[0] - 1) / 2; j++) 1159 goto err;
968 { 1160 for (j = 1; j <= (p[0] - 1) / 2; j++) {
969 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; 1161 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
970 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; 1162 goto err;
971 if (!BN_GF2m_add(z, z, a)) goto err; 1163 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
972 } 1164 goto err;
973 1165 if (!BN_GF2m_add(z, z, a))
1166 goto err;
974 } 1167 }
1168
1169 }
975 else /* m is even */ 1170 else /* m is even */
976 { 1171 {
977 rho = BN_CTX_get(ctx); 1172 rho = BN_CTX_get(ctx);
978 w2 = BN_CTX_get(ctx); 1173 w2 = BN_CTX_get(ctx);
979 tmp = BN_CTX_get(ctx); 1174 tmp = BN_CTX_get(ctx);
980 if (tmp == NULL) goto err; 1175 if (tmp == NULL)
981 do 1176 goto err;
982 { 1177 do {
983 if (!BN_rand(rho, p[0], 0, 0)) goto err; 1178 if (!BN_rand(rho, p[0], 0, 0))
984 if (!BN_GF2m_mod_arr(rho, rho, p)) goto err; 1179 goto err;
1180 if (!BN_GF2m_mod_arr(rho, rho, p))
1181 goto err;
985 BN_zero(z); 1182 BN_zero(z);
986 if (!BN_copy(w, rho)) goto err; 1183 if (!BN_copy(w, rho))
987 for (j = 1; j <= p[0] - 1; j++) 1184 goto err;
988 { 1185 for (j = 1; j <= p[0] - 1; j++) {
989 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; 1186 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
990 if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) goto err; 1187 goto err;
991 if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) goto err; 1188 if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx))
992 if (!BN_GF2m_add(z, z, tmp)) goto err; 1189 goto err;
993 if (!BN_GF2m_add(w, w2, rho)) goto err; 1190 if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx))
994 } 1191 goto err;
1192 if (!BN_GF2m_add(z, z, tmp))
1193 goto err;
1194 if (!BN_GF2m_add(w, w2, rho))
1195 goto err;
1196 }
995 count++; 1197 count++;
996 } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); 1198 } while (BN_is_zero(w) && (count < MAX_ITERATIONS));
997 if (BN_is_zero(w)) 1199 if (BN_is_zero(w)) {
998 { 1200 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,
999 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,BN_R_TOO_MANY_ITERATIONS); 1201 BN_R_TOO_MANY_ITERATIONS);
1000 goto err; 1202 goto err;
1001 }
1002 } 1203 }
1003 1204 }
1004 if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err; 1205
1005 if (!BN_GF2m_add(w, z, w)) goto err; 1206 if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx))
1006 if (BN_GF2m_cmp(w, a)) 1207 goto err;
1007 { 1208 if (!BN_GF2m_add(w, z, w))
1209 goto err;
1210 if (BN_GF2m_cmp(w, a)) {
1008 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); 1211 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
1009 goto err; 1212 goto err;
1010 } 1213 }
1011 1214
1012 if (!BN_copy(r, z)) goto err; 1215 if (!BN_copy(r, z))
1216 goto err;
1013 bn_check_top(r); 1217 bn_check_top(r);
1014 1218
1015 ret = 1; 1219 ret = 1;
@@ -1017,66 +1221,68 @@ int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], BN_CT
1017err: 1221err:
1018 BN_CTX_end(ctx); 1222 BN_CTX_end(ctx);
1019 return ret; 1223 return ret;
1020 } 1224}
1021 1225
1022/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. 1226/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0.
1023 * 1227 *
1024 * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper 1228 * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper
1025 * function is only provided for convenience; for best performance, use the 1229 * function is only provided for convenience; for best performance, use the
1026 * BN_GF2m_mod_solve_quad_arr function. 1230 * BN_GF2m_mod_solve_quad_arr function.
1027 */ 1231 */
1028int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 1232int
1029 { 1233BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
1234{
1030 int ret = 0; 1235 int ret = 0;
1031 const int max = BN_num_bits(p) + 1; 1236 const int max = BN_num_bits(p) + 1;
1032 int *arr=NULL; 1237 int *arr = NULL;
1238
1033 bn_check_top(a); 1239 bn_check_top(a);
1034 bn_check_top(p); 1240 bn_check_top(p);
1035 if ((arr = (int *)malloc(sizeof(int) * 1241 if ((arr = (int *)malloc(sizeof(int) * max)) == NULL)
1036 max)) == NULL) goto err; 1242 goto err;
1037 ret = BN_GF2m_poly2arr(p, arr, max); 1243 ret = BN_GF2m_poly2arr(p, arr, max);
1038 if (!ret || ret > max) 1244 if (!ret || ret > max) {
1039 { 1245 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH);
1040 BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD,BN_R_INVALID_LENGTH);
1041 goto err; 1246 goto err;
1042 } 1247 }
1043 ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); 1248 ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
1044 bn_check_top(r); 1249 bn_check_top(r);
1250
1045err: 1251err:
1046 if (arr) free(arr); 1252 if (arr)
1253 free(arr);
1047 return ret; 1254 return ret;
1048 } 1255}
1049 1256
1050/* Convert the bit-string representation of a polynomial 1257/* Convert the bit-string representation of a polynomial
1051 * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding 1258 * ( \sum_{i=0}^n a_i * x^i) into an array of integers corresponding
1052 * to the bits with non-zero coefficient. Array is terminated with -1. 1259 * to the bits with non-zero coefficient. Array is terminated with -1.
1053 * Up to max elements of the array will be filled. Return value is total 1260 * Up to max elements of the array will be filled. Return value is total
1054 * number of array elements that would be filled if array was large enough. 1261 * number of array elements that would be filled if array was large enough.
1055 */ 1262 */
1056int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) 1263int
1057 { 1264BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
1265{
1058 int i, j, k = 0; 1266 int i, j, k = 0;
1059 BN_ULONG mask; 1267 BN_ULONG mask;
1060 1268
1061 if (BN_is_zero(a)) 1269 if (BN_is_zero(a))
1062 return 0; 1270 return 0;
1063 1271
1064 for (i = a->top - 1; i >= 0; i--) 1272 for (i = a->top - 1; i >= 0; i--) {
1065 {
1066 if (!a->d[i]) 1273 if (!a->d[i])
1067 /* skip word if a->d[i] == 0 */ 1274 /* skip word if a->d[i] == 0 */
1068 continue; 1275 continue;
1069 mask = BN_TBIT; 1276 mask = BN_TBIT;
1070 for (j = BN_BITS2 - 1; j >= 0; j--) 1277 for (j = BN_BITS2 - 1; j >= 0; j--) {
1071 { 1278 if (a->d[i] & mask) {
1072 if (a->d[i] & mask) 1279 if (k < max)
1073 { 1280 p[k] = BN_BITS2 * i + j;
1074 if (k < max) p[k] = BN_BITS2 * i + j;
1075 k++; 1281 k++;
1076 }
1077 mask >>= 1;
1078 } 1282 }
1283 mask >>= 1;
1079 } 1284 }
1285 }
1080 1286
1081 if (k < max) { 1287 if (k < max) {
1082 p[k] = -1; 1288 p[k] = -1;
@@ -1084,25 +1290,25 @@ int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
1084 } 1290 }
1085 1291
1086 return k; 1292 return k;
1087 } 1293}
1088 1294
1089/* Convert the coefficient array representation of a polynomial to a 1295/* Convert the coefficient array representation of a polynomial to a
1090 * bit-string. The array must be terminated by -1. 1296 * bit-string. The array must be terminated by -1.
1091 */ 1297 */
1092int BN_GF2m_arr2poly(const int p[], BIGNUM *a) 1298int
1093 { 1299BN_GF2m_arr2poly(const int p[], BIGNUM *a)
1300{
1094 int i; 1301 int i;
1095 1302
1096 bn_check_top(a); 1303 bn_check_top(a);
1097 BN_zero(a); 1304 BN_zero(a);
1098 for (i = 0; p[i] != -1; i++) 1305 for (i = 0; p[i] != -1; i++) {
1099 {
1100 if (BN_set_bit(a, p[i]) == 0) 1306 if (BN_set_bit(a, p[i]) == 0)
1101 return 0; 1307 return 0;
1102 } 1308 }
1103 bn_check_top(a); 1309 bn_check_top(a);
1104 1310
1105 return 1; 1311 return 1;
1106 } 1312}
1107 1313
1108#endif 1314#endif