blob: 3e619979db153bbe643f86dd458cff6316ed17ce [file] [log] [blame]
Alexandre Lision67916dd2014-01-24 13:33:04 -05001/*
2 * math.c
3 *
4 * crypto math operations and data types
5 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
10 *
11 * Copyright (c) 2001-2006 Cisco Systems, Inc.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials provided
24 * with the distribution.
25 *
26 * Neither the name of the Cisco Systems, Inc. nor the names of its
27 * contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 * OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44
45#include "crypto_math.h"
46#include <stdlib.h> /* malloc() used in bitvector_alloc */
47
48int
49octet_weight[256] = {
50 0, 1, 1, 2, 1, 2, 2, 3,
51 1, 2, 2, 3, 2, 3, 3, 4,
52 1, 2, 2, 3, 2, 3, 3, 4,
53 2, 3, 3, 4, 3, 4, 4, 5,
54 1, 2, 2, 3, 2, 3, 3, 4,
55 2, 3, 3, 4, 3, 4, 4, 5,
56 2, 3, 3, 4, 3, 4, 4, 5,
57 3, 4, 4, 5, 4, 5, 5, 6,
58 1, 2, 2, 3, 2, 3, 3, 4,
59 2, 3, 3, 4, 3, 4, 4, 5,
60 2, 3, 3, 4, 3, 4, 4, 5,
61 3, 4, 4, 5, 4, 5, 5, 6,
62 2, 3, 3, 4, 3, 4, 4, 5,
63 3, 4, 4, 5, 4, 5, 5, 6,
64 3, 4, 4, 5, 4, 5, 5, 6,
65 4, 5, 5, 6, 5, 6, 6, 7,
66 1, 2, 2, 3, 2, 3, 3, 4,
67 2, 3, 3, 4, 3, 4, 4, 5,
68 2, 3, 3, 4, 3, 4, 4, 5,
69 3, 4, 4, 5, 4, 5, 5, 6,
70 2, 3, 3, 4, 3, 4, 4, 5,
71 3, 4, 4, 5, 4, 5, 5, 6,
72 3, 4, 4, 5, 4, 5, 5, 6,
73 4, 5, 5, 6, 5, 6, 6, 7,
74 2, 3, 3, 4, 3, 4, 4, 5,
75 3, 4, 4, 5, 4, 5, 5, 6,
76 3, 4, 4, 5, 4, 5, 5, 6,
77 4, 5, 5, 6, 5, 6, 6, 7,
78 3, 4, 4, 5, 4, 5, 5, 6,
79 4, 5, 5, 6, 5, 6, 6, 7,
80 4, 5, 5, 6, 5, 6, 6, 7,
81 5, 6, 6, 7, 6, 7, 7, 8
82};
83
84int
85low_bit[256] = {
86 -1, 0, 1, 0, 2, 0, 1, 0,
87 3, 0, 1, 0, 2, 0, 1, 0,
88 4, 0, 1, 0, 2, 0, 1, 0,
89 3, 0, 1, 0, 2, 0, 1, 0,
90 5, 0, 1, 0, 2, 0, 1, 0,
91 3, 0, 1, 0, 2, 0, 1, 0,
92 4, 0, 1, 0, 2, 0, 1, 0,
93 3, 0, 1, 0, 2, 0, 1, 0,
94 6, 0, 1, 0, 2, 0, 1, 0,
95 3, 0, 1, 0, 2, 0, 1, 0,
96 4, 0, 1, 0, 2, 0, 1, 0,
97 3, 0, 1, 0, 2, 0, 1, 0,
98 5, 0, 1, 0, 2, 0, 1, 0,
99 3, 0, 1, 0, 2, 0, 1, 0,
100 4, 0, 1, 0, 2, 0, 1, 0,
101 3, 0, 1, 0, 2, 0, 1, 0,
102 7, 0, 1, 0, 2, 0, 1, 0,
103 3, 0, 1, 0, 2, 0, 1, 0,
104 4, 0, 1, 0, 2, 0, 1, 0,
105 3, 0, 1, 0, 2, 0, 1, 0,
106 5, 0, 1, 0, 2, 0, 1, 0,
107 3, 0, 1, 0, 2, 0, 1, 0,
108 4, 0, 1, 0, 2, 0, 1, 0,
109 3, 0, 1, 0, 2, 0, 1, 0,
110 6, 0, 1, 0, 2, 0, 1, 0,
111 3, 0, 1, 0, 2, 0, 1, 0,
112 4, 0, 1, 0, 2, 0, 1, 0,
113 3, 0, 1, 0, 2, 0, 1, 0,
114 5, 0, 1, 0, 2, 0, 1, 0,
115 3, 0, 1, 0, 2, 0, 1, 0,
116 4, 0, 1, 0, 2, 0, 1, 0,
117 3, 0, 1, 0, 2, 0, 1, 0
118};
119
120
121int
122high_bit[256] = {
123 -1, 0, 1, 1, 2, 2, 2, 2,
124 3, 3, 3, 3, 3, 3, 3, 3,
125 4, 4, 4, 4, 4, 4, 4, 4,
126 4, 4, 4, 4, 4, 4, 4, 4,
127 5, 5, 5, 5, 5, 5, 5, 5,
128 5, 5, 5, 5, 5, 5, 5, 5,
129 5, 5, 5, 5, 5, 5, 5, 5,
130 5, 5, 5, 5, 5, 5, 5, 5,
131 6, 6, 6, 6, 6, 6, 6, 6,
132 6, 6, 6, 6, 6, 6, 6, 6,
133 6, 6, 6, 6, 6, 6, 6, 6,
134 6, 6, 6, 6, 6, 6, 6, 6,
135 6, 6, 6, 6, 6, 6, 6, 6,
136 6, 6, 6, 6, 6, 6, 6, 6,
137 6, 6, 6, 6, 6, 6, 6, 6,
138 6, 6, 6, 6, 6, 6, 6, 6,
139 7, 7, 7, 7, 7, 7, 7, 7,
140 7, 7, 7, 7, 7, 7, 7, 7,
141 7, 7, 7, 7, 7, 7, 7, 7,
142 7, 7, 7, 7, 7, 7, 7, 7,
143 7, 7, 7, 7, 7, 7, 7, 7,
144 7, 7, 7, 7, 7, 7, 7, 7,
145 7, 7, 7, 7, 7, 7, 7, 7,
146 7, 7, 7, 7, 7, 7, 7, 7,
147 7, 7, 7, 7, 7, 7, 7, 7,
148 7, 7, 7, 7, 7, 7, 7, 7,
149 7, 7, 7, 7, 7, 7, 7, 7,
150 7, 7, 7, 7, 7, 7, 7, 7,
151 7, 7, 7, 7, 7, 7, 7, 7,
152 7, 7, 7, 7, 7, 7, 7, 7,
153 7, 7, 7, 7, 7, 7, 7, 7,
154 7, 7, 7, 7, 7, 7, 7, 7
155};
156
157int
158octet_get_weight(uint8_t octet) {
159 extern int octet_weight[256];
160
161 return octet_weight[octet];
162}
163
164unsigned char
165v32_weight(v32_t a) {
166 unsigned int wt = 0;
167
168 wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */
169 wt += octet_weight[a.v8[1]];
170 wt += octet_weight[a.v8[2]];
171 wt += octet_weight[a.v8[3]];
172
173 return wt;
174}
175
176inline unsigned char
177v32_distance(v32_t x, v32_t y) {
178 x.value ^= y.value;
179 return v32_weight(x);
180}
181
182unsigned int
183v32_dot_product(v32_t a, v32_t b) {
184 a.value &= b.value;
185 return v32_weight(a) & 1;
186}
187
188/*
189 * _bit_string returns a NULL-terminated character string suitable for
190 * printing
191 */
192
193#define MAX_STRING_LENGTH 1024
194
195char bit_string[MAX_STRING_LENGTH];
196
197char *
198octet_bit_string(uint8_t x) {
199 int mask, index;
200
201 for (mask = 1, index = 0; mask < 256; mask <<= 1)
202 if ((x & mask) == 0)
203 bit_string[index++] = '0';
204 else
205 bit_string[index++] = '1';
206
207 bit_string[index++] = 0; /* NULL terminate string */
208
209 return bit_string;
210}
211
212char *
213v16_bit_string(v16_t x) {
214 int i, mask, index;
215
216 for (i = index = 0; i < 2; i++) {
217 for (mask = 1; mask < 256; mask <<= 1)
218 if ((x.v8[i] & mask) == 0)
219 bit_string[index++] = '0';
220 else
221 bit_string[index++] = '1';
222 }
223 bit_string[index++] = 0; /* NULL terminate string */
224 return bit_string;
225}
226
227char *
228v32_bit_string(v32_t x) {
229 int i, mask, index;
230
231 for (i = index = 0; i < 4; i++) {
232 for (mask = 128; mask > 0; mask >>= 1)
233 if ((x.v8[i] & mask) == 0)
234 bit_string[index++] = '0';
235 else
236 bit_string[index++] = '1';
237 }
238 bit_string[index++] = 0; /* NULL terminate string */
239 return bit_string;
240}
241
242char *
243v64_bit_string(const v64_t *x) {
244 int i, mask, index;
245
246 for (i = index = 0; i < 8; i++) {
247 for (mask = 1; mask < 256; mask <<= 1)
248 if ((x->v8[i] & mask) == 0)
249 bit_string[index++] = '0';
250 else
251 bit_string[index++] = '1';
252 }
253 bit_string[index++] = 0; /* NULL terminate string */
254 return bit_string;
255}
256
257char *
258v128_bit_string(v128_t *x) {
259 int j, index;
260 uint32_t mask;
261
262 for (j=index=0; j < 4; j++) {
263 for (mask=0x80000000; mask > 0; mask >>= 1) {
264 if (x->v32[j] & mask)
265 bit_string[index] = '1';
266 else
267 bit_string[index] = '0';
268 ++index;
269 }
270 }
271 bit_string[128] = 0; /* null terminate string */
272
273 return bit_string;
274}
275
276uint8_t
277nibble_to_hex_char(uint8_t nibble) {
278 char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
279 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
280 return buf[nibble & 0xF];
281}
282
283char *
284octet_hex_string(uint8_t x) {
285
286 bit_string[0] = nibble_to_hex_char(x >> 4);
287 bit_string[1] = nibble_to_hex_char(x & 0xF);
288
289 bit_string[2] = 0; /* null terminate string */
290 return bit_string;
291}
292
293char *
294octet_string_hex_string(const void *str, int length) {
295 const uint8_t *s = str;
296 int i;
297
298 /* double length, since one octet takes two hex characters */
299 length *= 2;
300
301 /* truncate string if it would be too long */
302 if (length > MAX_STRING_LENGTH)
303 length = MAX_STRING_LENGTH-1;
304
305 for (i=0; i < length; i+=2) {
306 bit_string[i] = nibble_to_hex_char(*s >> 4);
307 bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF);
308 }
309 bit_string[i] = 0; /* null terminate string */
310 return bit_string;
311}
312
313char *
314v16_hex_string(v16_t x) {
315 int i, j;
316
317 for (i=j=0; i < 2; i++) {
318 bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
319 bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
320 }
321
322 bit_string[j] = 0; /* null terminate string */
323 return bit_string;
324}
325
326char *
327v32_hex_string(v32_t x) {
328 int i, j;
329
330 for (i=j=0; i < 4; i++) {
331 bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
332 bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
333 }
334
335 bit_string[j] = 0; /* null terminate string */
336 return bit_string;
337}
338
339char *
340v64_hex_string(const v64_t *x) {
341 int i, j;
342
343 for (i=j=0; i < 8; i++) {
344 bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
345 bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
346 }
347
348 bit_string[j] = 0; /* null terminate string */
349 return bit_string;
350}
351
352char *
353v128_hex_string(v128_t *x) {
354 int i, j;
355
356 for (i=j=0; i < 16; i++) {
357 bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
358 bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
359 }
360
361 bit_string[j] = 0; /* null terminate string */
362 return bit_string;
363}
364
365char *
366char_to_hex_string(char *x, int num_char) {
367 int i, j;
368
369 if (num_char >= 16)
370 num_char = 16;
371 for (i=j=0; i < num_char; i++) {
372 bit_string[j++] = nibble_to_hex_char(x[i] >> 4);
373 bit_string[j++] = nibble_to_hex_char(x[i] & 0xF);
374 }
375
376 bit_string[j] = 0; /* null terminate string */
377 return bit_string;
378}
379
380int
381hex_char_to_nibble(uint8_t c) {
382 switch(c) {
383 case ('0'): return 0x0;
384 case ('1'): return 0x1;
385 case ('2'): return 0x2;
386 case ('3'): return 0x3;
387 case ('4'): return 0x4;
388 case ('5'): return 0x5;
389 case ('6'): return 0x6;
390 case ('7'): return 0x7;
391 case ('8'): return 0x8;
392 case ('9'): return 0x9;
393 case ('a'): return 0xa;
394 case ('A'): return 0xa;
395 case ('b'): return 0xb;
396 case ('B'): return 0xb;
397 case ('c'): return 0xc;
398 case ('C'): return 0xc;
399 case ('d'): return 0xd;
400 case ('D'): return 0xd;
401 case ('e'): return 0xe;
402 case ('E'): return 0xe;
403 case ('f'): return 0xf;
404 case ('F'): return 0xf;
405 default: return -1; /* this flags an error */
406 }
407 /* NOTREACHED */
408 return -1; /* this keeps compilers from complaining */
409}
410
411int
412is_hex_string(char *s) {
413 while(*s != 0)
414 if (hex_char_to_nibble(*s++) == -1)
415 return 0;
416 return 1;
417}
418
419uint8_t
420hex_string_to_octet(char *s) {
421 uint8_t x;
422
423 x = (hex_char_to_nibble(s[0]) << 4)
424 | hex_char_to_nibble(s[1] & 0xFF);
425
426 return x;
427}
428
429/*
430 * hex_string_to_octet_string converts a hexadecimal string
431 * of length 2 * len to a raw octet string of length len
432 */
433
434int
435hex_string_to_octet_string(char *raw, char *hex, int len) {
436 uint8_t x;
437 int tmp;
438 int hex_len;
439
440 hex_len = 0;
441 while (hex_len < len) {
442 tmp = hex_char_to_nibble(hex[0]);
443 if (tmp == -1)
444 return hex_len;
445 x = (tmp << 4);
446 hex_len++;
447 tmp = hex_char_to_nibble(hex[1]);
448 if (tmp == -1)
449 return hex_len;
450 x |= (tmp & 0xff);
451 hex_len++;
452 *raw++ = x;
453 hex += 2;
454 }
455 return hex_len;
456}
457
458v16_t
459hex_string_to_v16(char *s) {
460 v16_t x;
461 int i, j;
462
463 for (i=j=0; i < 4; i += 2, j++) {
464 x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
465 | hex_char_to_nibble(s[i+1] & 0xFF);
466 }
467 return x;
468}
469
470v32_t
471hex_string_to_v32(char *s) {
472 v32_t x;
473 int i, j;
474
475 for (i=j=0; i < 8; i += 2, j++) {
476 x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
477 | hex_char_to_nibble(s[i+1] & 0xFF);
478 }
479 return x;
480}
481
482v64_t
483hex_string_to_v64(char *s) {
484 v64_t x;
485 int i, j;
486
487 for (i=j=0; i < 16; i += 2, j++) {
488 x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
489 | hex_char_to_nibble(s[i+1] & 0xFF);
490 }
491 return x;
492}
493
494v128_t
495hex_string_to_v128(char *s) {
496 v128_t x;
497 int i, j;
498
499 for (i=j=0; i < 32; i += 2, j++) {
500 x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
501 | hex_char_to_nibble(s[i+1] & 0xFF);
502 }
503 return x;
504}
505
506
507
508/*
509 * the matrix A[] is stored in column format, i.e., A[i] is the ith
510 * column of the matrix
511 */
512
513uint8_t
514A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
515 int index = 0;
516 unsigned mask;
517
518 for (mask=1; mask < 256; mask *= 2) {
519 if (x & mask)
520 b^= A[index];
521 ++index;
522 }
523
524 return b;
525}
526
527inline void
528v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
529 x->v8[0] = s[0];
530 x->v8[1] = s[1];
531}
532
533inline void
534v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
535 x->v8[0] = s[0];
536 x->v8[1] = s[1];
537 x->v8[2] = s[2];
538 x->v8[3] = s[3];
539}
540
541inline void
542v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
543 x->v8[0] = s[0];
544 x->v8[1] = s[1];
545 x->v8[2] = s[2];
546 x->v8[3] = s[3];
547 x->v8[4] = s[4];
548 x->v8[5] = s[5];
549 x->v8[6] = s[6];
550 x->v8[7] = s[7];
551}
552
553void
554v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
555 x->v8[0] = s[0];
556 x->v8[1] = s[1];
557 x->v8[2] = s[2];
558 x->v8[3] = s[3];
559 x->v8[4] = s[4];
560 x->v8[5] = s[5];
561 x->v8[6] = s[6];
562 x->v8[7] = s[7];
563 x->v8[8] = s[8];
564 x->v8[9] = s[9];
565 x->v8[10] = s[10];
566 x->v8[11] = s[11];
567 x->v8[12] = s[12];
568 x->v8[13] = s[13];
569 x->v8[14] = s[14];
570 x->v8[15] = s[15];
571
572}
573
574#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
575
576void
577v128_set_to_zero(v128_t *x) {
578 _v128_set_to_zero(x);
579}
580
581void
582v128_copy(v128_t *x, const v128_t *y) {
583 _v128_copy(x, y);
584}
585
586void
587v128_xor(v128_t *z, v128_t *x, v128_t *y) {
588 _v128_xor(z, x, y);
589}
590
591void
592v128_and(v128_t *z, v128_t *x, v128_t *y) {
593 _v128_and(z, x, y);
594}
595
596void
597v128_or(v128_t *z, v128_t *x, v128_t *y) {
598 _v128_or(z, x, y);
599}
600
601void
602v128_complement(v128_t *x) {
603 _v128_complement(x);
604}
605
606int
607v128_is_eq(const v128_t *x, const v128_t *y) {
608 return _v128_is_eq(x, y);
609}
610
611int
612v128_get_bit(const v128_t *x, int i) {
613 return _v128_get_bit(x, i);
614}
615
616void
617v128_set_bit(v128_t *x, int i) {
618 _v128_set_bit(x, i);
619}
620
621void
622v128_clear_bit(v128_t *x, int i){
623 _v128_clear_bit(x, i);
624}
625
626void
627v128_set_bit_to(v128_t *x, int i, int y){
628 _v128_set_bit_to(x, i, y);
629}
630
631
632#endif /* DATATYPES_USE_MACROS */
633
634
635inline void
636v128_left_shift2(v128_t *x, int num_bits) {
637 int i;
638 int word_shift = num_bits >> 5;
639 int bit_shift = num_bits & 31;
640
641 for (i=0; i < (4-word_shift); i++) {
642 x->v32[i] = x->v32[i+word_shift] << bit_shift;
643 }
644
645 for ( ; i < word_shift; i++) {
646 x->v32[i] = 0;
647 }
648
649}
650
651void
652v128_right_shift(v128_t *x, int index) {
653 const int base_index = index >> 5;
654 const int bit_index = index & 31;
655 int i, from;
656 uint32_t b;
657
658 if (index > 127) {
659 v128_set_to_zero(x);
660 return;
661 }
662
663 if (bit_index == 0) {
664
665 /* copy each word from left size to right side */
666 x->v32[4-1] = x->v32[4-1-base_index];
667 for (i=4-1; i > base_index; i--)
668 x->v32[i-1] = x->v32[i-1-base_index];
669
670 } else {
671
672 /* set each word to the "or" of the two bit-shifted words */
673 for (i = 4; i > base_index; i--) {
674 from = i-1 - base_index;
675 b = x->v32[from] << bit_index;
676 if (from > 0)
677 b |= x->v32[from-1] >> (32-bit_index);
678 x->v32[i-1] = b;
679 }
680
681 }
682
683 /* now wrap up the final portion */
684 for (i=0; i < base_index; i++)
685 x->v32[i] = 0;
686
687}
688
689void
690v128_left_shift(v128_t *x, int index) {
691 int i;
692 const int base_index = index >> 5;
693 const int bit_index = index & 31;
694
695 if (index > 127) {
696 v128_set_to_zero(x);
697 return;
698 }
699
700 if (bit_index == 0) {
701 for (i=0; i < 4 - base_index; i++)
702 x->v32[i] = x->v32[i+base_index];
703 } else {
704 for (i=0; i < 4 - base_index - 1; i++)
705 x->v32[i] = (x->v32[i+base_index] << bit_index) ^
706 (x->v32[i+base_index+1] >> (32 - bit_index));
707 x->v32[4 - base_index-1] = x->v32[4-1] << bit_index;
708 }
709
710 /* now wrap up the final portion */
711 for (i = 4 - base_index; i < 4; i++)
712 x->v32[i] = 0;
713
714}
715
716
717#if 0
718void
719v128_add(v128_t *z, v128_t *x, v128_t *y) {
720 /* integer addition modulo 2^128 */
721
722#ifdef WORDS_BIGENDIAN
723 uint64_t tmp;
724
725 tmp = x->v32[3] + y->v32[3];
726 z->v32[3] = (uint32_t) tmp;
727
728 tmp = x->v32[2] + y->v32[2] + (tmp >> 32);
729 z->v32[2] = (uint32_t) tmp;
730
731 tmp = x->v32[1] + y->v32[1] + (tmp >> 32);
732 z->v32[1] = (uint32_t) tmp;
733
734 tmp = x->v32[0] + y->v32[0] + (tmp >> 32);
735 z->v32[0] = (uint32_t) tmp;
736
737#else /* assume little endian architecture */
738 uint64_t tmp;
739
740 tmp = htonl(x->v32[3]) + htonl(y->v32[3]);
741 z->v32[3] = ntohl((uint32_t) tmp);
742
743 tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32);
744 z->v32[2] = ntohl((uint32_t) tmp);
745
746 tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32);
747 z->v32[1] = ntohl((uint32_t) tmp);
748
749 tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32);
750 z->v32[0] = ntohl((uint32_t) tmp);
751
752#endif /* WORDS_BIGENDIAN */
753
754}
755#endif
756
757int
758octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
759 uint8_t *end = b + len;
760 while (b < end)
761 if (*a++ != *b++)
762 return 1;
763 return 0;
764}
765
766void
767octet_string_set_to_zero(uint8_t *s, int len) {
768 uint8_t *end = s + len;
769
770 do {
771 *s = 0;
772 } while (++s < end);
773
774}
775
776/* functions manipulating bit_vector_t */
777
778#define BITVECTOR_MAX_WORDS 5
779
780int
781bitvector_alloc(bitvector_t *v, unsigned long length) {
782 unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;
783 int i;
784
785 /* allocate memory, then set parameters */
786 if (l > BITVECTOR_MAX_WORDS)
787 return -1;
788 else
789 l = BITVECTOR_MAX_WORDS;
790 v->word = malloc(l);
791 if (v->word == NULL)
792 return -1;
793 v->length = length;
794
795 /* initialize bitvector to zero */
796 for (i=0; i < (length >> 5); i++) {
797 v->word = 0;
798 }
799
800 return 0;
801}
802
803void
804bitvector_set_bit(bitvector_t *v, int bit_index) {
805
806 v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));
807
808}
809
810int
811bitvector_get_bit(const bitvector_t *v, int bit_index) {
812
813 return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;
814
815}
816
817#include <stdio.h>
818
819int
820bitvector_print_hex(const bitvector_t *v, FILE *stream) {
821 int i;
822 int m = v->length >> 5;
823 int n = v->length & 31;
824 char string[9];
825 uint32_t tmp;
826
827 /* if length isn't a multiple of four, we can't hex_print */
828 if (n & 3)
829 return -1;
830
831 /* if the length is zero, do nothing */
832 if (v->length == 0)
833 return 0;
834
835 /*
836 * loop over words from most significant to least significant -
837 */
838
839 for (i=m; i > 0; i++) {
840 char *str = string + 7;
841 tmp = v->word[i];
842
843 /* null terminate string */
844 string[8] = 0;
845
846 /* loop over nibbles */
847 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
848 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
849 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
850 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
851 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
852 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
853 *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
854 *str-- = nibble_to_hex_char(tmp & 0xf);
855
856 /* now print stream */
857 fprintf(stream, string);
858 }
859
860 return 0;
861
862}
863
864
865int
866hex_string_length(char *s) {
867 int count = 0;
868
869 /* ignore leading zeros */
870 while ((*s != 0) && *s == '0')
871 s++;
872
873 /* count remaining characters */
874 while (*s != 0) {
875 if (hex_char_to_nibble(*s++) == -1)
876 return -1;
877 count++;
878 }
879
880 return count;
881}
882
883int
884bitvector_set_from_hex(bitvector_t *v, char *string) {
885 int num_hex_chars, m, n, i, j;
886 uint32_t tmp;
887
888 num_hex_chars = hex_string_length(string);
889 if (num_hex_chars == -1)
890 return -1;
891
892 /* set length */
893 v->length = num_hex_chars * 4;
894 /*
895 * at this point, we should subtract away a bit if the high
896 * bit of the first character is zero, but we ignore that
897 * for now and assume that we're four-bit aligned - DAM
898 */
899
900
901 m = num_hex_chars / 8; /* number of words */
902 n = num_hex_chars % 8; /* number of nibbles in last word */
903
904 /* if the length is greater than the bitvector, return an error */
905 if (m > BITVECTOR_MAX_WORDS)
906 return -1;
907
908 /*
909 * loop over words from most significant - first word is a special
910 * case
911 */
912
913 if (n) {
914 tmp = 0;
915 for (i=0; i < n; i++) {
916 tmp = hex_char_to_nibble(*string++);
917 tmp <<= 4;
918 }
919 v->word[m] = tmp;
920 }
921
922 /* now loop over the rest of the words */
923 for (i=m-1; i >= 0; i--) {
924 tmp = 0;
925 for (j=0; j < 8; j++) {
926 tmp = hex_char_to_nibble(*string++);
927 tmp <<= 4;
928 }
929 v->word[i] = tmp;
930 }
931
932 return 0;
933}
934
935
936/* functions below not yet tested! */
937
938int
939v32_low_bit(v32_t *w) {
940 int value;
941
942 value = low_bit[w->v8[0]];
943 if (value != -1)
944 return value;
945 value = low_bit[w->v8[1]];
946 if (value != -1)
947 return value + 8;
948 value = low_bit[w->v8[2]];
949 if (value != -1)
950 return value + 16;
951 value = low_bit[w->v8[3]];
952 if (value == -1)
953 return -1;
954 return value + 24;
955}
956
957/* high_bit not done yet */
958
959
960
961
962