- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / cscrypt / bn_add.c
blob32cdd2a7b999c878df47bed8f009a5a1f10092ff
1 #include "bn.h"
3 #ifndef WITH_LIBCRYPTO
4 //FIXME Not checked on threadsafety yet; after checking please remove this line
5 /* crypto/bn/bn_add.c */
6 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
7 * All rights reserved.
9 * This package is an SSL implementation written
10 * by Eric Young (eay@cryptsoft.com).
11 * The implementation was written so as to conform with Netscapes SSL.
13 * This library is free for commercial and non-commercial use as long as
14 * the following conditions are aheared to. The following conditions
15 * apply to all code found in this distribution, be it the RC4, RSA,
16 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17 * included with this distribution is covered by the same copyright terms
18 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
20 * Copyright remains Eric Young's, and as such any Copyright notices in
21 * the code are not to be removed.
22 * If this package is used in a product, Eric Young should be given attribution
23 * as the author of the parts of the library used.
24 * This can be in the form of a textual message at program startup or
25 * in documentation (online or textual) provided with the package.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * "This product includes cryptographic software written by
38 * Eric Young (eay@cryptsoft.com)"
39 * The word 'cryptographic' can be left out if the rouines from the library
40 * being used are not cryptographic related :-).
41 * 4. If you include any Windows specific code (or a derivative thereof) from
42 * the apps directory (application code) you must include an acknowledgement:
43 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
45 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
57 * The license and distribution terms for any publically available version or
58 * derivative of this code cannot be changed. i.e. this code cannot simply be
59 * copied and put under another distribution license
60 * [including the GNU Public License.]
63 #include <stdio.h>
64 #include "openssl_mods.h"
65 #include "bn_lcl.h"
67 /* r can == a or b */
68 int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
70 const BIGNUM *tmp;
72 bn_check_top(a);
73 bn_check_top(b);
75 /* a + b a+b
76 * a + -b a-b
77 * -a + b b-a
78 * -a + -b -(a+b)
80 if(a->neg ^ b->neg)
82 /* only one is negative */
83 if(a->neg)
85 tmp = a;
86 a = b;
87 b = tmp;
90 /* we are now a - b */
92 if(BN_ucmp(a, b) < 0)
94 if(!BN_usub(r, b, a)) { return (0); }
95 r->neg = 1;
97 else
99 if(!BN_usub(r, a, b)) { return (0); }
100 r->neg = 0;
102 return (1);
105 if(a->neg) /* both are neg */
106 { r->neg = 1; }
107 else
108 { r->neg = 0; }
110 if(!BN_uadd(r, a, b)) { return (0); }
111 return (1);
114 /* unsigned add of b to a, r must be large enough */
115 int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
117 register int i;
118 int max, min;
119 BN_ULONG *ap, *bp, *rp, carry, t1;
120 const BIGNUM *tmp;
122 bn_check_top(a);
123 bn_check_top(b);
125 if(a->top < b->top)
127 tmp = a;
128 a = b;
129 b = tmp;
131 max = a->top;
132 min = b->top;
134 if(bn_wexpand(r, max + 1) == NULL)
135 { return (0); }
137 r->top = max;
140 ap = a->d;
141 bp = b->d;
142 rp = r->d;
144 carry = bn_add_words(rp, ap, bp, min);
145 rp += min;
146 ap += min;
147 i = min;
149 if(carry)
151 while(i < max)
153 i++;
154 t1 = *(ap++);
155 if((*(rp++) = (t1 + 1)&BN_MASK2) >= t1)
157 carry = 0;
158 break;
161 if((i >= max) && carry)
163 *(rp++) = 1;
164 r->top++;
167 if(rp != ap)
169 for(; i < max; i++)
170 { *(rp++) = *(ap++); }
172 /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
173 return (1);
176 /* unsigned subtraction of b from a, a must be larger than b. */
177 int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
179 int max, min;
180 register BN_ULONG t1, t2, *ap, *bp, *rp;
181 int i, carry;
184 bn_check_top(a);
185 bn_check_top(b);
187 if(a->top < b->top) /* hmm... should not be happening */
189 return (0);
192 max = a->top;
193 min = b->top;
194 if(bn_wexpand(r, max) == NULL) { return (0); }
196 ap = a->d;
197 bp = b->d;
198 rp = r->d;
200 #if 1
201 carry = 0;
202 for(i = 0; i < min; i++)
204 t1 = *(ap++);
205 t2 = *(bp++);
206 if(carry)
208 carry = (t1 <= t2);
209 t1 = (t1 - t2 - 1)&BN_MASK2;
211 else
213 carry = (t1 < t2);
214 t1 = (t1 - t2)&BN_MASK2;
216 #if defined(IRIX_CC_BUG) && !defined(LINT)
217 int dummy;
218 dummy = t1;
219 #endif
220 *(rp++) = t1 & BN_MASK2;
222 #else
223 carry = bn_sub_words(rp, ap, bp, min);
224 ap += min;
225 bp += min;
226 rp += min;
227 i = min;
228 #endif
229 if(carry) /* subtracted */
231 while(i < max)
233 i++;
234 t1 = *(ap++);
235 t2 = (t1 - 1)&BN_MASK2;
236 *(rp++) = t2;
237 if(t1 > t2) { break; }
240 #if 0
241 memcpy(rp, ap, sizeof(*rp) * (max - i));
242 #else
243 if(rp != ap)
245 for(;;)
247 if(i++ >= max) { break; }
248 rp[0] = ap[0];
249 if(i++ >= max) { break; }
250 rp[1] = ap[1];
251 if(i++ >= max) { break; }
252 rp[2] = ap[2];
253 if(i++ >= max) { break; }
254 rp[3] = ap[3];
255 rp += 4;
256 ap += 4;
259 #endif
261 r->top = max;
262 bn_fix_top(r);
263 return (1);
266 int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
268 int max;
269 int add = 0, neg = 0;
270 const BIGNUM *tmp;
272 bn_check_top(a);
273 bn_check_top(b);
275 /* a - b a-b
276 * a - -b a+b
277 * -a - b -(a+b)
278 * -a - -b b-a
280 if(a->neg)
282 if(b->neg)
284 tmp = a;
285 a = b;
286 b = tmp;
288 else
290 add = 1;
291 neg = 1;
294 else
296 if(b->neg)
298 add = 1;
299 neg = 0;
303 if(add)
305 if(!BN_uadd(r, a, b)) { return (0); }
306 r->neg = neg;
307 return (1);
310 /* We are actually doing a - b :-) */
312 max = (a->top > b->top) ? a->top : b->top;
313 if(bn_wexpand(r, max) == NULL) { return (0); }
314 if(BN_ucmp(a, b) < 0)
316 if(!BN_usub(r, b, a)) { return (0); }
317 r->neg = 1;
319 else
321 if(!BN_usub(r, a, b)) { return (0); }
322 r->neg = 0;
324 return (1);
327 #endif