summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_gf2m.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_gf2m.c')
-rw-r--r--src/lib/libcrypto/bn/bn_gf2m.c114
1 files changed, 96 insertions, 18 deletions
diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c
index 432a3aa338..8a4dc20ad9 100644
--- a/src/lib/libcrypto/bn/bn_gf2m.c
+++ b/src/lib/libcrypto/bn/bn_gf2m.c
@@ -94,6 +94,8 @@
94#include "cryptlib.h" 94#include "cryptlib.h"
95#include "bn_lcl.h" 95#include "bn_lcl.h"
96 96
97#ifndef OPENSSL_NO_EC2M
98
97/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */ 99/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
98#define MAX_ITERATIONS 50 100#define MAX_ITERATIONS 50
99 101
@@ -122,6 +124,7 @@ static const BN_ULONG SQR_tb[16] =
122 SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] 124 SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
123#endif 125#endif
124 126
127#if !defined(OPENSSL_BN_ASM_GF2m)
125/* Product of two polynomials a, b each with degree < BN_BITS2 - 1, 128/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
126 * result is a polynomial r with degree < 2 * BN_BITS - 1 129 * result is a polynomial r with degree < 2 * BN_BITS - 1
127 * The caller MUST ensure that the variables have the right amount 130 * The caller MUST ensure that the variables have the right amount
@@ -216,7 +219,9 @@ static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, c
216 r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ 219 r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
217 r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ 220 r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
218 } 221 }
219 222#else
223void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
224#endif
220 225
221/* Add polynomials a and b and store result in r; r could be a or b, a and b 226/* 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. 227 * could be equal; r is the bitwise XOR of a and b.
@@ -360,21 +365,17 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
360int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) 365int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
361 { 366 {
362 int ret = 0; 367 int ret = 0;
363 const int max = BN_num_bits(p) + 1; 368 int arr[6];
364 int *arr=NULL;
365 bn_check_top(a); 369 bn_check_top(a);
366 bn_check_top(p); 370 bn_check_top(p);
367 if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; 371 ret = BN_GF2m_poly2arr(p, arr, sizeof(arr)/sizeof(arr[0]));
368 ret = BN_GF2m_poly2arr(p, arr, max); 372 if (!ret || ret > (int)(sizeof(arr)/sizeof(arr[0])))
369 if (!ret || ret > max)
370 { 373 {
371 BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH); 374 BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
372 goto err; 375 return 0;
373 } 376 }
374 ret = BN_GF2m_mod_arr(r, a, arr); 377 ret = BN_GF2m_mod_arr(r, a, arr);
375 bn_check_top(r); 378 bn_check_top(r);
376err:
377 if (arr) OPENSSL_free(arr);
378 return ret; 379 return ret;
379 } 380 }
380 381
@@ -521,7 +522,7 @@ err:
521 */ 522 */
522int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 523int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
523 { 524 {
524 BIGNUM *b, *c, *u, *v, *tmp; 525 BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
525 int ret = 0; 526 int ret = 0;
526 527
527 bn_check_top(a); 528 bn_check_top(a);
@@ -529,18 +530,18 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
529 530
530 BN_CTX_start(ctx); 531 BN_CTX_start(ctx);
531 532
532 b = BN_CTX_get(ctx); 533 if ((b = BN_CTX_get(ctx))==NULL) goto err;
533 c = BN_CTX_get(ctx); 534 if ((c = BN_CTX_get(ctx))==NULL) goto err;
534 u = BN_CTX_get(ctx); 535 if ((u = BN_CTX_get(ctx))==NULL) goto err;
535 v = BN_CTX_get(ctx); 536 if ((v = BN_CTX_get(ctx))==NULL) goto err;
536 if (v == NULL) goto err;
537 537
538 if (!BN_one(b)) goto err;
539 if (!BN_GF2m_mod(u, a, p)) goto err; 538 if (!BN_GF2m_mod(u, a, p)) goto err;
540 if (!BN_copy(v, p)) goto err;
541
542 if (BN_is_zero(u)) goto err; 539 if (BN_is_zero(u)) goto err;
543 540
541 if (!BN_copy(v, p)) goto err;
542#if 0
543 if (!BN_one(b)) goto err;
544
544 while (1) 545 while (1)
545 { 546 {
546 while (!BN_is_odd(u)) 547 while (!BN_is_odd(u))
@@ -565,13 +566,89 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
565 if (!BN_GF2m_add(u, u, v)) goto err; 566 if (!BN_GF2m_add(u, u, v)) goto err;
566 if (!BN_GF2m_add(b, b, c)) goto err; 567 if (!BN_GF2m_add(b, b, c)) goto err;
567 } 568 }
569#else
570 {
571 int i, ubits = BN_num_bits(u),
572 vbits = BN_num_bits(v), /* v is copy of p */
573 top = p->top;
574 BN_ULONG *udp,*bdp,*vdp,*cdp;
575
576 bn_wexpand(u,top); udp = u->d;
577 for (i=u->top;i<top;i++) udp[i] = 0;
578 u->top = top;
579 bn_wexpand(b,top); bdp = b->d;
580 bdp[0] = 1;
581 for (i=1;i<top;i++) bdp[i] = 0;
582 b->top = top;
583 bn_wexpand(c,top); cdp = c->d;
584 for (i=0;i<top;i++) cdp[i] = 0;
585 c->top = top;
586 vdp = v->d; /* It pays off to "cache" *->d pointers, because
587 * it allows optimizer to be more aggressive.
588 * But we don't have to "cache" p->d, because *p
589 * is declared 'const'... */
590 while (1)
591 {
592 while (ubits && !(udp[0]&1))
593 {
594 BN_ULONG u0,u1,b0,b1,mask;
595
596 u0 = udp[0];
597 b0 = bdp[0];
598 mask = (BN_ULONG)0-(b0&1);
599 b0 ^= p->d[0]&mask;
600 for (i=0;i<top-1;i++)
601 {
602 u1 = udp[i+1];
603 udp[i] = ((u0>>1)|(u1<<(BN_BITS2-1)))&BN_MASK2;
604 u0 = u1;
605 b1 = bdp[i+1]^(p->d[i+1]&mask);
606 bdp[i] = ((b0>>1)|(b1<<(BN_BITS2-1)))&BN_MASK2;
607 b0 = b1;
608 }
609 udp[i] = u0>>1;
610 bdp[i] = b0>>1;
611 ubits--;
612 }
568 613
614 if (ubits<=BN_BITS2 && udp[0]==1) break;
615
616 if (ubits<vbits)
617 {
618 i = ubits; ubits = vbits; vbits = i;
619 tmp = u; u = v; v = tmp;
620 tmp = b; b = c; c = tmp;
621 udp = vdp; vdp = v->d;
622 bdp = cdp; cdp = c->d;
623 }
624 for(i=0;i<top;i++)
625 {
626 udp[i] ^= vdp[i];
627 bdp[i] ^= cdp[i];
628 }
629 if (ubits==vbits)
630 {
631 BN_ULONG ul;
632 int utop = (ubits-1)/BN_BITS2;
633
634 while ((ul=udp[utop])==0 && utop) utop--;
635 ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
636 }
637 }
638 bn_correct_top(b);
639 }
640#endif
569 641
570 if (!BN_copy(r, b)) goto err; 642 if (!BN_copy(r, b)) goto err;
571 bn_check_top(r); 643 bn_check_top(r);
572 ret = 1; 644 ret = 1;
573 645
574err: 646err:
647#ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */
648 bn_correct_top(c);
649 bn_correct_top(u);
650 bn_correct_top(v);
651#endif
575 BN_CTX_end(ctx); 652 BN_CTX_end(ctx);
576 return ret; 653 return ret;
577 } 654 }
@@ -1033,3 +1110,4 @@ int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
1033 return 1; 1110 return 1;
1034 } 1111 }
1035 1112
1113#endif