summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_add.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_add.c')
-rw-r--r--src/lib/libcrypto/bn/bn_add.c96
1 files changed, 50 insertions, 46 deletions
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c
index 6cba07e9f6..9405163706 100644
--- a/src/lib/libcrypto/bn/bn_add.c
+++ b/src/lib/libcrypto/bn/bn_add.c
@@ -64,7 +64,7 @@
64int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 64int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
65 { 65 {
66 const BIGNUM *tmp; 66 const BIGNUM *tmp;
67 int a_neg = a->neg; 67 int a_neg = a->neg, ret;
68 68
69 bn_check_top(a); 69 bn_check_top(a);
70 bn_check_top(b); 70 bn_check_top(b);
@@ -95,20 +95,17 @@ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
95 return(1); 95 return(1);
96 } 96 }
97 97
98 if (!BN_uadd(r,a,b)) return(0); 98 ret = BN_uadd(r,a,b);
99 if (a_neg) /* both are neg */ 99 r->neg = a_neg;
100 r->neg=1; 100 bn_check_top(r);
101 else 101 return ret;
102 r->neg=0;
103 return(1);
104 } 102 }
105 103
106/* unsigned add of b to a, r must be large enough */ 104/* unsigned add of b to a */
107int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 105int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
108 { 106 {
109 register int i; 107 int max,min,dif;
110 int max,min; 108 BN_ULONG *ap,*bp,*rp,carry,t1,t2;
111 BN_ULONG *ap,*bp,*rp,carry,t1;
112 const BIGNUM *tmp; 109 const BIGNUM *tmp;
113 110
114 bn_check_top(a); 111 bn_check_top(a);
@@ -116,11 +113,12 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
116 113
117 if (a->top < b->top) 114 if (a->top < b->top)
118 { tmp=a; a=b; b=tmp; } 115 { tmp=a; a=b; b=tmp; }
119 max=a->top; 116 max = a->top;
120 min=b->top; 117 min = b->top;
118 dif = max - min;
121 119
122 if (bn_wexpand(r,max+1) == NULL) 120 if (bn_wexpand(r,max+1) == NULL)
123 return(0); 121 return 0;
124 122
125 r->top=max; 123 r->top=max;
126 124
@@ -128,46 +126,46 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
128 ap=a->d; 126 ap=a->d;
129 bp=b->d; 127 bp=b->d;
130 rp=r->d; 128 rp=r->d;
131 carry=0;
132 129
133 carry=bn_add_words(rp,ap,bp,min); 130 carry=bn_add_words(rp,ap,bp,min);
134 rp+=min; 131 rp+=min;
135 ap+=min; 132 ap+=min;
136 bp+=min; 133 bp+=min;
137 i=min;
138 134
139 if (carry) 135 if (carry)
140 { 136 {
141 while (i < max) 137 while (dif)
142 { 138 {
143 i++; 139 dif--;
144 t1= *(ap++); 140 t1 = *(ap++);
145 if ((*(rp++)=(t1+1)&BN_MASK2) >= t1) 141 t2 = (t1+1) & BN_MASK2;
142 *(rp++) = t2;
143 if (t2)
146 { 144 {
147 carry=0; 145 carry=0;
148 break; 146 break;
149 } 147 }
150 } 148 }
151 if ((i >= max) && carry) 149 if (carry)
152 { 150 {
153 *(rp++)=1; 151 /* carry != 0 => dif == 0 */
152 *rp = 1;
154 r->top++; 153 r->top++;
155 } 154 }
156 } 155 }
157 if (rp != ap) 156 if (dif && rp != ap)
158 { 157 while (dif--)
159 for (; i<max; i++) 158 /* copy remaining words if ap != rp */
160 *(rp++)= *(ap++); 159 *(rp++) = *(ap++);
161 }
162 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
163 r->neg = 0; 160 r->neg = 0;
164 return(1); 161 bn_check_top(r);
162 return 1;
165 } 163 }
166 164
167/* unsigned subtraction of b from a, a must be larger than b. */ 165/* unsigned subtraction of b from a, a must be larger than b. */
168int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) 166int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
169 { 167 {
170 int max,min; 168 int max,min,dif;
171 register BN_ULONG t1,t2,*ap,*bp,*rp; 169 register BN_ULONG t1,t2,*ap,*bp,*rp;
172 int i,carry; 170 int i,carry;
173#if defined(IRIX_CC_BUG) && !defined(LINT) 171#if defined(IRIX_CC_BUG) && !defined(LINT)
@@ -177,14 +175,16 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
177 bn_check_top(a); 175 bn_check_top(a);
178 bn_check_top(b); 176 bn_check_top(b);
179 177
180 if (a->top < b->top) /* hmm... should not be happening */ 178 max = a->top;
179 min = b->top;
180 dif = max - min;
181
182 if (dif < 0) /* hmm... should not be happening */
181 { 183 {
182 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3); 184 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
183 return(0); 185 return(0);
184 } 186 }
185 187
186 max=a->top;
187 min=b->top;
188 if (bn_wexpand(r,max) == NULL) return(0); 188 if (bn_wexpand(r,max) == NULL) return(0);
189 189
190 ap=a->d; 190 ap=a->d;
@@ -193,7 +193,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
193 193
194#if 1 194#if 1
195 carry=0; 195 carry=0;
196 for (i=0; i<min; i++) 196 for (i = min; i != 0; i--)
197 { 197 {
198 t1= *(ap++); 198 t1= *(ap++);
199 t2= *(bp++); 199 t2= *(bp++);
@@ -217,17 +217,20 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
217 ap+=min; 217 ap+=min;
218 bp+=min; 218 bp+=min;
219 rp+=min; 219 rp+=min;
220 i=min;
221#endif 220#endif
222 if (carry) /* subtracted */ 221 if (carry) /* subtracted */
223 { 222 {
224 while (i < max) 223 if (!dif)
224 /* error: a < b */
225 return 0;
226 while (dif)
225 { 227 {
226 i++; 228 dif--;
227 t1= *(ap++); 229 t1 = *(ap++);
228 t2=(t1-1)&BN_MASK2; 230 t2 = (t1-1)&BN_MASK2;
229 *(rp++)=t2; 231 *(rp++) = t2;
230 if (t1 > t2) break; 232 if (t1)
233 break;
231 } 234 }
232 } 235 }
233#if 0 236#if 0
@@ -237,13 +240,13 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
237 { 240 {
238 for (;;) 241 for (;;)
239 { 242 {
240 if (i++ >= max) break; 243 if (!dif--) break;
241 rp[0]=ap[0]; 244 rp[0]=ap[0];
242 if (i++ >= max) break; 245 if (!dif--) break;
243 rp[1]=ap[1]; 246 rp[1]=ap[1];
244 if (i++ >= max) break; 247 if (!dif--) break;
245 rp[2]=ap[2]; 248 rp[2]=ap[2];
246 if (i++ >= max) break; 249 if (!dif--) break;
247 rp[3]=ap[3]; 250 rp[3]=ap[3];
248 rp+=4; 251 rp+=4;
249 ap+=4; 252 ap+=4;
@@ -253,7 +256,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
253 256
254 r->top=max; 257 r->top=max;
255 r->neg=0; 258 r->neg=0;
256 bn_fix_top(r); 259 bn_correct_top(r);
257 return(1); 260 return(1);
258 } 261 }
259 262
@@ -304,6 +307,7 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
304 if (!BN_usub(r,a,b)) return(0); 307 if (!BN_usub(r,a,b)) return(0);
305 r->neg=0; 308 r->neg=0;
306 } 309 }
310 bn_check_top(r);
307 return(1); 311 return(1);
308 } 312 }
309 313