提交 cf9056cf 编写于 作者: G Geoff Thorpe

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
上级 f7fc4ca1
...@@ -87,7 +87,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) ...@@ -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 BN_div_word(BIGNUM *a, BN_ULONG w)
{ {
BN_ULONG ret = 0; BN_ULONG ret = 0;
int i; int i, j;
bn_check_top(a); bn_check_top(a);
w &= BN_MASK2; w &= BN_MASK2;
...@@ -98,6 +98,12 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) ...@@ -98,6 +98,12 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
if (a->top == 0) if (a->top == 0)
return 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--) for (i=a->top-1; i>=0; i--)
{ {
BN_ULONG l,d; BN_ULONG l,d;
...@@ -109,6 +115,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) ...@@ -109,6 +115,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
} }
if ((a->top > 0) && (a->d[a->top-1] == 0)) if ((a->top > 0) && (a->d[a->top-1] == 0))
a->top--; a->top--;
ret >>= j;
bn_check_top(a); bn_check_top(a);
return(ret); return(ret);
} }
......
...@@ -98,6 +98,7 @@ int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_); ...@@ -98,6 +98,7 @@ int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
int test_rshift1(BIO *bp); int test_rshift1(BIO *bp);
int test_rshift(BIO *bp,BN_CTX *ctx); int test_rshift(BIO *bp,BN_CTX *ctx);
int test_div(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_div_recp(BIO *bp,BN_CTX *ctx);
int test_mul(BIO *bp); int test_mul(BIO *bp);
int test_sqr(BIO *bp,BN_CTX *ctx); int test_sqr(BIO *bp,BN_CTX *ctx);
...@@ -221,6 +222,10 @@ int main(int argc, char *argv[]) ...@@ -221,6 +222,10 @@ int main(int argc, char *argv[])
if (!test_div(out,ctx)) goto err; if (!test_div(out,ctx)) goto err;
BIO_flush(out); BIO_flush(out);
message(out,"BN_div_word");
if (!test_div_word(out)) goto err;
BIO_flush(out);
message(out,"BN_div_recp"); message(out,"BN_div_recp");
if (!test_div_recp(out,ctx)) goto err; if (!test_div_recp(out,ctx)) goto err;
BIO_flush(out); BIO_flush(out);
...@@ -463,6 +468,62 @@ int test_div(BIO *bp, BN_CTX *ctx) ...@@ -463,6 +468,62 @@ int test_div(BIO *bp, BN_CTX *ctx)
return(1); 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) int test_div_recp(BIO *bp, BN_CTX *ctx)
{ {
BIGNUM a,b,c,d,e; BIGNUM a,b,c,d,e;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册