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