diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_add.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_add.c | 96 |
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 @@ | |||
64 | int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 64 | int 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 */ |
107 | int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 105 | int 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. */ |
168 | int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | 166 | int 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 | ||