diff options
author | Geoff Thorpe <geoff@openssl.org> | 2004-03-17 17:36:54 +0000 |
---|---|---|
committer | Geoff Thorpe <geoff@openssl.org> | 2004-03-17 17:36:54 +0000 |
commit | e042540f6bb0ebd8acf5c2ab0ccd1f14b5fc0f77 (patch) | |
tree | 45cc4498f4011adb6d3a20a608f131b01bcc2c7a /crypto/bn/bn_word.c | |
parent | 4e8172d6dafec18c4512267b80879de7f0a9fff9 (diff) | |
download | openssl-new-e042540f6bb0ebd8acf5c2ab0ccd1f14b5fc0f77.tar.gz |
Variety of belt-tightenings in the bignum code. (Please help test this!)
- Remove some unnecessary "+1"-like fudges. Sizes should be handled
exactly, as enlarging size parameters causes needless bloat and may just
make bugs less likely rather than fixing them: bn_expand() macro,
bn_expand_internal(), and BN_sqr().
- Deprecate bn_dup_expand() - it's new since 0.9.7, unused, and not that
useful.
- Remove unnecessary zeroing of unused bytes in bn_expand2().
- Rewrite BN_set_word() - it should be much simpler, the previous
complexities probably date from old mismatched type issues.
- Add missing bn_check_top() macros in bn_word.c
- Improve some degenerate case handling in BN_[add|sub]_word(), add
comments, and avoid a bignum expansion if an overflow isn't possible.
Diffstat (limited to 'crypto/bn/bn_word.c')
-rw-r--r-- | crypto/bn/bn_word.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c index a241150157..7aa2a33d2d 100644 --- a/crypto/bn/bn_word.c +++ b/crypto/bn/bn_word.c @@ -69,6 +69,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) #endif int i; + bn_check_top(a); w&=BN_MASK2; for (i=a->top-1; i>=0; i--) { @@ -88,6 +89,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) BN_ULONG ret = 0; int i; + bn_check_top(a); w &= BN_MASK2; if (!w) @@ -116,11 +118,14 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) BN_ULONG l; int i; + bn_check_top(a); w &= BN_MASK2; - if (!w) - return 1; - + /* 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; @@ -129,14 +134,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) a->neg=!(a->neg); return(i); } - if (bn_wexpand(a,a->top+1) == NULL) return(0); + /* Only expand (and risk failing) if it's possibly necessary */ + if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) && + (bn_wexpand(a,a->top+1) == NULL)) + return(0); i=0; for (;;) { if (i >= a->top) l=w; else - l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; + l=(a->d[i]+w)&BN_MASK2; a->d[i]=l; if (w > l) w=1; @@ -154,12 +162,15 @@ int BN_sub_word(BIGNUM *a, BN_ULONG w) { int i; + bn_check_top(a); w &= BN_MASK2; - if (!w) - return 1; - - if (BN_is_zero(a) || a->neg) + /* 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; i=BN_add_word(a,w); @@ -198,6 +209,7 @@ int BN_mul_word(BIGNUM *a, BN_ULONG w) { BN_ULONG ll; + bn_check_top(a); w&=BN_MASK2; if (a->top) { |