4
* crypto math operations and data types
11
* Copyright (c) 2001-2006 Cisco Systems, Inc.
12
* All rights reserved.
14
* Redistribution and use in source and binary forms, with or without
15
* modification, are permitted provided that the following conditions
18
* Redistributions of source code must retain the above copyright
19
* notice, this list of conditions and the following disclaimer.
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.
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.
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.
45
#include "crypto_math.h"
46
#include <stdlib.h> /* malloc() used in bitvector_alloc */
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
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
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
158
octet_get_weight(uint8_t octet) {
159
extern int octet_weight[256];
161
return octet_weight[octet];
165
v32_weight(v32_t a) {
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]];
177
v32_distance(v32_t x, v32_t y) {
179
return v32_weight(x);
183
v32_dot_product(v32_t a, v32_t b) {
185
return v32_weight(a) & 1;
189
* _bit_string returns a NULL-terminated character string suitable for
193
#define MAX_STRING_LENGTH 1024
195
char bit_string[MAX_STRING_LENGTH];
198
octet_bit_string(uint8_t x) {
201
for (mask = 1, index = 0; mask < 256; mask <<= 1)
203
bit_string[index++] = '0';
205
bit_string[index++] = '1';
207
bit_string[index++] = 0; /* NULL terminate string */
213
v16_bit_string(v16_t x) {
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';
221
bit_string[index++] = '1';
223
bit_string[index++] = 0; /* NULL terminate string */
228
v32_bit_string(v32_t x) {
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';
236
bit_string[index++] = '1';
238
bit_string[index++] = 0; /* NULL terminate string */
243
v64_bit_string(const v64_t *x) {
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';
251
bit_string[index++] = '1';
253
bit_string[index++] = 0; /* NULL terminate string */
258
v128_bit_string(v128_t *x) {
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';
267
bit_string[index] = '0';
271
bit_string[128] = 0; /* null terminate string */
277
nibble_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];
284
octet_hex_string(uint8_t x) {
286
bit_string[0] = nibble_to_hex_char(x >> 4);
287
bit_string[1] = nibble_to_hex_char(x & 0xF);
289
bit_string[2] = 0; /* null terminate string */
294
octet_string_hex_string(const void *str, int length) {
295
const uint8_t *s = str;
298
/* double length, since one octet takes two hex characters */
301
/* truncate string if it would be too long */
302
if (length > MAX_STRING_LENGTH)
303
length = MAX_STRING_LENGTH-1;
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);
309
bit_string[i] = 0; /* null terminate string */
314
v16_hex_string(v16_t x) {
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);
322
bit_string[j] = 0; /* null terminate string */
327
v32_hex_string(v32_t x) {
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);
335
bit_string[j] = 0; /* null terminate string */
340
v64_hex_string(const v64_t *x) {
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);
348
bit_string[j] = 0; /* null terminate string */
353
v128_hex_string(v128_t *x) {
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);
361
bit_string[j] = 0; /* null terminate string */
366
char_to_hex_string(char *x, int num_char) {
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);
376
bit_string[j] = 0; /* null terminate string */
381
hex_char_to_nibble(uint8_t 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 */
408
return -1; /* this keeps compilers from complaining */
412
is_hex_string(char *s) {
414
if (hex_char_to_nibble(*s++) == -1)
420
hex_string_to_octet(char *s) {
423
x = (hex_char_to_nibble(s[0]) << 4)
424
| hex_char_to_nibble(s[1] & 0xFF);
430
* hex_string_to_octet_string converts a hexadecimal string
431
* of length 2 * len to a raw octet string of length len
435
hex_string_to_octet_string(char *raw, char *hex, int len) {
441
while (hex_len < len) {
442
tmp = hex_char_to_nibble(hex[0]);
447
tmp = hex_char_to_nibble(hex[1]);
459
hex_string_to_v16(char *s) {
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);
471
hex_string_to_v32(char *s) {
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);
483
hex_string_to_v64(char *s) {
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);
495
hex_string_to_v128(char *s) {
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);
509
* the matrix A[] is stored in column format, i.e., A[i] is the ith
510
* column of the matrix
514
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
518
for (mask=1; mask < 256; mask *= 2) {
528
v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
534
v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
542
v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
554
v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
574
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
577
v128_set_to_zero(v128_t *x) {
578
_v128_set_to_zero(x);
582
v128_copy(v128_t *x, const v128_t *y) {
587
v128_xor(v128_t *z, v128_t *x, v128_t *y) {
592
v128_and(v128_t *z, v128_t *x, v128_t *y) {
597
v128_or(v128_t *z, v128_t *x, v128_t *y) {
602
v128_complement(v128_t *x) {
607
v128_is_eq(const v128_t *x, const v128_t *y) {
608
return _v128_is_eq(x, y);
612
v128_get_bit(const v128_t *x, int i) {
613
return _v128_get_bit(x, i);
617
v128_set_bit(v128_t *x, int i) {
622
v128_clear_bit(v128_t *x, int i){
623
_v128_clear_bit(x, i);
627
v128_set_bit_to(v128_t *x, int i, int y){
628
_v128_set_bit_to(x, i, y);
632
#endif /* DATATYPES_USE_MACROS */
636
v128_left_shift2(v128_t *x, int num_bits) {
638
int word_shift = num_bits >> 5;
639
int bit_shift = num_bits & 31;
641
for (i=0; i < (4-word_shift); i++) {
642
x->v32[i] = x->v32[i+word_shift] << bit_shift;
645
for ( ; i < word_shift; i++) {
652
v128_right_shift(v128_t *x, int index) {
653
const int base_index = index >> 5;
654
const int bit_index = index & 31;
663
if (bit_index == 0) {
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];
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;
677
b |= x->v32[from-1] >> (32-bit_index);
683
/* now wrap up the final portion */
684
for (i=0; i < base_index; i++)
690
v128_left_shift(v128_t *x, int index) {
692
const int base_index = index >> 5;
693
const int bit_index = index & 31;
700
if (bit_index == 0) {
701
for (i=0; i < 4 - base_index; i++)
702
x->v32[i] = x->v32[i+base_index];
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;
710
/* now wrap up the final portion */
711
for (i = 4 - base_index; i < 4; i++)
719
v128_add(v128_t *z, v128_t *x, v128_t *y) {
720
/* integer addition modulo 2^128 */
722
#ifdef WORDS_BIGENDIAN
725
tmp = x->v32[3] + y->v32[3];
726
z->v32[3] = (uint32_t) tmp;
728
tmp = x->v32[2] + y->v32[2] + (tmp >> 32);
729
z->v32[2] = (uint32_t) tmp;
731
tmp = x->v32[1] + y->v32[1] + (tmp >> 32);
732
z->v32[1] = (uint32_t) tmp;
734
tmp = x->v32[0] + y->v32[0] + (tmp >> 32);
735
z->v32[0] = (uint32_t) tmp;
737
#else /* assume little endian architecture */
740
tmp = htonl(x->v32[3]) + htonl(y->v32[3]);
741
z->v32[3] = ntohl((uint32_t) tmp);
743
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32);
744
z->v32[2] = ntohl((uint32_t) tmp);
746
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32);
747
z->v32[1] = ntohl((uint32_t) tmp);
749
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32);
750
z->v32[0] = ntohl((uint32_t) tmp);
752
#endif /* WORDS_BIGENDIAN */
758
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
759
uint8_t *end = b + len;
767
octet_string_set_to_zero(uint8_t *s, int len) {
768
uint8_t *end = s + len;
776
/* functions manipulating bit_vector_t */
778
#define BITVECTOR_MAX_WORDS 5
781
bitvector_alloc(bitvector_t *v, unsigned long length) {
782
unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;
785
/* allocate memory, then set parameters */
786
if (l > BITVECTOR_MAX_WORDS)
789
l = BITVECTOR_MAX_WORDS;
795
/* initialize bitvector to zero */
796
for (i=0; i < (length >> 5); i++) {
804
bitvector_set_bit(bitvector_t *v, int bit_index) {
806
v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));
811
bitvector_get_bit(const bitvector_t *v, int bit_index) {
813
return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;
820
bitvector_print_hex(const bitvector_t *v, FILE *stream) {
822
int m = v->length >> 5;
823
int n = v->length & 31;
827
/* if length isn't a multiple of four, we can't hex_print */
831
/* if the length is zero, do nothing */
836
* loop over words from most significant to least significant -
839
for (i=m; i > 0; i++) {
840
char *str = string + 7;
843
/* null terminate string */
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);
856
/* now print stream */
857
fprintf(stream, string);
866
hex_string_length(char *s) {
869
/* ignore leading zeros */
870
while ((*s != 0) && *s == '0')
873
/* count remaining characters */
875
if (hex_char_to_nibble(*s++) == -1)
884
bitvector_set_from_hex(bitvector_t *v, char *string) {
885
int num_hex_chars, m, n, i, j;
888
num_hex_chars = hex_string_length(string);
889
if (num_hex_chars == -1)
893
v->length = num_hex_chars * 4;
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
901
m = num_hex_chars / 8; /* number of words */
902
n = num_hex_chars % 8; /* number of nibbles in last word */
904
/* if the length is greater than the bitvector, return an error */
905
if (m > BITVECTOR_MAX_WORDS)
909
* loop over words from most significant - first word is a special
915
for (i=0; i < n; i++) {
916
tmp = hex_char_to_nibble(*string++);
922
/* now loop over the rest of the words */
923
for (i=m-1; i >= 0; i--) {
925
for (j=0; j < 8; j++) {
926
tmp = hex_char_to_nibble(*string++);
936
/* functions below not yet tested! */
939
v32_low_bit(v32_t *w) {
942
value = low_bit[w->v8[0]];
945
value = low_bit[w->v8[1]];
948
value = low_bit[w->v8[2]];
951
value = low_bit[w->v8[3]];
957
/* high_bit not done yet */