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