security/nss/lib/freebl/mpi/mplogic.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial