Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: net/third_party/nss/ssl/mpi/mplogic.c

Issue 6804032: Add TLS-SRP (RFC 5054) support Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * mplogic.c
3 *
4 * Bitwise logical operations on MPI values
5 *
6 * ***** BEGIN LICENSE BLOCK *****
7 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8 *
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
13 *
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
17 * License.
18 *
19 * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
20 *
21 * The Initial Developer of the Original Code is
22 * Michael J. Fromberger.
23 * Portions created by the Initial Developer are Copyright (C) 1998
24 * the Initial Developer. All Rights Reserved.
25 *
26 * Contributor(s):
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
39 *
40 * ***** END LICENSE BLOCK ***** */
41 /* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
42
43 #define MP_API_COMPATIBLE 1
44 #include "mpi-priv.h"
45 #include "mplogic.h"
46
47 /* {{{ Lookup table for population count */
48
49 static unsigned char bitc[] = {
50 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
51 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
52 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
53 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
54 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
55 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
56 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
57 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
58 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
59 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
60 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
61 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
62 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
63 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
64 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
65 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
66 };
67
68 /* }}} */
69
70 /*------------------------------------------------------------------------*/
71 /*
72 mpl_not(a, b) - compute b = ~a
73 mpl_and(a, b, c) - compute c = a & b
74 mpl_or(a, b, c) - compute c = a | b
75 mpl_xor(a, b, c) - compute c = a ^ b
76 */
77
78 /* {{{ mpl_not(a, b) */
79
80 mp_err mpl_not(mp_int *a, mp_int *b)
81 {
82 mp_err res;
83 unsigned int ix;
84
85 ARGCHK(a != NULL && b != NULL, MP_BADARG);
86
87 if((res = mp_copy(a, b)) != MP_OKAY)
88 return res;
89
90 /* This relies on the fact that the digit type is unsigned */
91 for(ix = 0; ix < USED(b); ix++)
92 DIGIT(b, ix) = ~DIGIT(b, ix);
93
94 s_mp_clamp(b);
95
96 return MP_OKAY;
97
98 } /* end mpl_not() */
99
100 /* }}} */
101
102 /* {{{ mpl_and(a, b, c) */
103
104 mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c)
105 {
106 mp_int *which, *other;
107 mp_err res;
108 unsigned int ix;
109
110 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
111
112 if(USED(a) <= USED(b)) {
113 which = a;
114 other = b;
115 } else {
116 which = b;
117 other = a;
118 }
119
120 if((res = mp_copy(which, c)) != MP_OKAY)
121 return res;
122
123 for(ix = 0; ix < USED(which); ix++)
124 DIGIT(c, ix) &= DIGIT(other, ix);
125
126 s_mp_clamp(c);
127
128 return MP_OKAY;
129
130 } /* end mpl_and() */
131
132 /* }}} */
133
134 /* {{{ mpl_or(a, b, c) */
135
136 mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c)
137 {
138 mp_int *which, *other;
139 mp_err res;
140 unsigned int ix;
141
142 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
143
144 if(USED(a) >= USED(b)) {
145 which = a;
146 other = b;
147 } else {
148 which = b;
149 other = a;
150 }
151
152 if((res = mp_copy(which, c)) != MP_OKAY)
153 return res;
154
155 for(ix = 0; ix < USED(which); ix++)
156 DIGIT(c, ix) |= DIGIT(other, ix);
157
158 return MP_OKAY;
159
160 } /* end mpl_or() */
161
162 /* }}} */
163
164 /* {{{ mpl_xor(a, b, c) */
165
166 mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c)
167 {
168 mp_int *which, *other;
169 mp_err res;
170 unsigned int ix;
171
172 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
173
174 if(USED(a) >= USED(b)) {
175 which = a;
176 other = b;
177 } else {
178 which = b;
179 other = a;
180 }
181
182 if((res = mp_copy(which, c)) != MP_OKAY)
183 return res;
184
185 for(ix = 0; ix < USED(which); ix++)
186 DIGIT(c, ix) ^= DIGIT(other, ix);
187
188 s_mp_clamp(c);
189
190 return MP_OKAY;
191
192 } /* end mpl_xor() */
193
194 /* }}} */
195
196 /*------------------------------------------------------------------------*/
197 /*
198 mpl_rsh(a, b, d) - b = a >> d
199 mpl_lsh(a, b, d) - b = a << d
200 */
201
202 /* {{{ mpl_rsh(a, b, d) */
203
204 mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
205 {
206 mp_err res;
207
208 ARGCHK(a != NULL && b != NULL, MP_BADARG);
209
210 if((res = mp_copy(a, b)) != MP_OKAY)
211 return res;
212
213 s_mp_div_2d(b, d);
214
215 return MP_OKAY;
216
217 } /* end mpl_rsh() */
218
219 /* }}} */
220
221 /* {{{ mpl_lsh(a, b, d) */
222
223 mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
224 {
225 mp_err res;
226
227 ARGCHK(a != NULL && b != NULL, MP_BADARG);
228
229 if((res = mp_copy(a, b)) != MP_OKAY)
230 return res;
231
232 return s_mp_mul_2d(b, d);
233
234 } /* end mpl_lsh() */
235
236 /* }}} */
237
238 /*------------------------------------------------------------------------*/
239 /*
240 mpl_num_set(a, num)
241
242 Count the number of set bits in the binary representation of a.
243 Returns MP_OKAY and sets 'num' to be the number of such bits, if
244 possible. If num is NULL, the result is thrown away, but it is
245 not considered an error.
246
247 mpl_num_clear() does basically the same thing for clear bits.
248 */
249
250 /* {{{ mpl_num_set(a, num) */
251
252 mp_err mpl_num_set(mp_int *a, int *num)
253 {
254 unsigned int ix;
255 int db, nset = 0;
256 mp_digit cur;
257 unsigned char reg;
258
259 ARGCHK(a != NULL, MP_BADARG);
260
261 for(ix = 0; ix < USED(a); ix++) {
262 cur = DIGIT(a, ix);
263
264 for(db = 0; db < sizeof(mp_digit); db++) {
265 reg = (unsigned char)(cur >> (CHAR_BIT * db));
266
267 nset += bitc[reg];
268 }
269 }
270
271 if(num)
272 *num = nset;
273
274 return MP_OKAY;
275
276 } /* end mpl_num_set() */
277
278 /* }}} */
279
280 /* {{{ mpl_num_clear(a, num) */
281
282 mp_err mpl_num_clear(mp_int *a, int *num)
283 {
284 unsigned int ix;
285 int db, nset = 0;
286 mp_digit cur;
287 unsigned char reg;
288
289 ARGCHK(a != NULL, MP_BADARG);
290
291 for(ix = 0; ix < USED(a); ix++) {
292 cur = DIGIT(a, ix);
293
294 for(db = 0; db < sizeof(mp_digit); db++) {
295 reg = (unsigned char)(cur >> (CHAR_BIT * db));
296
297 nset += bitc[UCHAR_MAX - reg];
298 }
299 }
300
301 if(num)
302 *num = nset;
303
304 return MP_OKAY;
305
306
307 } /* end mpl_num_clear() */
308
309 /* }}} */
310
311 /*------------------------------------------------------------------------*/
312 /*
313 mpl_parity(a)
314
315 Determines the bitwise parity of the value given. Returns MP_EVEN
316 if an even number of digits are set, MP_ODD if an odd number are
317 set.
318 */
319
320 /* {{{ mpl_parity(a) */
321
322 mp_err mpl_parity(mp_int *a)
323 {
324 unsigned int ix;
325 int par = 0;
326 mp_digit cur;
327
328 ARGCHK(a != NULL, MP_BADARG);
329
330 for(ix = 0; ix < USED(a); ix++) {
331 int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
332
333 cur = DIGIT(a, ix);
334
335 /* Compute parity for current digit */
336 while(shft != 0) {
337 cur ^= (cur >> shft);
338 shft >>= 1;
339 }
340 cur &= 1;
341
342 /* XOR with running parity so far */
343 par ^= cur;
344 }
345
346 if(par)
347 return MP_ODD;
348 else
349 return MP_EVEN;
350
351 } /* end mpl_parity() */
352
353 /* }}} */
354
355 /*
356 mpl_set_bit
357
358 Returns MP_OKAY or some error code.
359 Grows a if needed to set a bit to 1.
360 */
361 mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
362 {
363 mp_size ix;
364 mp_err rv;
365 mp_digit mask;
366
367 ARGCHK(a != NULL, MP_BADARG);
368
369 ix = bitNum / MP_DIGIT_BIT;
370 if (ix + 1 > MP_USED(a)) {
371 rv = s_mp_pad(a, ix + 1);
372 if (rv != MP_OKAY)
373 return rv;
374 }
375
376 bitNum = bitNum % MP_DIGIT_BIT;
377 mask = (mp_digit)1 << bitNum;
378 if (value)
379 MP_DIGIT(a,ix) |= mask;
380 else
381 MP_DIGIT(a,ix) &= ~mask;
382 s_mp_clamp(a);
383 return MP_OKAY;
384 }
385
386 /*
387 mpl_get_bit
388
389 returns 0 or 1 or some (negative) error code.
390 */
391 mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
392 {
393 mp_size bit, ix;
394 mp_err rv;
395
396 ARGCHK(a != NULL, MP_BADARG);
397
398 ix = bitNum / MP_DIGIT_BIT;
399 ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
400
401 bit = bitNum % MP_DIGIT_BIT;
402 rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
403 return rv;
404 }
405
406 /*
407 mpl_get_bits
408 - Extracts numBits bits from a, where the least significant extracted bit
409 is bit lsbNum. Returns a negative value if error occurs.
410 - Because sign bit is used to indicate error, maximum number of bits to
411 be returned is the lesser of (a) the number of bits in an mp_digit, or
412 (b) one less than the number of bits in an mp_err.
413 - lsbNum + numbits can be greater than the number of significant bits in
414 integer a, as long as bit lsbNum is in the high order digit of a.
415 */
416 mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
417 {
418 mp_size rshift = (lsbNum % MP_DIGIT_BIT);
419 mp_size lsWndx = (lsbNum / MP_DIGIT_BIT);
420 mp_digit * digit = MP_DIGITS(a) + lsWndx;
421 mp_digit mask = ((1 << numBits) - 1);
422
423 ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
424 ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
425
426 if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
427 (lsWndx + 1 >= MP_USED(a))) {
428 mask &= (digit[0] >> rshift);
429 } else {
430 mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
431 }
432 return (mp_err)mask;
433 }
434
435 /*
436 mpl_significant_bits
437 returns number of significnant bits in abs(a).
438 returns 1 if value is zero.
439 */
440 mp_err mpl_significant_bits(const mp_int *a)
441 {
442 mp_err bits = 0;
443 int ix;
444
445 ARGCHK(a != NULL, MP_BADARG);
446
447 ix = MP_USED(a);
448 for (ix = MP_USED(a); ix > 0; ) {
449 mp_digit d;
450 d = MP_DIGIT(a, --ix);
451 if (d) {
452 while (d) {
453 ++bits;
454 d >>= 1;
455 }
456 break;
457 }
458 }
459 bits += ix * MP_DIGIT_BIT;
460 if (!bits)
461 bits = 1;
462 return bits;
463 }
464
465 /*------------------------------------------------------------------------*/
466 /* HERE THERE BE DRAGONS */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698