blob: 667902d91d33799cc8421f67049bd44a23f75710 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "Bitvec.h"
2
3#include "Random.h"
4
5#include <assert.h>
6#include <stdio.h>
7
8#ifndef DEBUG
9#undef assert
10void assert ( bool )
11{
12}
13#endif
14
15//----------------------------------------------------------------------------
16
17void printbits ( void * blob, int len )
18{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000019 uint8_t * data = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000020
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000021 printf("[");
22 for(int i = 0; i < len; i++)
23 {
24 unsigned char byte = data[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000025
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000026 int hi = (byte >> 4);
27 int lo = (byte & 0xF);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000028
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000029 if(hi) printf("%01x",hi);
30 else printf(".");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000031
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000032 if(lo) printf("%01x",lo);
33 else printf(".");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000034
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000035 if(i != len-1) printf(" ");
36 }
37 printf("]");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000038}
39
40void printbits2 ( uint8_t * k, int nbytes )
41{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000042 printf("[");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000043
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000044 for(int i = nbytes-1; i >= 0; i--)
45 {
46 uint8_t b = k[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000047
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000048 for(int j = 7; j >= 0; j--)
49 {
50 uint8_t c = (b & (1 << j)) ? '#' : ' ';
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000051
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000052 putc(c,stdout);
53 }
54 }
55 printf("]");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000056}
57
58void printhex32 ( void * blob, int len )
59{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000060 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000061
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000062 uint32_t * d = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000063
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000064 printf("{ ");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000065
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000066 for(int i = 0; i < len/4; i++)
67 {
68 printf("0x%08x, ",d[i]);
69 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000070
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000071 printf("}");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000072}
73
tanjent@gmail.combabb5532011-02-28 06:03:12 +000074void printbytes ( void * blob, int len )
75{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000076 uint8_t * d = (uint8_t*)blob;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000077
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000078 printf("{ ");
tanjent@gmail.combabb5532011-02-28 06:03:12 +000079
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000080 for(int i = 0; i < len; i++)
81 {
82 printf("0x%02x, ",d[i]);
83 }
tanjent@gmail.combabb5532011-02-28 06:03:12 +000084
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000085 printf(" };");
tanjent@gmail.combabb5532011-02-28 06:03:12 +000086}
87
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000088//-----------------------------------------------------------------------------
89
90uint32_t getbit ( void * block, int len, uint32_t bit )
91{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000092 uint8_t * b = (uint8_t*)block;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000093
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000094 int byte = bit >> 3;
95 bit = bit & 0x7;
96
97 if(byte < len) return (b[byte] >> bit) & 1;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000098
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000099 return 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000100}
101
102uint32_t getbit_wrap ( void * block, int len, uint32_t bit )
103{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000104 uint8_t * b = (uint8_t*)block;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000105
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000106 int byte = bit >> 3;
107 bit = bit & 0x7;
108
109 byte %= len;
110
111 return (b[byte] >> bit) & 1;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000112}
113
114void setbit ( void * block, int len, uint32_t bit )
115{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000116 uint8_t * b = (uint8_t*)block;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000117
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000118 int byte = bit >> 3;
119 bit = bit & 0x7;
120
121 if(byte < len) b[byte] |= (1 << bit);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000122}
123
124void setbit ( void * block, int len, uint32_t bit, uint32_t val )
125{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000126 val ? setbit(block,len,bit) : clearbit(block,len,bit);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000127}
128
129void clearbit ( void * block, int len, uint32_t bit )
130{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000131 uint8_t * b = (uint8_t*)block;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000132
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000133 int byte = bit >> 3;
134 bit = bit & 0x7;
135
136 if(byte < len) b[byte] &= ~(1 << bit);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000137}
138
139void flipbit ( void * block, int len, uint32_t bit )
140{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000141 uint8_t * b = (uint8_t*)block;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000142
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000143 int byte = bit >> 3;
144 bit = bit & 0x7;
145
146 if(byte < len) b[byte] ^= (1 << bit);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000147}
148
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000149// from the "Bit Twiddling Hacks" webpage
150
151int countbits ( uint32_t v )
152{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000153 v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
154 v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
155 int c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000156
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000157 return c;
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000158}
159
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000160//-----------------------------------------------------------------------------
161
162void lshift1 ( void * blob, int len, int c )
163{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000164 int nbits = len*8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000165
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000166 for(int i = nbits-1; i >= 0; i--)
167 {
168 setbit(blob,len,i,getbit(blob,len,i-c));
169 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000170}
171
172
173void lshift8 ( void * blob, int nbytes, int c )
174{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000175 uint8_t * k = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000176
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000177 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000178
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000179 int b = c >> 3;
180 c &= 7;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000181
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000182 for(int i = nbytes-1; i >= b; i--)
183 {
184 k[i] = k[i-b];
185 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000186
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000187 for(int i = b-1; i >= 0; i--)
188 {
189 k[i] = 0;
190 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000191
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000192 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000193
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000194 for(int i = nbytes-1; i >= 0; i--)
195 {
196 uint8_t a = k[i];
197 uint8_t b = (i == 0) ? 0 : k[i-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000198
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000199 k[i] = (a << c) | (b >> (8-c));
200 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000201}
202
203void lshift32 ( void * blob, int len, int c )
204{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000205 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000206
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000207 int nbytes = len;
208 int ndwords = nbytes / 4;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000209
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000210 uint32_t * k = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000211
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000212 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000213
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000214 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000215
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000216 int b = c / 32;
217 c &= (32-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000218
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000219 for(int i = ndwords-1; i >= b; i--)
220 {
221 k[i] = k[i-b];
222 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000223
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000224 for(int i = b-1; i >= 0; i--)
225 {
226 k[i] = 0;
227 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000228
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000229 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000230
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000231 for(int i = ndwords-1; i >= 0; i--)
232 {
233 uint32_t a = k[i];
234 uint32_t b = (i == 0) ? 0 : k[i-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000235
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000236 k[i] = (a << c) | (b >> (32-c));
237 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000238}
239
240//-----------------------------------------------------------------------------
241
242void rshift1 ( void * blob, int len, int c )
243{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000244 int nbits = len*8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000245
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000246 for(int i = 0; i < nbits; i++)
247 {
248 setbit(blob,len,i,getbit(blob,len,i+c));
249 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000250}
251
252void rshift8 ( void * blob, int nbytes, int c )
253{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000254 uint8_t * k = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000255
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000256 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000257
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000258 int b = c >> 3;
259 c &= 7;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000260
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000261 for(int i = 0; i < nbytes-b; i++)
262 {
263 k[i] = k[i+b];
264 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000265
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000266 for(int i = nbytes-b; i < nbytes; i++)
267 {
268 k[i] = 0;
269 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000270
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000271 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000272
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000273 for(int i = 0; i < nbytes; i++)
274 {
275 uint8_t a = (i == nbytes-1) ? 0 : k[i+1];
276 uint8_t b = k[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000277
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000278 k[i] = (a << (8-c) ) | (b >> c);
279 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000280}
281
282void rshift32 ( void * blob, int len, int c )
283{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000284 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000285
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000286 int nbytes = len;
287 int ndwords = nbytes / 4;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000288
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000289 uint32_t * k = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000290
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000291 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000292
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000293 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000294
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000295 int b = c / 32;
296 c &= (32-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000297
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000298 for(int i = 0; i < ndwords-b; i++)
299 {
300 k[i] = k[i+b];
301 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000302
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000303 for(int i = ndwords-b; i < ndwords; i++)
304 {
305 k[i] = 0;
306 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000307
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000308 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000309
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000310 for(int i = 0; i < ndwords; i++)
311 {
312 uint32_t a = (i == ndwords-1) ? 0 : k[i+1];
313 uint32_t b = k[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000314
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000315 k[i] = (a << (32-c) ) | (b >> c);
316 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000317}
318
319//-----------------------------------------------------------------------------
320
321void lrot1 ( void * blob, int len, int c )
322{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000323 int nbits = len * 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000324
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000325 for(int i = 0; i < c; i++)
326 {
327 uint32_t bit = getbit(blob,len,nbits-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000328
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000329 lshift1(blob,len,1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000330
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000331 setbit(blob,len,0,bit);
332 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000333}
334
335void lrot8 ( void * blob, int len, int c )
336{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000337 int nbytes = len;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000338
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000339 uint8_t * k = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000340
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000341 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000342
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000343 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000344
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000345 int b = c / 8;
346 c &= (8-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000347
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000348 for(int j = 0; j < b; j++)
349 {
350 uint8_t t = k[nbytes-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000351
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000352 for(int i = nbytes-1; i > 0; i--)
353 {
354 k[i] = k[i-1];
355 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000356
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000357 k[0] = t;
358 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000359
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000360 uint8_t t = k[nbytes-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000361
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000362 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000363
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000364 for(int i = nbytes-1; i >= 0; i--)
365 {
366 uint8_t a = k[i];
367 uint8_t b = (i == 0) ? t : k[i-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000368
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000369 k[i] = (a << c) | (b >> (8-c));
370 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000371}
372
373void lrot32 ( void * blob, int len, int c )
374{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000375 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000376
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000377 int nbytes = len;
378 int ndwords = nbytes/4;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000379
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000380 uint32_t * k = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000381
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000382 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000383
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000384 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000385
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000386 int b = c / 32;
387 c &= (32-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000388
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000389 for(int j = 0; j < b; j++)
390 {
391 uint32_t t = k[ndwords-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000392
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000393 for(int i = ndwords-1; i > 0; i--)
394 {
395 k[i] = k[i-1];
396 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000397
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000398 k[0] = t;
399 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000400
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000401 uint32_t t = k[ndwords-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000402
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000403 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000404
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000405 for(int i = ndwords-1; i >= 0; i--)
406 {
407 uint32_t a = k[i];
408 uint32_t b = (i == 0) ? t : k[i-1];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000409
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000410 k[i] = (a << c) | (b >> (32-c));
411 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000412}
413
414//-----------------------------------------------------------------------------
415
416void rrot1 ( void * blob, int len, int c )
417{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000418 int nbits = len * 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000419
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000420 for(int i = 0; i < c; i++)
421 {
422 uint32_t bit = getbit(blob,len,0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000423
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000424 rshift1(blob,len,1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000425
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000426 setbit(blob,len,nbits-1,bit);
427 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000428}
429
430void rrot8 ( void * blob, int len, int c )
431{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000432 int nbytes = len;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000433
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000434 uint8_t * k = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000435
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000436 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000437
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000438 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000439
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000440 int b = c / 8;
441 c &= (8-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000442
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000443 for(int j = 0; j < b; j++)
444 {
445 uint8_t t = k[0];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000446
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000447 for(int i = 0; i < nbytes-1; i++)
448 {
449 k[i] = k[i+1];
450 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000451
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000452 k[nbytes-1] = t;
453 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000454
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000455 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000456
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000457 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000458
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000459 uint8_t t = k[0];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000460
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000461 for(int i = 0; i < nbytes; i++)
462 {
463 uint8_t a = (i == nbytes-1) ? t : k[i+1];
464 uint8_t b = k[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000465
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000466 k[i] = (a << (8-c)) | (b >> c);
467 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000468}
469
470void rrot32 ( void * blob, int len, int c )
471{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000472 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000473
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000474 int nbytes = len;
475 int ndwords = nbytes/4;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000476
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000477 uint32_t * k = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000478
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000479 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000480
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000481 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000482
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000483 int b = c / 32;
484 c &= (32-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000485
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000486 for(int j = 0; j < b; j++)
487 {
488 uint32_t t = k[0];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000489
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000490 for(int i = 0; i < ndwords-1; i++)
491 {
492 k[i] = k[i+1];
493 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000494
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000495 k[ndwords-1] = t;
496 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000497
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000498 if(c == 0) return;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000499
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000500 //----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000501
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000502 uint32_t t = k[0];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000503
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000504 for(int i = 0; i < ndwords; i++)
505 {
506 uint32_t a = (i == ndwords-1) ? t : k[i+1];
507 uint32_t b = k[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000508
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000509 k[i] = (a << (32-c)) | (b >> c);
510 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000511}
512
513//-----------------------------------------------------------------------------
514
515uint32_t window1 ( void * blob, int len, int start, int count )
516{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000517 int nbits = len*8;
518 start %= nbits;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000519
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000520 uint32_t t = 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000521
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000522 for(int i = 0; i < count; i++)
523 {
524 setbit(&t,sizeof(t),i, getbit_wrap(blob,len,start+i));
525 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000526
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000527 return t;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000528}
529
530uint32_t window8 ( void * blob, int len, int start, int count )
531{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000532 int nbits = len*8;
533 start %= nbits;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000534
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000535 uint32_t t = 0;
536 uint8_t * k = (uint8_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000537
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000538 if(count == 0) return 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000539
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000540 int c = start & (8-1);
541 int d = start / 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000542
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000543 for(int i = 0; i < 4; i++)
544 {
545 int ia = (i + d + 1) % len;
546 int ib = (i + d + 0) % len;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000547
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000548 uint32_t a = k[ia];
549 uint32_t b = k[ib];
550
551 uint32_t m = (a << (8-c)) | (b >> c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000552
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000553 t |= (m << (8*i));
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000554
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000555 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000556
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000557 t &= ((1 << count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000558
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000559 return t;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000560}
561
562uint32_t window32 ( void * blob, int len, int start, int count )
563{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000564 int nbits = len*8;
565 start %= nbits;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000566
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000567 assert((len & 3) == 0);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000568
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000569 int ndwords = len / 4;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000570
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000571 uint32_t * k = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000572
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000573 if(count == 0) return 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000574
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000575 int c = start & (32-1);
576 int d = start / 32;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000577
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000578 if(c == 0) return (k[d] & ((1 << count) - 1));
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000579
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000580 int ia = (d + 1) % ndwords;
581 int ib = (d + 0) % ndwords;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000582
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000583 uint32_t a = k[ia];
584 uint32_t b = k[ib];
585
586 uint32_t t = (a << (32-c)) | (b >> c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000587
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000588 t &= ((1 << count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000589
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000590 return t;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000591}
592
593//-----------------------------------------------------------------------------
594
595bool test_shift ( void )
596{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000597 int nbits = 64;
598 int nbytes = nbits / 8;
599 int reps = 10000;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000600
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000601 for(int j = 0; j < reps; j++)
602 {
603 if(j % (reps/10) == 0) printf(".");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000604
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000605 uint64_t a = rand_u64();
606 uint64_t b;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000607
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000608 for(int i = 0; i < nbits; i++)
609 {
610 b = a; lshift1 (&b,nbytes,i); assert(b == (a << i));
611 b = a; lshift8 (&b,nbytes,i); assert(b == (a << i));
612 b = a; lshift32 (&b,nbytes,i); assert(b == (a << i));
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000613
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000614 b = a; rshift1 (&b,nbytes,i); assert(b == (a >> i));
615 b = a; rshift8 (&b,nbytes,i); assert(b == (a >> i));
616 b = a; rshift32 (&b,nbytes,i); assert(b == (a >> i));
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000617
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000618 b = a; lrot1 (&b,nbytes,i); assert(b == ROTL64(a,i));
619 b = a; lrot8 (&b,nbytes,i); assert(b == ROTL64(a,i));
620 b = a; lrot32 (&b,nbytes,i); assert(b == ROTL64(a,i));
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000621
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000622 b = a; rrot1 (&b,nbytes,i); assert(b == ROTR64(a,i));
623 b = a; rrot8 (&b,nbytes,i); assert(b == ROTR64(a,i));
624 b = a; rrot32 (&b,nbytes,i); assert(b == ROTR64(a,i));
625 }
626 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000627
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000628 printf("PASS\n");
629 return true;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000630}
631
632//-----------------------------------------------------------------------------
633
634template < int nbits >
635bool test_window2 ( void )
636{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000637 struct keytype
638 {
639 uint8_t bytes[nbits/8];
640 };
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000641
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000642 int nbytes = nbits / 8;
643 int reps = 10000;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000644
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000645 for(int j = 0; j < reps; j++)
646 {
647 if(j % (reps/10) == 0) printf(".");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000648
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000649 keytype k;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000650
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000651 rand_p(&k,nbytes);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000652
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000653 for(int start = 0; start < nbits; start++)
654 {
655 for(int count = 0; count < 32; count++)
656 {
657 uint32_t a = window1(&k,nbytes,start,count);
658 uint32_t b = window8(&k,nbytes,start,count);
659 uint32_t c = window(&k,nbytes,start,count);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000660
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000661 assert(a == b);
662 assert(a == c);
663 }
664 }
665 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000666
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000667 printf("PASS %d\n",nbits);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000668
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000669 return true;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000670}
671
672bool test_window ( void )
673{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000674 int reps = 10000;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000675
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000676 for(int j = 0; j < reps; j++)
677 {
678 if(j % (reps/10) == 0) printf(".");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000679
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000680 int nbits = 64;
681 int nbytes = nbits / 8;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000682
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000683 uint64_t x = rand_u64();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000684
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000685 for(int start = 0; start < nbits; start++)
686 {
687 for(int count = 0; count < 32; count++)
688 {
689 uint32_t a = (uint32_t)ROTR64(x,start);
690 a &= ((1 << count)-1);
691
692 uint32_t b = window1 (&x,nbytes,start,count);
693 uint32_t c = window8 (&x,nbytes,start,count);
694 uint32_t d = window32(&x,nbytes,start,count);
695 uint32_t e = window (x,start,count);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000696
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000697 assert(a == b);
698 assert(a == c);
699 assert(a == d);
700 assert(a == e);
701 }
702 }
703 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000704
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000705 printf("PASS 64\n");
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000706
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000707 test_window2<8>();
708 test_window2<16>();
709 test_window2<24>();
710 test_window2<32>();
711 test_window2<40>();
712 test_window2<48>();
713 test_window2<56>();
714 test_window2<64>();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000715
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000716 return true;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000717}
718
719//-----------------------------------------------------------------------------