summaryrefslogtreecommitdiff
path: root/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
diff options
context:
space:
mode:
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/bn/bn_shift.c')
-rw-r--r--Cryptlib/OpenSSL/crypto/bn/bn_shift.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_shift.c b/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
index 67904c99..9673d9a3 100644
--- a/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
+++ b/Cryptlib/OpenSSL/crypto/bn/bn_shift.c
@@ -96,7 +96,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
int BN_rshift1(BIGNUM *r, const BIGNUM *a)
{
BN_ULONG *ap, *rp, t, c;
- int i;
+ int i, j;
bn_check_top(r);
bn_check_top(a);
@@ -105,21 +105,25 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
BN_zero(r);
return (1);
}
+ i = a->top;
+ ap = a->d;
+ j = i - (ap[i - 1] == 1);
if (a != r) {
- if (bn_wexpand(r, a->top) == NULL)
+ if (bn_wexpand(r, j) == NULL)
return (0);
- r->top = a->top;
r->neg = a->neg;
}
- ap = a->d;
rp = r->d;
- c = 0;
- for (i = a->top - 1; i >= 0; i--) {
- t = ap[i];
+ t = ap[--i];
+ c = (t & 1) ? BN_TBIT : 0;
+ if (t >>= 1)
+ rp[i] = t;
+ while (i > 0) {
+ t = ap[--i];
rp[i] = ((t >> 1) & BN_MASK2) | c;
c = (t & 1) ? BN_TBIT : 0;
}
- bn_correct_top(r);
+ r->top = j;
bn_check_top(r);
return (1);
}
@@ -133,6 +137,11 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
bn_check_top(r);
bn_check_top(a);
+ if (n < 0) {
+ BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
r->neg = a->neg;
nw = n / BN_BITS2;
if (bn_wexpand(r, a->top + nw + 1) == NULL)
@@ -170,6 +179,11 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
bn_check_top(r);
bn_check_top(a);
+ if (n < 0) {
+ BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
+ return 0;
+ }
+
nw = n / BN_BITS2;
rb = n % BN_BITS2;
lb = BN_BITS2 - rb;
@@ -177,9 +191,10 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
BN_zero(r);
return (1);
}
+ i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
if (r != a) {
r->neg = a->neg;
- if (bn_wexpand(r, a->top - nw + 1) == NULL)
+ if (bn_wexpand(r, i) == NULL)
return (0);
} else {
if (n == 0)
@@ -189,7 +204,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
f = &(a->d[nw]);
t = r->d;
j = a->top - nw;
- r->top = j;
+ r->top = i;
if (rb == 0) {
for (i = j; i != 0; i--)
@@ -201,9 +216,9 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
l = *(f++);
*(t++) = (tmp | (l << lb)) & BN_MASK2;
}
- *(t++) = (l >> rb) & BN_MASK2;
+ if ((l = (l >> rb) & BN_MASK2))
+ *(t) = l;
}
- bn_correct_top(r);
bn_check_top(r);
return (1);
}