X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbn%2Fbn_add.c;h=9405163706aae5dc8064780a2ce879fece80ccdf;hb=a4d9c12f998d2260bf637d9964b53c28a191b173;hp=cd7d48d71e4a0b5c8048ce09b0af58392d427c92;hpb=6b691a5c85ddc4e407e32781841fee5c029506cd;p=oweals%2Fopenssl.git diff --git a/crypto/bn/bn_add.c b/crypto/bn/bn_add.c index cd7d48d71e..9405163706 100644 --- a/crypto/bn/bn_add.c +++ b/crypto/bn/bn_add.c @@ -61,9 +61,10 @@ #include "bn_lcl.h" /* r can == a or b */ -int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { - BIGNUM *tmp; + const BIGNUM *tmp; + int a_neg = a->neg, ret; bn_check_top(a); bn_check_top(b); @@ -73,10 +74,10 @@ int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) * -a + b b-a * -a + -b -(a+b) */ - if (a->neg ^ b->neg) + if (a_neg ^ b->neg) { /* only one is negative */ - if (a->neg) + if (a_neg) { tmp=a; a=b; b=tmp; } /* we are now a - b */ @@ -94,33 +95,30 @@ int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) return(1); } - if (a->neg) /* both are neg */ - r->neg=1; - else - r->neg=0; - - if (!BN_uadd(r,a,b)) return(0); - return(1); + ret = BN_uadd(r,a,b); + r->neg = a_neg; + bn_check_top(r); + return ret; } -/* unsigned add of b to a, r must be large enough */ -int BN_uadd(BIGNUM *r, BIGNUM *a, BIGNUM *b) +/* unsigned add of b to a */ +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { - register int i; - int max,min; - BN_ULONG *ap,*bp,*rp,carry,t1; - BIGNUM *tmp; + int max,min,dif; + BN_ULONG *ap,*bp,*rp,carry,t1,t2; + const BIGNUM *tmp; bn_check_top(a); bn_check_top(b); if (a->top < b->top) { tmp=a; a=b; b=tmp; } - max=a->top; - min=b->top; + max = a->top; + min = b->top; + dif = max - min; if (bn_wexpand(r,max+1) == NULL) - return(0); + return 0; r->top=max; @@ -128,45 +126,46 @@ int BN_uadd(BIGNUM *r, BIGNUM *a, BIGNUM *b) ap=a->d; bp=b->d; rp=r->d; - carry=0; carry=bn_add_words(rp,ap,bp,min); rp+=min; ap+=min; bp+=min; - i=min; if (carry) { - while (i < max) + while (dif) { - i++; - t1= *(ap++); - if ((*(rp++)=(t1+1)&BN_MASK2) >= t1) + dif--; + t1 = *(ap++); + t2 = (t1+1) & BN_MASK2; + *(rp++) = t2; + if (t2) { carry=0; break; } } - if ((i >= max) && carry) + if (carry) { - *(rp++)=1; + /* carry != 0 => dif == 0 */ + *rp = 1; r->top++; } } - if (rp != ap) - { - for (; ineg = 0; + bn_check_top(r); + return 1; } /* unsigned subtraction of b from a, a must be larger than b. */ -int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b) +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { - int max,min; + int max,min,dif; register BN_ULONG t1,t2,*ap,*bp,*rp; int i,carry; #if defined(IRIX_CC_BUG) && !defined(LINT) @@ -176,14 +175,16 @@ int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b) bn_check_top(a); bn_check_top(b); - if (a->top < b->top) /* hmm... should not be happening */ + max = a->top; + min = b->top; + dif = max - min; + + if (dif < 0) /* hmm... should not be happening */ { BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3); return(0); } - max=a->top; - min=b->top; if (bn_wexpand(r,max) == NULL) return(0); ap=a->d; @@ -192,7 +193,7 @@ int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b) #if 1 carry=0; - for (i=0; i t2) break; + dif--; + t1 = *(ap++); + t2 = (t1-1)&BN_MASK2; + *(rp++) = t2; + if (t1) + break; } } #if 0 @@ -236,13 +240,13 @@ int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b) { for (;;) { - if (i++ >= max) break; + if (!dif--) break; rp[0]=ap[0]; - if (i++ >= max) break; + if (!dif--) break; rp[1]=ap[1]; - if (i++ >= max) break; + if (!dif--) break; rp[2]=ap[2]; - if (i++ >= max) break; + if (!dif--) break; rp[3]=ap[3]; rp+=4; ap+=4; @@ -251,15 +255,16 @@ int BN_usub(BIGNUM *r, BIGNUM *a, BIGNUM *b) #endif r->top=max; - bn_fix_top(r); + r->neg=0; + bn_correct_top(r); return(1); } -int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { int max; int add=0,neg=0; - BIGNUM *tmp; + const BIGNUM *tmp; bn_check_top(a); bn_check_top(b); @@ -302,6 +307,7 @@ int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) if (!BN_usub(r,a,b)) return(0); r->neg=0; } + bn_check_top(r); return(1); }