Commit cf9056cf authored by Geoff Thorpe's avatar Geoff Thorpe
Browse files

BN_div_word() was breaking when called from BN_bn2dec() (actually, this is

the only function that uses it) because it would trip up an assertion in
bn_div_words() when first invoked. This also adds BN_div_word() testing to
bntest.

Submitted by: Nils Larsch
Reviewed by: Geoff Thorpe
parent f7fc4ca1
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
	{
	BN_ULONG ret = 0;
	int i;
	int i, j;

	bn_check_top(a);
	w &= BN_MASK2;
@@ -98,6 +98,12 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
	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 0;

	for (i=a->top-1; i>=0; i--)
		{
		BN_ULONG l,d;
@@ -109,6 +115,7 @@ 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);
	}
+61 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
int test_rshift1(BIO *bp);
int test_rshift(BIO *bp,BN_CTX *ctx);
int test_div(BIO *bp,BN_CTX *ctx);
int test_div_word(BIO *bp);
int test_div_recp(BIO *bp,BN_CTX *ctx);
int test_mul(BIO *bp);
int test_sqr(BIO *bp,BN_CTX *ctx);
@@ -221,6 +222,10 @@ int main(int argc, char *argv[])
	if (!test_div(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_div_word");
	if (!test_div_word(out)) goto err;
	BIO_flush(out);

	message(out,"BN_div_recp");
	if (!test_div_recp(out,ctx)) goto err;
	BIO_flush(out);
@@ -463,6 +468,62 @@ int test_div(BIO *bp, BN_CTX *ctx)
	return(1);
	}

int test_div_word(BIO *bp)
	{
	BIGNUM   a,b;
	BN_ULONG r,s;
	int i;

	BN_init(&a);
	BN_init(&b);

	for (i=0; i<num0; i++)
		{
		do {
			BN_bntest_rand(&a,512,-1,0);
			BN_bntest_rand(&b,BN_BITS2,-1,0);
			s = b.d[0];
		} while (!s);

		BN_copy(&b, &a);
		r = BN_div_word(&b, s);

		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,&a);
				BIO_puts(bp," / ");
				BIO_printf(bp,"%lX",s);
				BIO_puts(bp," - ");
				}
			BN_print(bp,&b);
			BIO_puts(bp,"\n");

			if (!results)
				{
				BN_print(bp,&a);
				BIO_puts(bp," % ");
				BIO_printf(bp,"%lX",s);
				BIO_puts(bp," - ");
				}
			BIO_printf(bp,"%lX",r);
			BIO_puts(bp,"\n");
			}
		BN_mul_word(&b,s);
		BN_add_word(&b,r);
		BN_sub(&b,&a,&b);
		if(!BN_is_zero(&b))
		    {
		    fprintf(stderr,"Division (word) test failed!\n");
		    return 0;
		    }
		}
	BN_free(&a);
	BN_free(&b);
	return(1);
	}

int test_div_recp(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM a,b,c,d,e;