* [including the GNU Public Licence.]
*/
-#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"
#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--)
{
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;
}
if ((a->top > 0) && (a->d[a->top-1] == 0))
a->top--;
+ ret >>= j;
+ bn_check_top(a);
return(ret);
}
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;
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++)
{
- 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);
}
{
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);
return(i);
}
- w&=BN_MASK2;
if ((a->top == 1) && (a->d[0] < w))
{
a->d[0]=w-a->d[0];
}
if ((a->d[i] == 0) && (i == (a->top-1)))
a->top--;
+ bn_check_top(a);
return(1);
}
{
BN_ULONG ll;
+ bn_check_top(a);
w&=BN_MASK2;
if (a->top)
{
- ll=bn_mul_words(a->d,a->d,a->top,w);
- if (ll)
+ if (w == 0)
+ BN_zero(a);
+ else
{
- if (bn_wexpand(a,a->top+1) == NULL) return(0);
- a->d[a->top++]=ll;
+ ll=bn_mul_words(a->d,a->d,a->top,w);
+ if (ll)
+ {
+ if (bn_wexpand(a,a->top+1) == NULL) return(0);
+ a->d[a->top++]=ll;
+ }
}
}
+ bn_check_top(a);
return(1);
}