| 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 |