OLD | NEW |
| (Empty) |
1 /* | |
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 #ifdef HAVE_CONFIG_H | |
46 #include <config.h> | |
47 #endif | |
48 | |
49 #include "crypto_math.h" | |
50 | |
51 int | |
52 octet_weight[256] = { | |
53 0, 1, 1, 2, 1, 2, 2, 3, | |
54 1, 2, 2, 3, 2, 3, 3, 4, | |
55 1, 2, 2, 3, 2, 3, 3, 4, | |
56 2, 3, 3, 4, 3, 4, 4, 5, | |
57 1, 2, 2, 3, 2, 3, 3, 4, | |
58 2, 3, 3, 4, 3, 4, 4, 5, | |
59 2, 3, 3, 4, 3, 4, 4, 5, | |
60 3, 4, 4, 5, 4, 5, 5, 6, | |
61 1, 2, 2, 3, 2, 3, 3, 4, | |
62 2, 3, 3, 4, 3, 4, 4, 5, | |
63 2, 3, 3, 4, 3, 4, 4, 5, | |
64 3, 4, 4, 5, 4, 5, 5, 6, | |
65 2, 3, 3, 4, 3, 4, 4, 5, | |
66 3, 4, 4, 5, 4, 5, 5, 6, | |
67 3, 4, 4, 5, 4, 5, 5, 6, | |
68 4, 5, 5, 6, 5, 6, 6, 7, | |
69 1, 2, 2, 3, 2, 3, 3, 4, | |
70 2, 3, 3, 4, 3, 4, 4, 5, | |
71 2, 3, 3, 4, 3, 4, 4, 5, | |
72 3, 4, 4, 5, 4, 5, 5, 6, | |
73 2, 3, 3, 4, 3, 4, 4, 5, | |
74 3, 4, 4, 5, 4, 5, 5, 6, | |
75 3, 4, 4, 5, 4, 5, 5, 6, | |
76 4, 5, 5, 6, 5, 6, 6, 7, | |
77 2, 3, 3, 4, 3, 4, 4, 5, | |
78 3, 4, 4, 5, 4, 5, 5, 6, | |
79 3, 4, 4, 5, 4, 5, 5, 6, | |
80 4, 5, 5, 6, 5, 6, 6, 7, | |
81 3, 4, 4, 5, 4, 5, 5, 6, | |
82 4, 5, 5, 6, 5, 6, 6, 7, | |
83 4, 5, 5, 6, 5, 6, 6, 7, | |
84 5, 6, 6, 7, 6, 7, 7, 8 | |
85 }; | |
86 | |
87 int | |
88 low_bit[256] = { | |
89 -1, 0, 1, 0, 2, 0, 1, 0, | |
90 3, 0, 1, 0, 2, 0, 1, 0, | |
91 4, 0, 1, 0, 2, 0, 1, 0, | |
92 3, 0, 1, 0, 2, 0, 1, 0, | |
93 5, 0, 1, 0, 2, 0, 1, 0, | |
94 3, 0, 1, 0, 2, 0, 1, 0, | |
95 4, 0, 1, 0, 2, 0, 1, 0, | |
96 3, 0, 1, 0, 2, 0, 1, 0, | |
97 6, 0, 1, 0, 2, 0, 1, 0, | |
98 3, 0, 1, 0, 2, 0, 1, 0, | |
99 4, 0, 1, 0, 2, 0, 1, 0, | |
100 3, 0, 1, 0, 2, 0, 1, 0, | |
101 5, 0, 1, 0, 2, 0, 1, 0, | |
102 3, 0, 1, 0, 2, 0, 1, 0, | |
103 4, 0, 1, 0, 2, 0, 1, 0, | |
104 3, 0, 1, 0, 2, 0, 1, 0, | |
105 7, 0, 1, 0, 2, 0, 1, 0, | |
106 3, 0, 1, 0, 2, 0, 1, 0, | |
107 4, 0, 1, 0, 2, 0, 1, 0, | |
108 3, 0, 1, 0, 2, 0, 1, 0, | |
109 5, 0, 1, 0, 2, 0, 1, 0, | |
110 3, 0, 1, 0, 2, 0, 1, 0, | |
111 4, 0, 1, 0, 2, 0, 1, 0, | |
112 3, 0, 1, 0, 2, 0, 1, 0, | |
113 6, 0, 1, 0, 2, 0, 1, 0, | |
114 3, 0, 1, 0, 2, 0, 1, 0, | |
115 4, 0, 1, 0, 2, 0, 1, 0, | |
116 3, 0, 1, 0, 2, 0, 1, 0, | |
117 5, 0, 1, 0, 2, 0, 1, 0, | |
118 3, 0, 1, 0, 2, 0, 1, 0, | |
119 4, 0, 1, 0, 2, 0, 1, 0, | |
120 3, 0, 1, 0, 2, 0, 1, 0 | |
121 }; | |
122 | |
123 | |
124 int | |
125 high_bit[256] = { | |
126 -1, 0, 1, 1, 2, 2, 2, 2, | |
127 3, 3, 3, 3, 3, 3, 3, 3, | |
128 4, 4, 4, 4, 4, 4, 4, 4, | |
129 4, 4, 4, 4, 4, 4, 4, 4, | |
130 5, 5, 5, 5, 5, 5, 5, 5, | |
131 5, 5, 5, 5, 5, 5, 5, 5, | |
132 5, 5, 5, 5, 5, 5, 5, 5, | |
133 5, 5, 5, 5, 5, 5, 5, 5, | |
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 6, 6, 6, 6, 6, 6, 6, 6, | |
140 6, 6, 6, 6, 6, 6, 6, 6, | |
141 6, 6, 6, 6, 6, 6, 6, 6, | |
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 7, 7, 7, 7, 7, 7, 7, 7, | |
156 7, 7, 7, 7, 7, 7, 7, 7, | |
157 7, 7, 7, 7, 7, 7, 7, 7 | |
158 }; | |
159 | |
160 int | |
161 octet_get_weight(uint8_t octet) { | |
162 extern int octet_weight[256]; | |
163 | |
164 return octet_weight[octet]; | |
165 } | |
166 | |
167 unsigned char | |
168 v32_weight(v32_t a) { | |
169 unsigned int wt = 0; | |
170 | |
171 wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */ | |
172 wt += octet_weight[a.v8[1]]; | |
173 wt += octet_weight[a.v8[2]]; | |
174 wt += octet_weight[a.v8[3]]; | |
175 | |
176 return wt; | |
177 } | |
178 | |
179 unsigned char | |
180 v32_distance(v32_t x, v32_t y) { | |
181 x.value ^= y.value; | |
182 return v32_weight(x); | |
183 } | |
184 | |
185 unsigned int | |
186 v32_dot_product(v32_t a, v32_t b) { | |
187 a.value &= b.value; | |
188 return v32_weight(a) & 1; | |
189 } | |
190 | |
191 /* | |
192 * _bit_string returns a NULL-terminated character string suitable for | |
193 * printing | |
194 */ | |
195 | |
196 #define MAX_STRING_LENGTH 1024 | |
197 | |
198 char bit_string[MAX_STRING_LENGTH]; | |
199 | |
200 char * | |
201 octet_bit_string(uint8_t x) { | |
202 int mask, index; | |
203 | |
204 for (mask = 1, index = 0; mask < 256; mask <<= 1) | |
205 if ((x & mask) == 0) | |
206 bit_string[index++] = '0'; | |
207 else | |
208 bit_string[index++] = '1'; | |
209 | |
210 bit_string[index++] = 0; /* NULL terminate string */ | |
211 | |
212 return bit_string; | |
213 } | |
214 | |
215 char * | |
216 v16_bit_string(v16_t x) { | |
217 int i, mask, index; | |
218 | |
219 for (i = index = 0; i < 2; i++) { | |
220 for (mask = 1; mask < 256; mask <<= 1) | |
221 if ((x.v8[i] & mask) == 0) | |
222 bit_string[index++] = '0'; | |
223 else | |
224 bit_string[index++] = '1'; | |
225 } | |
226 bit_string[index++] = 0; /* NULL terminate string */ | |
227 return bit_string; | |
228 } | |
229 | |
230 char * | |
231 v32_bit_string(v32_t x) { | |
232 int i, mask, index; | |
233 | |
234 for (i = index = 0; i < 4; i++) { | |
235 for (mask = 128; mask > 0; mask >>= 1) | |
236 if ((x.v8[i] & mask) == 0) | |
237 bit_string[index++] = '0'; | |
238 else | |
239 bit_string[index++] = '1'; | |
240 } | |
241 bit_string[index++] = 0; /* NULL terminate string */ | |
242 return bit_string; | |
243 } | |
244 | |
245 char * | |
246 v64_bit_string(const v64_t *x) { | |
247 int i, mask, index; | |
248 | |
249 for (i = index = 0; i < 8; i++) { | |
250 for (mask = 1; mask < 256; mask <<= 1) | |
251 if ((x->v8[i] & mask) == 0) | |
252 bit_string[index++] = '0'; | |
253 else | |
254 bit_string[index++] = '1'; | |
255 } | |
256 bit_string[index++] = 0; /* NULL terminate string */ | |
257 return bit_string; | |
258 } | |
259 | |
260 char * | |
261 v128_bit_string(v128_t *x) { | |
262 int j, index; | |
263 uint32_t mask; | |
264 | |
265 for (j=index=0; j < 4; j++) { | |
266 for (mask=0x80000000; mask > 0; mask >>= 1) { | |
267 if (x->v32[j] & mask) | |
268 bit_string[index] = '1'; | |
269 else | |
270 bit_string[index] = '0'; | |
271 ++index; | |
272 } | |
273 } | |
274 bit_string[128] = 0; /* null terminate string */ | |
275 | |
276 return bit_string; | |
277 } | |
278 | |
279 uint8_t | |
280 nibble_to_hex_char(uint8_t nibble) { | |
281 char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', | |
282 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; | |
283 return buf[nibble & 0xF]; | |
284 } | |
285 | |
286 char * | |
287 octet_hex_string(uint8_t x) { | |
288 | |
289 bit_string[0] = nibble_to_hex_char(x >> 4); | |
290 bit_string[1] = nibble_to_hex_char(x & 0xF); | |
291 | |
292 bit_string[2] = 0; /* null terminate string */ | |
293 return bit_string; | |
294 } | |
295 | |
296 char * | |
297 octet_string_hex_string(const void *str, int length) { | |
298 const uint8_t *s = str; | |
299 int i; | |
300 | |
301 /* double length, since one octet takes two hex characters */ | |
302 length *= 2; | |
303 | |
304 /* truncate string if it would be too long */ | |
305 if (length > MAX_STRING_LENGTH) | |
306 length = MAX_STRING_LENGTH-1; | |
307 | |
308 for (i=0; i < length; i+=2) { | |
309 bit_string[i] = nibble_to_hex_char(*s >> 4); | |
310 bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF); | |
311 } | |
312 bit_string[i] = 0; /* null terminate string */ | |
313 return bit_string; | |
314 } | |
315 | |
316 char * | |
317 v16_hex_string(v16_t x) { | |
318 int i, j; | |
319 | |
320 for (i=j=0; i < 2; i++) { | |
321 bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); | |
322 bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); | |
323 } | |
324 | |
325 bit_string[j] = 0; /* null terminate string */ | |
326 return bit_string; | |
327 } | |
328 | |
329 char * | |
330 v32_hex_string(v32_t x) { | |
331 int i, j; | |
332 | |
333 for (i=j=0; i < 4; i++) { | |
334 bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); | |
335 bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); | |
336 } | |
337 | |
338 bit_string[j] = 0; /* null terminate string */ | |
339 return bit_string; | |
340 } | |
341 | |
342 char * | |
343 v64_hex_string(const v64_t *x) { | |
344 int i, j; | |
345 | |
346 for (i=j=0; i < 8; i++) { | |
347 bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); | |
348 bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); | |
349 } | |
350 | |
351 bit_string[j] = 0; /* null terminate string */ | |
352 return bit_string; | |
353 } | |
354 | |
355 char * | |
356 v128_hex_string(v128_t *x) { | |
357 int i, j; | |
358 | |
359 for (i=j=0; i < 16; i++) { | |
360 bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); | |
361 bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); | |
362 } | |
363 | |
364 bit_string[j] = 0; /* null terminate string */ | |
365 return bit_string; | |
366 } | |
367 | |
368 char * | |
369 char_to_hex_string(char *x, int num_char) { | |
370 int i, j; | |
371 | |
372 if (num_char >= 16) | |
373 num_char = 16; | |
374 for (i=j=0; i < num_char; i++) { | |
375 bit_string[j++] = nibble_to_hex_char(x[i] >> 4); | |
376 bit_string[j++] = nibble_to_hex_char(x[i] & 0xF); | |
377 } | |
378 | |
379 bit_string[j] = 0; /* null terminate string */ | |
380 return bit_string; | |
381 } | |
382 | |
383 int | |
384 hex_char_to_nibble(uint8_t c) { | |
385 switch(c) { | |
386 case ('0'): return 0x0; | |
387 case ('1'): return 0x1; | |
388 case ('2'): return 0x2; | |
389 case ('3'): return 0x3; | |
390 case ('4'): return 0x4; | |
391 case ('5'): return 0x5; | |
392 case ('6'): return 0x6; | |
393 case ('7'): return 0x7; | |
394 case ('8'): return 0x8; | |
395 case ('9'): return 0x9; | |
396 case ('a'): return 0xa; | |
397 case ('A'): return 0xa; | |
398 case ('b'): return 0xb; | |
399 case ('B'): return 0xb; | |
400 case ('c'): return 0xc; | |
401 case ('C'): return 0xc; | |
402 case ('d'): return 0xd; | |
403 case ('D'): return 0xd; | |
404 case ('e'): return 0xe; | |
405 case ('E'): return 0xe; | |
406 case ('f'): return 0xf; | |
407 case ('F'): return 0xf; | |
408 default: return -1; /* this flags an error */ | |
409 } | |
410 /* NOTREACHED */ | |
411 return -1; /* this keeps compilers from complaining */ | |
412 } | |
413 | |
414 int | |
415 is_hex_string(char *s) { | |
416 while(*s != 0) | |
417 if (hex_char_to_nibble(*s++) == -1) | |
418 return 0; | |
419 return 1; | |
420 } | |
421 | |
422 uint8_t | |
423 hex_string_to_octet(char *s) { | |
424 uint8_t x; | |
425 | |
426 x = (hex_char_to_nibble(s[0]) << 4) | |
427 | hex_char_to_nibble(s[1] & 0xFF); | |
428 | |
429 return x; | |
430 } | |
431 | |
432 /* | |
433 * hex_string_to_octet_string converts a hexadecimal string | |
434 * of length 2 * len to a raw octet string of length len | |
435 */ | |
436 | |
437 int | |
438 hex_string_to_octet_string(char *raw, char *hex, int len) { | |
439 uint8_t x; | |
440 int tmp; | |
441 int hex_len; | |
442 | |
443 hex_len = 0; | |
444 while (hex_len < len) { | |
445 tmp = hex_char_to_nibble(hex[0]); | |
446 if (tmp == -1) | |
447 return hex_len; | |
448 x = (tmp << 4); | |
449 hex_len++; | |
450 tmp = hex_char_to_nibble(hex[1]); | |
451 if (tmp == -1) | |
452 return hex_len; | |
453 x |= (tmp & 0xff); | |
454 hex_len++; | |
455 *raw++ = x; | |
456 hex += 2; | |
457 } | |
458 return hex_len; | |
459 } | |
460 | |
461 v16_t | |
462 hex_string_to_v16(char *s) { | |
463 v16_t x; | |
464 int i, j; | |
465 | |
466 for (i=j=0; i < 4; i += 2, j++) { | |
467 x.v8[j] = (hex_char_to_nibble(s[i]) << 4) | |
468 | hex_char_to_nibble(s[i+1] & 0xFF); | |
469 } | |
470 return x; | |
471 } | |
472 | |
473 v32_t | |
474 hex_string_to_v32(char *s) { | |
475 v32_t x; | |
476 int i, j; | |
477 | |
478 for (i=j=0; i < 8; i += 2, j++) { | |
479 x.v8[j] = (hex_char_to_nibble(s[i]) << 4) | |
480 | hex_char_to_nibble(s[i+1] & 0xFF); | |
481 } | |
482 return x; | |
483 } | |
484 | |
485 v64_t | |
486 hex_string_to_v64(char *s) { | |
487 v64_t x; | |
488 int i, j; | |
489 | |
490 for (i=j=0; i < 16; i += 2, j++) { | |
491 x.v8[j] = (hex_char_to_nibble(s[i]) << 4) | |
492 | hex_char_to_nibble(s[i+1] & 0xFF); | |
493 } | |
494 return x; | |
495 } | |
496 | |
497 v128_t | |
498 hex_string_to_v128(char *s) { | |
499 v128_t x; | |
500 int i, j; | |
501 | |
502 for (i=j=0; i < 32; i += 2, j++) { | |
503 x.v8[j] = (hex_char_to_nibble(s[i]) << 4) | |
504 | hex_char_to_nibble(s[i+1] & 0xFF); | |
505 } | |
506 return x; | |
507 } | |
508 | |
509 | |
510 | |
511 /* | |
512 * the matrix A[] is stored in column format, i.e., A[i] is the ith | |
513 * column of the matrix | |
514 */ | |
515 | |
516 uint8_t | |
517 A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) { | |
518 int index = 0; | |
519 unsigned mask; | |
520 | |
521 for (mask=1; mask < 256; mask *= 2) { | |
522 if (x & mask) | |
523 b^= A[index]; | |
524 ++index; | |
525 } | |
526 | |
527 return b; | |
528 } | |
529 | |
530 void | |
531 v16_copy_octet_string(v16_t *x, const uint8_t s[2]) { | |
532 x->v8[0] = s[0]; | |
533 x->v8[1] = s[1]; | |
534 } | |
535 | |
536 void | |
537 v32_copy_octet_string(v32_t *x, const uint8_t s[4]) { | |
538 x->v8[0] = s[0]; | |
539 x->v8[1] = s[1]; | |
540 x->v8[2] = s[2]; | |
541 x->v8[3] = s[3]; | |
542 } | |
543 | |
544 void | |
545 v64_copy_octet_string(v64_t *x, const uint8_t s[8]) { | |
546 x->v8[0] = s[0]; | |
547 x->v8[1] = s[1]; | |
548 x->v8[2] = s[2]; | |
549 x->v8[3] = s[3]; | |
550 x->v8[4] = s[4]; | |
551 x->v8[5] = s[5]; | |
552 x->v8[6] = s[6]; | |
553 x->v8[7] = s[7]; | |
554 } | |
555 | |
556 void | |
557 v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { | |
558 x->v8[0] = s[0]; | |
559 x->v8[1] = s[1]; | |
560 x->v8[2] = s[2]; | |
561 x->v8[3] = s[3]; | |
562 x->v8[4] = s[4]; | |
563 x->v8[5] = s[5]; | |
564 x->v8[6] = s[6]; | |
565 x->v8[7] = s[7]; | |
566 x->v8[8] = s[8]; | |
567 x->v8[9] = s[9]; | |
568 x->v8[10] = s[10]; | |
569 x->v8[11] = s[11]; | |
570 x->v8[12] = s[12]; | |
571 x->v8[13] = s[13]; | |
572 x->v8[14] = s[14]; | |
573 x->v8[15] = s[15]; | |
574 | |
575 } | |
576 | |
577 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */ | |
578 | |
579 void | |
580 v128_set_to_zero(v128_t *x) { | |
581 _v128_set_to_zero(x); | |
582 } | |
583 | |
584 void | |
585 v128_copy(v128_t *x, const v128_t *y) { | |
586 _v128_copy(x, y); | |
587 } | |
588 | |
589 void | |
590 v128_xor(v128_t *z, v128_t *x, v128_t *y) { | |
591 _v128_xor(z, x, y); | |
592 } | |
593 | |
594 void | |
595 v128_and(v128_t *z, v128_t *x, v128_t *y) { | |
596 _v128_and(z, x, y); | |
597 } | |
598 | |
599 void | |
600 v128_or(v128_t *z, v128_t *x, v128_t *y) { | |
601 _v128_or(z, x, y); | |
602 } | |
603 | |
604 void | |
605 v128_complement(v128_t *x) { | |
606 _v128_complement(x); | |
607 } | |
608 | |
609 int | |
610 v128_is_eq(const v128_t *x, const v128_t *y) { | |
611 return _v128_is_eq(x, y); | |
612 } | |
613 | |
614 int | |
615 v128_get_bit(const v128_t *x, int i) { | |
616 return _v128_get_bit(x, i); | |
617 } | |
618 | |
619 void | |
620 v128_set_bit(v128_t *x, int i) { | |
621 _v128_set_bit(x, i); | |
622 } | |
623 | |
624 void | |
625 v128_clear_bit(v128_t *x, int i){ | |
626 _v128_clear_bit(x, i); | |
627 } | |
628 | |
629 void | |
630 v128_set_bit_to(v128_t *x, int i, int y){ | |
631 _v128_set_bit_to(x, i, y); | |
632 } | |
633 | |
634 | |
635 #endif /* DATATYPES_USE_MACROS */ | |
636 | |
637 | |
638 static inline void | |
639 v128_left_shift2(v128_t *x, int num_bits) { | |
640 int i; | |
641 int word_shift = num_bits >> 5; | |
642 int bit_shift = num_bits & 31; | |
643 | |
644 for (i=0; i < (4-word_shift); i++) { | |
645 x->v32[i] = x->v32[i+word_shift] << bit_shift; | |
646 } | |
647 | |
648 for ( ; i < word_shift; i++) { | |
649 x->v32[i] = 0; | |
650 } | |
651 | |
652 } | |
653 | |
654 void | |
655 v128_right_shift(v128_t *x, int index) { | |
656 const int base_index = index >> 5; | |
657 const int bit_index = index & 31; | |
658 int i, from; | |
659 uint32_t b; | |
660 | |
661 if (index > 127) { | |
662 v128_set_to_zero(x); | |
663 return; | |
664 } | |
665 | |
666 if (bit_index == 0) { | |
667 | |
668 /* copy each word from left size to right side */ | |
669 x->v32[4-1] = x->v32[4-1-base_index]; | |
670 for (i=4-1; i > base_index; i--) | |
671 x->v32[i-1] = x->v32[i-1-base_index]; | |
672 | |
673 } else { | |
674 | |
675 /* set each word to the "or" of the two bit-shifted words */ | |
676 for (i = 4; i > base_index; i--) { | |
677 from = i-1 - base_index; | |
678 b = x->v32[from] << bit_index; | |
679 if (from > 0) | |
680 b |= x->v32[from-1] >> (32-bit_index); | |
681 x->v32[i-1] = b; | |
682 } | |
683 | |
684 } | |
685 | |
686 /* now wrap up the final portion */ | |
687 for (i=0; i < base_index; i++) | |
688 x->v32[i] = 0; | |
689 | |
690 } | |
691 | |
692 void | |
693 v128_left_shift(v128_t *x, int index) { | |
694 int i; | |
695 const int base_index = index >> 5; | |
696 const int bit_index = index & 31; | |
697 | |
698 if (index > 127) { | |
699 v128_set_to_zero(x); | |
700 return; | |
701 } | |
702 | |
703 if (bit_index == 0) { | |
704 for (i=0; i < 4 - base_index; i++) | |
705 x->v32[i] = x->v32[i+base_index]; | |
706 } else { | |
707 for (i=0; i < 4 - base_index - 1; i++) | |
708 x->v32[i] = (x->v32[i+base_index] << bit_index) ^ | |
709 (x->v32[i+base_index+1] >> (32 - bit_index)); | |
710 x->v32[4 - base_index-1] = x->v32[4-1] << bit_index; | |
711 } | |
712 | |
713 /* now wrap up the final portion */ | |
714 for (i = 4 - base_index; i < 4; i++) | |
715 x->v32[i] = 0; | |
716 | |
717 } | |
718 | |
719 | |
720 #if 0 | |
721 void | |
722 v128_add(v128_t *z, v128_t *x, v128_t *y) { | |
723 /* integer addition modulo 2^128 */ | |
724 | |
725 #ifdef WORDS_BIGENDIAN | |
726 uint64_t tmp; | |
727 | |
728 tmp = x->v32[3] + y->v32[3]; | |
729 z->v32[3] = (uint32_t) tmp; | |
730 | |
731 tmp = x->v32[2] + y->v32[2] + (tmp >> 32); | |
732 z->v32[2] = (uint32_t) tmp; | |
733 | |
734 tmp = x->v32[1] + y->v32[1] + (tmp >> 32); | |
735 z->v32[1] = (uint32_t) tmp; | |
736 | |
737 tmp = x->v32[0] + y->v32[0] + (tmp >> 32); | |
738 z->v32[0] = (uint32_t) tmp; | |
739 | |
740 #else /* assume little endian architecture */ | |
741 uint64_t tmp; | |
742 | |
743 tmp = htonl(x->v32[3]) + htonl(y->v32[3]); | |
744 z->v32[3] = ntohl((uint32_t) tmp); | |
745 | |
746 tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32); | |
747 z->v32[2] = ntohl((uint32_t) tmp); | |
748 | |
749 tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32); | |
750 z->v32[1] = ntohl((uint32_t) tmp); | |
751 | |
752 tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32); | |
753 z->v32[0] = ntohl((uint32_t) tmp); | |
754 | |
755 #endif /* WORDS_BIGENDIAN */ | |
756 | |
757 } | |
758 #endif | |
759 | |
760 int | |
761 octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { | |
762 uint8_t *end = b + len; | |
763 while (b < end) | |
764 if (*a++ != *b++) | |
765 return 1; | |
766 return 0; | |
767 } | |
768 | |
769 void | |
770 octet_string_set_to_zero(uint8_t *s, int len) { | |
771 uint8_t *end = s + len; | |
772 | |
773 do { | |
774 *s = 0; | |
775 } while (++s < end); | |
776 | |
777 } | |
778 | |
779 | |
780 /* functions below not yet tested! */ | |
781 | |
782 int | |
783 v32_low_bit(v32_t *w) { | |
784 int value; | |
785 | |
786 value = low_bit[w->v8[0]]; | |
787 if (value != -1) | |
788 return value; | |
789 value = low_bit[w->v8[1]]; | |
790 if (value != -1) | |
791 return value + 8; | |
792 value = low_bit[w->v8[2]]; | |
793 if (value != -1) | |
794 return value + 16; | |
795 value = low_bit[w->v8[3]]; | |
796 if (value == -1) | |
797 return -1; | |
798 return value + 24; | |
799 } | |
800 | |
801 /* high_bit not done yet */ | |
802 | |
803 | |
804 | |
805 | |
806 | |
OLD | NEW |