diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bn/bn_word.c | 9 | ||||
-rw-r--r-- | crypto/bn/bntest.c | 61 |
2 files changed, 69 insertions, 1 deletions
diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c index 7aa2a33d2d..1bcb37e292 100644 --- a/crypto/bn/bn_word.c +++ b/crypto/bn/bn_word.c @@ -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); } diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c index 0d37dcff4d..d4cb92f847 100644 --- a/crypto/bn/bntest.c +++ b/crypto/bn/bntest.c @@ -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; |