/src/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 | |
|
52 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
53 | | |
54 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
55 | 0 | return res; |
56 | | |
57 | | /* 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 | |
|
61 | 0 | s_mp_clamp(b); |
62 | |
|
63 | 0 | return MP_OKAY; |
64 | |
|
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 | |
|
78 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
79 | | |
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 | |
|
88 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
89 | 0 | return res; |
90 | | |
91 | 0 | for (ix = 0; ix < USED(which); ix++) |
92 | 0 | DIGIT(c, ix) &= DIGIT(other, ix); |
93 | |
|
94 | 0 | s_mp_clamp(c); |
95 | |
|
96 | 0 | return MP_OKAY; |
97 | |
|
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 | |
|
111 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
112 | | |
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 | |
|
121 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
122 | 0 | return res; |
123 | | |
124 | 0 | for (ix = 0; ix < USED(which); ix++) |
125 | 0 | DIGIT(c, ix) |= DIGIT(other, ix); |
126 | |
|
127 | 0 | return MP_OKAY; |
128 | |
|
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 | |
|
142 | 0 | ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
143 | | |
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 | |
|
152 | 0 | if ((res = mp_copy(which, c)) != MP_OKAY) |
153 | 0 | return res; |
154 | | |
155 | 0 | for (ix = 0; ix < USED(which); ix++) |
156 | 0 | DIGIT(c, ix) ^= DIGIT(other, ix); |
157 | |
|
158 | 0 | s_mp_clamp(c); |
159 | |
|
160 | 0 | return MP_OKAY; |
161 | |
|
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 | |
|
179 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
180 | | |
181 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
182 | 0 | return res; |
183 | | |
184 | 0 | s_mp_div_2d(b, d); |
185 | |
|
186 | 0 | return MP_OKAY; |
187 | |
|
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 | |
|
199 | 0 | ARGCHK(a != NULL && b != NULL, MP_BADARG); |
200 | | |
201 | 0 | if ((res = mp_copy(a, b)) != MP_OKAY) |
202 | 0 | return res; |
203 | | |
204 | 0 | return s_mp_mul_2d(b, d); |
205 | |
|
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, unsigned int *num) |
226 | 0 | { |
227 | 0 | unsigned int ix, db, nset = 0; |
228 | 0 | mp_digit cur; |
229 | 0 | unsigned char reg; |
230 | |
|
231 | 0 | ARGCHK(a != NULL, MP_BADARG); |
232 | | |
233 | 0 | for (ix = 0; ix < USED(a); ix++) { |
234 | 0 | cur = DIGIT(a, ix); |
235 | |
|
236 | 0 | for (db = 0; db < sizeof(mp_digit); db++) { |
237 | 0 | reg = (unsigned char)(cur >> (CHAR_BIT * db)); |
238 | |
|
239 | 0 | nset += bitc[reg]; |
240 | 0 | } |
241 | 0 | } |
242 | |
|
243 | 0 | if (num) |
244 | 0 | *num = nset; |
245 | |
|
246 | 0 | return MP_OKAY; |
247 | |
|
248 | 0 | } /* end mpl_num_set() */ |
249 | | |
250 | | /* }}} */ |
251 | | |
252 | | /* {{{ mpl_num_clear(a, num) */ |
253 | | |
254 | | mp_err |
255 | | mpl_num_clear(mp_int *a, unsigned int *num) |
256 | 0 | { |
257 | 0 | unsigned int ix, db, nset = 0; |
258 | 0 | mp_digit cur; |
259 | 0 | unsigned char reg; |
260 | |
|
261 | 0 | ARGCHK(a != NULL, MP_BADARG); |
262 | | |
263 | 0 | for (ix = 0; ix < USED(a); ix++) { |
264 | 0 | cur = DIGIT(a, ix); |
265 | |
|
266 | 0 | for (db = 0; db < sizeof(mp_digit); db++) { |
267 | 0 | reg = (unsigned char)(cur >> (CHAR_BIT * db)); |
268 | |
|
269 | 0 | nset += bitc[UCHAR_MAX - reg]; |
270 | 0 | } |
271 | 0 | } |
272 | |
|
273 | 0 | if (num) |
274 | 0 | *num = nset; |
275 | |
|
276 | 0 | return MP_OKAY; |
277 | |
|
278 | 0 | } /* end mpl_num_clear() */ |
279 | | |
280 | | /* }}} */ |
281 | | |
282 | | /*------------------------------------------------------------------------*/ |
283 | | /* |
284 | | mpl_parity(a) |
285 | | |
286 | | Determines the bitwise parity of the value given. Returns MP_EVEN |
287 | | if an even number of digits are set, MP_ODD if an odd number are |
288 | | set. |
289 | | */ |
290 | | |
291 | | /* {{{ mpl_parity(a) */ |
292 | | |
293 | | mp_err |
294 | | mpl_parity(mp_int *a) |
295 | 0 | { |
296 | 0 | unsigned int ix; |
297 | 0 | int par = 0; |
298 | 0 | mp_digit cur; |
299 | |
|
300 | 0 | ARGCHK(a != NULL, MP_BADARG); |
301 | | |
302 | 0 | for (ix = 0; ix < USED(a); ix++) { |
303 | 0 | int shft = (sizeof(mp_digit) * CHAR_BIT) / 2; |
304 | |
|
305 | 0 | cur = DIGIT(a, ix); |
306 | | |
307 | | /* Compute parity for current digit */ |
308 | 0 | while (shft != 0) { |
309 | 0 | cur ^= (cur >> shft); |
310 | 0 | shft >>= 1; |
311 | 0 | } |
312 | 0 | cur &= 1; |
313 | | |
314 | | /* XOR with running parity so far */ |
315 | 0 | par ^= cur; |
316 | 0 | } |
317 | |
|
318 | 0 | if (par) |
319 | 0 | return MP_ODD; |
320 | 0 | else |
321 | 0 | return MP_EVEN; |
322 | |
|
323 | 0 | } /* end mpl_parity() */ |
324 | | |
325 | | /* }}} */ |
326 | | |
327 | | /* |
328 | | mpl_set_bit |
329 | | |
330 | | Returns MP_OKAY or some error code. |
331 | | Grows a if needed to set a bit to 1. |
332 | | */ |
333 | | mp_err |
334 | | mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value) |
335 | 0 | { |
336 | 0 | mp_size ix; |
337 | 0 | mp_err rv; |
338 | 0 | mp_digit mask; |
339 | |
|
340 | 0 | ARGCHK(a != NULL, MP_BADARG); |
341 | | |
342 | 0 | ix = bitNum / MP_DIGIT_BIT; |
343 | 0 | if (ix + 1 > MP_USED(a)) { |
344 | 0 | rv = s_mp_pad(a, ix + 1); |
345 | 0 | if (rv != MP_OKAY) |
346 | 0 | return rv; |
347 | 0 | } |
348 | | |
349 | 0 | bitNum = bitNum % MP_DIGIT_BIT; |
350 | 0 | mask = (mp_digit)1 << bitNum; |
351 | 0 | if (value) |
352 | 0 | MP_DIGIT(a, ix) |= mask; |
353 | 0 | else |
354 | 0 | MP_DIGIT(a, ix) &= ~mask; |
355 | 0 | s_mp_clamp(a); |
356 | 0 | return MP_OKAY; |
357 | 0 | } |
358 | | |
359 | | /* |
360 | | mpl_get_bit |
361 | | |
362 | | returns 0 or 1 or some (negative) error code. |
363 | | */ |
364 | | mp_err |
365 | | mpl_get_bit(const mp_int *a, mp_size bitNum) |
366 | 0 | { |
367 | 0 | mp_size bit, ix; |
368 | 0 | mp_err rv; |
369 | |
|
370 | 0 | ARGCHK(a != NULL, MP_BADARG); |
371 | | |
372 | 0 | ix = bitNum / MP_DIGIT_BIT; |
373 | 0 | ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE); |
374 | | |
375 | 0 | bit = bitNum % MP_DIGIT_BIT; |
376 | 0 | rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1; |
377 | 0 | return rv; |
378 | 0 | } |
379 | | |
380 | | /* |
381 | | mpl_get_bits |
382 | | - Extracts numBits bits from a, where the least significant extracted bit |
383 | | is bit lsbNum. Returns a negative value if error occurs. |
384 | | - Because sign bit is used to indicate error, maximum number of bits to |
385 | | be returned is the lesser of (a) the number of bits in an mp_digit, or |
386 | | (b) one less than the number of bits in an mp_err. |
387 | | - lsbNum + numbits can be greater than the number of significant bits in |
388 | | integer a, as long as bit lsbNum is in the high order digit of a. |
389 | | */ |
390 | | mp_err |
391 | | mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits) |
392 | 0 | { |
393 | 0 | mp_size rshift = (lsbNum % MP_DIGIT_BIT); |
394 | 0 | mp_size lsWndx = (lsbNum / MP_DIGIT_BIT); |
395 | 0 | mp_digit *digit = MP_DIGITS(a) + lsWndx; |
396 | 0 | mp_digit mask = ((1 << numBits) - 1); |
397 | |
|
398 | 0 | ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG); |
399 | 0 | ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE); |
400 | | |
401 | 0 | if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) || |
402 | 0 | (lsWndx + 1 >= MP_USED(a))) { |
403 | 0 | mask &= (digit[0] >> rshift); |
404 | 0 | } else { |
405 | 0 | mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift))); |
406 | 0 | } |
407 | 0 | return (mp_err)mask; |
408 | 0 | } |
409 | | |
410 | | #define LZCNTLOOP(i) \ |
411 | 0 | do { \ |
412 | 0 | x = d >> (i); \ |
413 | 0 | mask = (0 - x); \ |
414 | 0 | mask = (0 - (mask >> (MP_DIGIT_BIT - 1))); \ |
415 | 0 | bits += (i)&mask; \ |
416 | 0 | d ^= (x ^ d) & mask; \ |
417 | 0 | } while (0) |
418 | | |
419 | | /* |
420 | | mpl_significant_bits |
421 | | returns number of significant bits in abs(a). |
422 | | In other words: floor(lg(abs(a))) + 1. |
423 | | returns 1 if value is zero. |
424 | | */ |
425 | | mp_size |
426 | | mpl_significant_bits(const mp_int *a) |
427 | 0 | { |
428 | | /* |
429 | | start bits at 1. |
430 | | lg(0) = 0 => bits = 1 by function semantics. |
431 | | below does a binary search for the _position_ of the top bit set, |
432 | | which is floor(lg(abs(a))) for a != 0. |
433 | | */ |
434 | 0 | mp_size bits = 1; |
435 | 0 | int ix; |
436 | |
|
437 | 0 | ARGCHK(a != NULL, MP_BADARG); |
438 | | |
439 | 0 | for (ix = MP_USED(a); ix > 0;) { |
440 | 0 | mp_digit d, x, mask; |
441 | 0 | if ((d = MP_DIGIT(a, --ix)) == 0) |
442 | 0 | continue; |
443 | 0 | #if !defined(MP_USE_UINT_DIGIT) |
444 | 0 | LZCNTLOOP(32); |
445 | 0 | #endif |
446 | 0 | LZCNTLOOP(16); |
447 | 0 | LZCNTLOOP(8); |
448 | 0 | LZCNTLOOP(4); |
449 | 0 | LZCNTLOOP(2); |
450 | 0 | LZCNTLOOP(1); |
451 | 0 | break; |
452 | 0 | } |
453 | 0 | bits += ix * MP_DIGIT_BIT; |
454 | 0 | return bits; |
455 | 0 | } |
456 | | |
457 | | #undef LZCNTLOOP |
458 | | |
459 | | /*------------------------------------------------------------------------*/ |
460 | | /* HERE THERE BE DRAGONS */ |