summaryrefslogtreecommitdiff
path: root/crypto/bn/bn_word.c
diff options
context:
space:
mode:
authorGeoff Thorpe <geoff@openssl.org>2004-03-17 17:36:54 +0000
committerGeoff Thorpe <geoff@openssl.org>2004-03-17 17:36:54 +0000
commite042540f6bb0ebd8acf5c2ab0ccd1f14b5fc0f77 (patch)
tree45cc4498f4011adb6d3a20a608f131b01bcc2c7a /crypto/bn/bn_word.c
parent4e8172d6dafec18c4512267b80879de7f0a9fff9 (diff)
downloadopenssl-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.c30
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)
{