comparison nss/lib/freebl/mpi/mplogic.c @ 0:1e5118fa0cb1

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