int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
{
- int i, j, nw, lb, rb;
- BN_ULONG *t, *f;
- BN_ULONG l, tmp;
-
- bn_check_top(r);
- bn_check_top(a);
+ int ret = 0;
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;
- if (nw >= a->top || a->top == 0) {
- BN_zero(r);
- return 1;
- }
- i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
- if (r != a) {
- if (bn_wexpand(r, i) == NULL)
- return 0;
- r->neg = a->neg;
- } else {
- if (n == 0)
- return 1; /* or the copying loop will go berserk */
- }
-
- f = &(a->d[nw]);
- t = r->d;
- j = a->top - nw;
- r->top = i;
+ ret = bn_rshift_fixed_top(r, a, n);
- if (rb == 0) {
- for (i = j; i != 0; i--)
- *(t++) = *(f++);
- } else {
- l = *(f++);
- for (i = j - 1; i != 0; i--) {
- tmp = (l >> rb) & BN_MASK2;
- l = *(f++);
- *(t++) = (tmp | (l << lb)) & BN_MASK2;
- }
- if ((l = (l >> rb) & BN_MASK2))
- *(t) = l;
- }
- if (!r->top)
- r->neg = 0; /* don't allow negative zero */
+ bn_correct_top(r);
bn_check_top(r);
- return 1;
+
+ return ret;
}
/*