/src/mozilla-central/security/nss/lib/freebl/mpi/mplogic.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * mplogic.c |
3 | | * |
4 | | * Bitwise logical operations on MPI values |
5 | | * |
6 | | * This Source Code Form is subject to the terms of the Mozilla Public |
7 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
9 | | |
10 | | #include "mpi-priv.h" |
11 | | #include "mplogic.h" |
12 | | |
13 | | /* {{{ Lookup table for population count */ |
14 | | |
15 | | static unsigned char bitc[] = { |
16 | | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, |
17 | | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
18 | | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
19 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
20 | | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
21 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
22 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
23 | | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, |
24 | | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, |
25 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
26 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
27 | | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, |
28 | | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, |
29 | | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, |
30 | | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, |
31 | | 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 |
32 | | }; |
33 | | |
34 | | /* }}} */ |
35 | | |
36 | | /*------------------------------------------------------------------------*/ |
37 | | /* |
38 | | mpl_not(a, b) - compute b = ~a |
39 | | mpl_and(a, b, c) - compute c = a & b |
40 | | mpl_or(a, b, c) - compute c = a | b |
41 | | mpl_xor(a, b, c) - compute c = a ^ b |
42 | | */ |
43 | | |
44 | | /* {{{ mpl_not(a, b) */ |
45 | | |
46 | | mp_err |
47 | | mpl_not(mp_int *a, mp_int *b) |
48 | 0 | { |
49 | 0 | mp_err res; |
50 | 0 | unsigned int ix; |
51 | 0 |
|
52 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
53 | 0 |
|
54 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
55 | 0 | return res; |
56 | 0 | |
57 | 0 | /* This relies on the fact that the digit type is unsigned */ |
58 | 0 | for (ix = 0; ix < USED(b); ix++) |
59 | 0 | DIGIT(b, ix) = ~DIGIT(b, ix); |
60 | 0 |
|
61 | 0 | s_mp_clamp(b); |
62 | 0 |
|
63 | 0 | return MP_OKAY; |
64 | 0 |
|
65 | 0 | } /* end mpl_not() */ |
66 | | |
67 | | /* }}} */ |
68 | | |
69 | | /* {{{ mpl_and(a, b, c) */ |
70 | | |
71 | | mp_err |
72 | | mpl_and(mp_int *a, mp_int *b, mp_int *c) |
73 | 0 | { |
74 | 0 | mp_int *which, *other; |
75 | 0 | mp_err res; |
76 | 0 | unsigned int ix; |
77 | 0 |
|
78 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
79 | 0 |
|
80 | 0 | if (USED(a) <= USED(b)) { |
81 | 0 | which = a; |
82 | 0 | other = b; |
83 | 0 | } else { |
84 | 0 | which = b; |
85 | 0 | other = a; |
86 | 0 | } |
87 | 0 |
|
88 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
89 | 0 | return res; |
90 | 0 | |
91 | 0 | for (ix = 0; ix < USED(which); ix++) |
92 | 0 | DIGIT(c, ix) &= DIGIT(other, ix); |
93 | 0 |
|
94 | 0 | s_mp_clamp(c); |
95 | 0 |
|
96 | 0 | return MP_OKAY; |
97 | 0 |
|
98 | 0 | } /* end mpl_and() */ |
99 | | |
100 | | /* }}} */ |
101 | | |
102 | | /* {{{ mpl_or(a, b, c) */ |
103 | | |
104 | | mp_err |
105 | | mpl_or(mp_int *a, mp_int *b, mp_int *c) |
106 | 0 | { |
107 | 0 | mp_int *which, *other; |
108 | 0 | mp_err res; |
109 | 0 | unsigned int ix; |
110 | 0 |
|
111 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
112 | 0 |
|
113 | 0 | if (USED(a) >= USED(b)) { |
114 | 0 | which = a; |
115 | 0 | other = b; |
116 | 0 | } else { |
117 | 0 | which = b; |
118 | 0 | other = a; |
119 | 0 | } |
120 | 0 |
|
121 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
122 | 0 | return res; |
123 | 0 | |
124 | 0 | for (ix = 0; ix < USED(which); ix++) |
125 | 0 | DIGIT(c, ix) |= DIGIT(other, ix); |
126 | 0 |
|
127 | 0 | return MP_OKAY; |
128 | 0 |
|
129 | 0 | } /* end mpl_or() */ |
130 | | |
131 | | /* }}} */ |
132 | | |
133 | | /* {{{ mpl_xor(a, b, c) */ |
134 | | |
135 | | mp_err |
136 | | mpl_xor(mp_int *a, mp_int *b, mp_int *c) |
137 | 0 | { |
138 | 0 | mp_int *which, *other; |
139 | 0 | mp_err res; |
140 | 0 | unsigned int ix; |
141 | 0 |
|
142 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
143 | 0 |
|
144 | 0 | if (USED(a) >= USED(b)) { |
145 | 0 | which = a; |
146 | 0 | other = b; |
147 | 0 | } else { |
148 | 0 | which = b; |
149 | 0 | other = a; |
150 | 0 | } |
151 | 0 |
|
152 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
153 | 0 | return res; |
154 | 0 | |
155 | 0 | for (ix = 0; ix < USED(which); ix++) |
156 | 0 | DIGIT(c, ix) ^= DIGIT(other, ix); |
157 | 0 |
|
158 | 0 | s_mp_clamp(c); |
159 | 0 |
|
160 | 0 | return MP_OKAY; |
161 | 0 |
|
162 | 0 | } /* end mpl_xor() */ |
163 | | |
164 | | /* }}} */ |
165 | | |
166 | | /*------------------------------------------------------------------------*/ |
167 | | /* |
168 | | mpl_rsh(a, b, d) - b = a >> d |
169 | | mpl_lsh(a, b, d) - b = a << d |
170 | | */ |
171 | | |
172 | | /* {{{ mpl_rsh(a, b, d) */ |
173 | | |
174 | | mp_err |
175 | | mpl_rsh(const mp_int *a, mp_int *b, mp_digit d) |
176 | 0 | { |
177 | 0 | mp_err res; |
178 | 0 |
|
179 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
180 | 0 |
|
181 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
182 | 0 | return res; |
183 | 0 | |
184 | 0 | s_mp_div_2d(b, d); |
185 | 0 |
|
186 | 0 | return MP_OKAY; |
187 | 0 |
|
188 | 0 | } /* end mpl_rsh() */ |
189 | | |
190 | | /* }}} */ |
191 | | |
192 | | /* {{{ mpl_lsh(a, b, d) */ |
193 | | |
194 | | mp_err |
195 | | mpl_lsh(const mp_int *a, mp_int *b, mp_digit d) |
196 | 0 | { |
197 | 0 | mp_err res; |
198 | 0 |
|
199 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
200 | 0 |
|
201 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
202 | 0 | return res; |
203 | 0 | |
204 | 0 | return s_mp_mul_2d(b, d); |
205 | 0 |
|
206 | 0 | } /* end mpl_lsh() */ |
207 | | |
208 | | /* }}} */ |
209 | | |
210 | | /*------------------------------------------------------------------------*/ |
211 | | /* |
212 | | mpl_num_set(a, num) |
213 | | |
214 | | Count the number of set bits in the binary representation of a. |
215 | | Returns MP_OKAY and sets 'num' to be the number of such bits, if |
216 | | possible. If num is NULL, the result is thrown away, but it is |
217 | | not considered an error. |
218 | | |
219 | | mpl_num_clear() does basically the same thing for clear bits. |
220 | | */ |
221 | | |
222 | | /* {{{ mpl_num_set(a, num) */ |
223 | | |
224 | | mp_err |
225 | | mpl_num_set(mp_int *a, int *num) |
226 | 0 | { |
227 | 0 | unsigned int ix; |
228 | 0 | int db, nset = 0; |
229 | 0 | mp_digit cur; |
230 | 0 | unsigned char reg; |
231 | 0 |
|
232 | 0 | ARGCHK(a != NULL, MP_BADARG); |
233 | 0 |
|
234 | 0 | for (ix = 0; ix < USED(a); ix++) { |
235 | 0 | cur = DIGIT(a, ix); |
236 | 0 |
|
237 | 0 | for (db = 0; db < sizeof(mp_digit); db++) { |
238 | 0 | reg = (unsigned char)(cur >> (CHAR_BIT * db)); |
239 | 0 |
|
240 | 0 | nset += bitc[reg]; |
241 | 0 | } |
242 | 0 | } |
243 | 0 |
|
244 | 0 | if (num) |
245 | 0 | *num = nset; |
246 | 0 |
|
247 | 0 | return MP_OKAY; |
248 | 0 |
|
249 | 0 | } /* end mpl_num_set() */ |
250 | | |
251 | | /* }}} */ |
252 | | |
253 | | /* {{{ mpl_num_clear(a, num) */ |
254 | | |
255 | | mp_err |
256 | | mpl_num_clear(mp_int *a, int *num) |
257 | 0 | { |
258 | 0 | unsigned int ix; |
259 | 0 | int db, nset = 0; |
260 | 0 | mp_digit cur; |
261 | 0 | unsigned char reg; |
262 | 0 |
|
263 | 0 | ARGCHK(a != NULL, MP_BADARG); |
264 | 0 |
|
265 | 0 | for (ix = 0; ix < USED(a); ix++) { |
266 | 0 | cur = DIGIT(a, ix); |
267 | 0 |
|
268 | 0 | for (db = 0; db < sizeof(mp_digit); db++) { |
269 | 0 | reg = (unsigned char)(cur >> (CHAR_BIT * db)); |
270 | 0 |
|
271 | 0 | nset += bitc[UCHAR_MAX - reg]; |
272 | 0 | } |
273 | 0 | } |
274 | 0 |
|
275 | 0 | if (num) |
276 | 0 | *num = nset; |
277 | 0 |
|
278 | 0 | return MP_OKAY; |
279 | 0 |
|
280 | 0 | } /* end mpl_num_clear() */ |
281 | | |
282 | | /* }}} */ |
283 | | |
284 | | /*------------------------------------------------------------------------*/ |
285 | | /* |
286 | | mpl_parity(a) |
287 | | |
288 | | Determines the bitwise parity of the value given. Returns MP_EVEN |
289 | | if an even number of digits are set, MP_ODD if an odd number are |
290 | | set. |
291 | | */ |
292 | | |
293 | | /* {{{ mpl_parity(a) */ |
294 | | |
295 | | mp_err |
296 | | mpl_parity(mp_int *a) |
297 | 0 | { |
298 | 0 | unsigned int ix; |
299 | 0 | int par = 0; |
300 | 0 | mp_digit cur; |
301 | 0 |
|
302 | 0 | ARGCHK(a != NULL, MP_BADARG); |
303 | 0 |
|
304 | 0 | for (ix = 0; ix < USED(a); ix++) { |
305 | 0 | int shft = (sizeof(mp_digit) * CHAR_BIT) / 2; |
306 | 0 |
|
307 | 0 | cur = DIGIT(a, ix); |
308 | 0 |
|
309 | 0 | /* Compute parity for current digit */ |
310 | 0 | while (shft != 0) { |
311 | 0 | cur ^= (cur >> shft); |
312 | 0 | shft >>= 1; |
313 | 0 | } |
314 | 0 | cur &= 1; |
315 | 0 |
|
316 | 0 | /* XOR with running parity so far */ |
317 | 0 | par ^= cur; |
318 | 0 | } |
319 | 0 |
|
320 | 0 | if (par) |
321 | 0 | return MP_ODD; |
322 | 0 | else |
323 | 0 | return MP_EVEN; |
324 | 0 |
|
325 | 0 | } /* end mpl_parity() */ |
326 | | |
327 | | /* }}} */ |
328 | | |
329 | | /* |
330 | | mpl_set_bit |
331 | | |
332 | | Returns MP_OKAY or some error code. |
333 | | Grows a if needed to set a bit to 1. |
334 | | */ |
335 | | mp_err |
336 | | mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value) |
337 | 0 | { |
338 | 0 | mp_size ix; |
339 | 0 | mp_err rv; |
340 | 0 | mp_digit mask; |
341 | 0 |
|
342 | 0 | ARGCHK(a != NULL, MP_BADARG); |
343 | 0 |
|
344 | 0 | ix = bitNum / MP_DIGIT_BIT; |
345 | 0 | if (ix + 1 > MP_USED(a)) { |
346 | 0 | rv = s_mp_pad(a, ix + 1); |
347 | 0 | if (rv != MP_OKAY) |
348 | 0 | return rv; |
349 | 0 | } |
350 | 0 | |
351 | 0 | bitNum = bitNum % MP_DIGIT_BIT; |
352 | 0 | mask = (mp_digit)1 << bitNum; |
353 | 0 | if (value) |
354 | 0 | MP_DIGIT(a, ix) |= mask; |
355 | 0 | else |
356 | 0 | MP_DIGIT(a, ix) &= ~mask; |
357 | 0 | s_mp_clamp(a); |
358 | 0 | return MP_OKAY; |
359 | 0 | } |
360 | | |
361 | | /* |
362 | | mpl_get_bit |
363 | | |
364 | | returns 0 or 1 or some (negative) error code. |
365 | | */ |
366 | | mp_err |
367 | | mpl_get_bit(const mp_int *a, mp_size bitNum) |
368 | 0 | { |
369 | 0 | mp_size bit, ix; |
370 | 0 | mp_err rv; |
371 | 0 |
|
372 | 0 | ARGCHK(a != NULL, MP_BADARG); |
373 | 0 |
|
374 | 0 | ix = bitNum / MP_DIGIT_BIT; |
375 | 0 | ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE); |
376 | 0 |
|
377 | 0 | bit = bitNum % MP_DIGIT_BIT; |
378 | 0 | rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1; |
379 | 0 | return rv; |
380 | 0 | } |
381 | | |
382 | | /* |
383 | | mpl_get_bits |
384 | | - Extracts numBits bits from a, where the least significant extracted bit |
385 | | is bit lsbNum. Returns a negative value if error occurs. |
386 | | - Because sign bit is used to indicate error, maximum number of bits to |
387 | | be returned is the lesser of (a) the number of bits in an mp_digit, or |
388 | | (b) one less than the number of bits in an mp_err. |
389 | | - lsbNum + numbits can be greater than the number of significant bits in |
390 | | integer a, as long as bit lsbNum is in the high order digit of a. |
391 | | */ |
392 | | mp_err |
393 | | mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits) |
394 | 0 | { |
395 | 0 | mp_size rshift = (lsbNum % MP_DIGIT_BIT); |
396 | 0 | mp_size lsWndx = (lsbNum / MP_DIGIT_BIT); |
397 | 0 | mp_digit *digit = MP_DIGITS(a) + lsWndx; |
398 | 0 | mp_digit mask = ((1 << numBits) - 1); |
399 | 0 |
|
400 | 0 | ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG); |
401 | 0 | ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE); |
402 | 0 |
|
403 | 0 | if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) || |
404 | 0 | (lsWndx + 1 >= MP_USED(a))) { |
405 | 0 | mask &= (digit[0] >> rshift); |
406 | 0 | } else { |
407 | 0 | mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift))); |
408 | 0 | } |
409 | 0 | return (mp_err)mask; |
410 | 0 | } |
411 | | |
412 | | /* |
413 | | mpl_significant_bits |
414 | | returns number of significnant bits in abs(a). |
415 | | returns 1 if value is zero. |
416 | | */ |
417 | | mp_size |
418 | | mpl_significant_bits(const mp_int *a) |
419 | 0 | { |
420 | 0 | mp_size bits = 0; |
421 | 0 | int ix; |
422 | 0 |
|
423 | 0 | ARGCHK(a != NULL, MP_BADARG); |
424 | 0 |
|
425 | 0 | for (ix = MP_USED(a); ix > 0;) { |
426 | 0 | mp_digit d; |
427 | 0 | d = MP_DIGIT(a, --ix); |
428 | 0 | if (d) { |
429 | 0 | while (d) { |
430 | 0 | ++bits; |
431 | 0 | d >>= 1; |
432 | 0 | } |
433 | 0 | break; |
434 | 0 | } |
435 | 0 | } |
436 | 0 | bits += ix * MP_DIGIT_BIT; |
437 | 0 | if (!bits) |
438 | 0 | bits = 1; |
439 | 0 | return bits; |
440 | 0 | } |
441 | | |
442 | | /*------------------------------------------------------------------------*/ |
443 | | /* HERE THERE BE DRAGONS */ |