bn/bn_recp.c: make it indent-friendly.
[openssl.git] / crypto / bn / bn_word.c
index 988e0ca7b37fb30fac9fa1646e084acf5bb3dec0..de83a15b99c53c0da9c07b1619153b9240359e18 100644 (file)
@@ -69,6 +69,10 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
 #endif
        int i;
 
+       if (w == 0)
+               return (BN_ULONG)-1;
+
+       bn_check_top(a);
        w&=BN_MASK2;
        for (i=a->top-1; i>=0; i--)
                {
@@ -85,12 +89,24 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
 
 BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
        {
-       BN_ULONG ret;
-       int i;
+       BN_ULONG ret = 0;
+       int i, j;
+
+       bn_check_top(a);
+       w &= BN_MASK2;
+
+       if (!w)
+               /* actually this an error (division by zero) */
+               return (BN_ULONG)-1;
+       if (a->top == 0)
+               return 0;
+
+       /* normalize input (so bn_div_words doesn't complain) */
+       j = BN_BITS2 - BN_num_bits_word(w);
+       w <<= j;
+       if (!BN_lshift(a, a, j))
+               return (BN_ULONG)-1;
 
-       if (a->top == 0) return(0);
-       ret=0;
-       w&=BN_MASK2;
        for (i=a->top-1; i>=0; i--)
                {
                BN_ULONG l,d;
@@ -102,6 +118,8 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
                }
        if ((a->top > 0) && (a->d[a->top-1] == 0))
                a->top--;
+       ret >>= j;
+       bn_check_top(a);
        return(ret);
        }
 
@@ -110,6 +128,14 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
        BN_ULONG l;
        int i;
 
+       bn_check_top(a);
+       w &= BN_MASK2;
+
+       /* degenerate case: w is zero */
+       if (!w) return 1;
+       /* degenerate case: a is zero */
+       if(BN_is_zero(a)) return BN_set_word(a, w);
+       /* handle 'a' when negative */
        if (a->neg)
                {
                a->neg=0;
@@ -118,24 +144,18 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
                        a->neg=!(a->neg);
                return(i);
                }
-       w&=BN_MASK2;
-       if (bn_wexpand(a,a->top+1) == NULL) return(0);
-       i=0;
-       for (;;)
+       for (i=0;w!=0 && i<a->top;i++)
                {
-               if (i >= a->top)
-                       l=w;
-               else
-                       l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
-               a->d[i]=l;
-               if (w > l)
-                       w=1;
-               else
-                       break;
-               i++;
+               a->d[i] = l = (a->d[i]+w)&BN_MASK2;
+               w = (w>l)?1:0;
                }
-       if (i >= a->top)
+       if (w && i==a->top)
+               {
+               if (bn_wexpand(a,a->top+1) == NULL) return 0;
                a->top++;
+               a->d[i]=w;
+               }
+       bn_check_top(a);
        return(1);
        }
 
@@ -143,7 +163,21 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
        {
        int i;
 
-       if (BN_is_zero(a) || a->neg)
+       bn_check_top(a);
+       w &= BN_MASK2;
+
+       /* degenerate case: w is zero */
+       if (!w) return 1;
+       /* degenerate case: a is zero */
+       if(BN_is_zero(a))
+               {
+               i = BN_set_word(a,w);
+               if (i != 0)
+                       BN_set_negative(a, 1);
+               return i;
+               }
+       /* handle 'a' when negative */
+       if (a->neg)
                {
                a->neg=0;
                i=BN_add_word(a,w);
@@ -151,7 +185,6 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
                return(i);
                }
 
-       w&=BN_MASK2;
        if ((a->top == 1) && (a->d[0] < w))
                {
                a->d[0]=w-a->d[0];
@@ -175,6 +208,7 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w)
                }
        if ((a->d[i] == 0) && (i == (a->top-1)))
                a->top--;
+       bn_check_top(a);
        return(1);
        }
 
@@ -182,6 +216,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
        {
        BN_ULONG ll;
 
+       bn_check_top(a);
        w&=BN_MASK2;
        if (a->top)
                {
@@ -197,6 +232,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w)
                                }
                        }
                }
+       bn_check_top(a);
        return(1);
        }