summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_add.c
diff options
context:
space:
mode:
authorbeck <>1999-09-29 04:37:45 +0000
committerbeck <>1999-09-29 04:37:45 +0000
commitde8f24ea083384bb66b32ec105dc4743c5663cdf (patch)
tree1412176ae62a3cab2cf2b0b92150fcbceaac6092 /src/lib/libcrypto/bn/bn_add.c
parentcb929d29896bcb87c2a97417fbd03e50078fc178 (diff)
downloadopenbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.gz
openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.bz2
openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.zip
OpenSSL 0.9.4 merge
Diffstat (limited to 'src/lib/libcrypto/bn/bn_add.c')
-rw-r--r--src/lib/libcrypto/bn/bn_add.c194
1 files changed, 167 insertions, 27 deletions
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c
index efb2e312e8..c5ab066c9e 100644
--- a/src/lib/libcrypto/bn/bn_add.c
+++ b/src/lib/libcrypto/bn/bn_add.c
@@ -61,14 +61,13 @@
61#include "bn_lcl.h" 61#include "bn_lcl.h"
62 62
63/* r can == a or b */ 63/* r can == a or b */
64int BN_add(r, a, b) 64int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b)
65BIGNUM *r;
66BIGNUM *a;
67BIGNUM *b;
68 { 65 {
69 int i;
70 BIGNUM *tmp; 66 BIGNUM *tmp;
71 67
68 bn_check_top(a);
69 bn_check_top(b);
70
72 /* a + b a+b 71 /* a + b a+b
73 * a + -b a-b 72 * a + -b a-b
74 * -a + b b-a 73 * -a + b b-a
@@ -84,14 +83,12 @@ BIGNUM *b;
84 83
85 if (BN_ucmp(a,b) < 0) 84 if (BN_ucmp(a,b) < 0)
86 { 85 {
87 if (bn_wexpand(r,b->top) == NULL) return(0); 86 if (!BN_usub(r,b,a)) return(0);
88 bn_qsub(r,b,a);
89 r->neg=1; 87 r->neg=1;
90 } 88 }
91 else 89 else
92 { 90 {
93 if (bn_wexpand(r,a->top) == NULL) return(0); 91 if (!BN_usub(r,a,b)) return(0);
94 bn_qsub(r,a,b);
95 r->neg=0; 92 r->neg=0;
96 } 93 }
97 return(1); 94 return(1);
@@ -102,35 +99,32 @@ BIGNUM *b;
102 else 99 else
103 r->neg=0; 100 r->neg=0;
104 101
105 i=(a->top > b->top); 102 if (!BN_uadd(r,a,b)) return(0);
106
107 if (i)
108 {
109 if (bn_wexpand(r,a->top+1) == NULL) return(0);
110 bn_qadd(r,a,b);
111 }
112 else
113 {
114 if (bn_wexpand(r,b->top+1) == NULL) return(0);
115 bn_qadd(r,b,a);
116 }
117 return(1); 103 return(1);
118 } 104 }
119 105
120/* unsigned add of b to a, r must be large enough */ 106/* unsigned add of b to a, r must be large enough */
121void bn_qadd(r,a,b) 107int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
122BIGNUM *r;
123BIGNUM *a;
124BIGNUM *b;
125 { 108 {
126 register int i; 109 register int i;
127 int max,min; 110 int max,min;
128 BN_ULONG *ap,*bp,*rp,carry,t1; 111 BN_ULONG *ap,*bp,*rp,carry,t1;
112 const BIGNUM *tmp;
113
114 bn_check_top(a);
115 bn_check_top(b);
129 116
117 if (a->top < b->top)
118 { tmp=a; a=b; b=tmp; }
130 max=a->top; 119 max=a->top;
131 min=b->top; 120 min=b->top;
121
122 if (bn_wexpand(r,max+1) == NULL)
123 return(0);
124
132 r->top=max; 125 r->top=max;
133 126
127
134 ap=a->d; 128 ap=a->d;
135 bp=b->d; 129 bp=b->d;
136 rp=r->d; 130 rp=r->d;
@@ -160,8 +154,154 @@ BIGNUM *b;
160 r->top++; 154 r->top++;
161 } 155 }
162 } 156 }
163 for (; i<max; i++) 157 if (rp != ap)
164 *(rp++)= *(ap++); 158 {
159 for (; i<max; i++)
160 *(rp++)= *(ap++);
161 }
165 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/ 162 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
163 return(1);
164 }
165
166/* unsigned subtraction of b from a, a must be larger than b. */
167int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
168 {
169 int max,min;
170 register BN_ULONG t1,t2,*ap,*bp,*rp;
171 int i,carry;
172#if defined(IRIX_CC_BUG) && !defined(LINT)
173 int dummy;
174#endif
175
176 bn_check_top(a);
177 bn_check_top(b);
178
179 if (a->top < b->top) /* hmm... should not be happening */
180 {
181 BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
182 return(0);
183 }
184
185 max=a->top;
186 min=b->top;
187 if (bn_wexpand(r,max) == NULL) return(0);
188
189 ap=a->d;
190 bp=b->d;
191 rp=r->d;
192
193#if 1
194 carry=0;
195 for (i=0; i<min; i++)
196 {
197 t1= *(ap++);
198 t2= *(bp++);
199 if (carry)
200 {
201 carry=(t1 <= t2);
202 t1=(t1-t2-1)&BN_MASK2;
203 }
204 else
205 {
206 carry=(t1 < t2);
207 t1=(t1-t2)&BN_MASK2;
208 }
209#if defined(IRIX_CC_BUG) && !defined(LINT)
210 dummy=t1;
211#endif
212 *(rp++)=t1&BN_MASK2;
213 }
214#else
215 carry=bn_sub_words(rp,ap,bp,min);
216 ap+=min;
217 bp+=min;
218 rp+=min;
219 i=min;
220#endif
221 if (carry) /* subtracted */
222 {
223 while (i < max)
224 {
225 i++;
226 t1= *(ap++);
227 t2=(t1-1)&BN_MASK2;
228 *(rp++)=t2;
229 if (t1 > t2) break;
230 }
231 }
232#if 0
233 memcpy(rp,ap,sizeof(*rp)*(max-i));
234#else
235 if (rp != ap)
236 {
237 for (;;)
238 {
239 if (i++ >= max) break;
240 rp[0]=ap[0];
241 if (i++ >= max) break;
242 rp[1]=ap[1];
243 if (i++ >= max) break;
244 rp[2]=ap[2];
245 if (i++ >= max) break;
246 rp[3]=ap[3];
247 rp+=4;
248 ap+=4;
249 }
250 }
251#endif
252
253 r->top=max;
254 bn_fix_top(r);
255 return(1);
256 }
257
258int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
259 {
260 int max;
261 int add=0,neg=0;
262 const BIGNUM *tmp;
263
264 bn_check_top(a);
265 bn_check_top(b);
266
267 /* a - b a-b
268 * a - -b a+b
269 * -a - b -(a+b)
270 * -a - -b b-a
271 */
272 if (a->neg)
273 {
274 if (b->neg)
275 { tmp=a; a=b; b=tmp; }
276 else
277 { add=1; neg=1; }
278 }
279 else
280 {
281 if (b->neg) { add=1; neg=0; }
282 }
283
284 if (add)
285 {
286 if (!BN_uadd(r,a,b)) return(0);
287 r->neg=neg;
288 return(1);
289 }
290
291 /* We are actually doing a - b :-) */
292
293 max=(a->top > b->top)?a->top:b->top;
294 if (bn_wexpand(r,max) == NULL) return(0);
295 if (BN_ucmp(a,b) < 0)
296 {
297 if (!BN_usub(r,b,a)) return(0);
298 r->neg=1;
299 }
300 else
301 {
302 if (!BN_usub(r,a,b)) return(0);
303 r->neg=0;
304 }
305 return(1);
166 } 306 }
167 307