Coverage Report

Created: 2025-07-01 06:25

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