sayaes 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6518dc99b77bc8afb254ef1c0b102c01f3c78527b3d6f8960876d64f1607cefe
4
+ data.tar.gz: 1c0ba2bf212cc9f142731fed8d4352e341aac669f5fd2c61b25660957e578db9
5
+ SHA512:
6
+ metadata.gz: f2481b76fb068800bfa5ce88f13741ec116e1e26be8791164299992ec565f52c078b90846ee0c09e703ddde779f23375abcc754685ef1311b9f61703eacab3cd
7
+ data.tar.gz: 39106b94bf35dee63cb12e8c0a92a58d9079cd044e07eaefc563316f70d5cc4e35d8f0573dddba4076fec79dc2b3cbc02d898199cea2beb83cc376d7a8c6ffc3
@@ -0,0 +1,2 @@
1
+
2
+ * sayaes v1.0.4 2019-08-03
@@ -0,0 +1,2 @@
1
+ = Sayaes - AES implementation with Say extensions
2
+ Let's see
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push 'lib'
8
+ t.libs.push 'ext'
9
+ t.test_files = FileList['spec/**/*.rb']
10
+ t.verbose = true
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Loads mkmf which is used to make makefiles for Ruby extensions
4
+ require 'mkmf'
5
+
6
+ # Give it a name
7
+ extension_name = 'sayaes'
8
+
9
+ # The destination
10
+ dir_config(extension_name)
11
+
12
+ # Do the work
13
+ create_makefile(extension_name)
@@ -0,0 +1,1234 @@
1
+ /*//////////////////////////////////////////////////////////////////////////////
2
+ ////////////////////////////////////////////////////////////////////////////////
3
+ //
4
+ // Sayaes Ruby/C library implementation.
5
+ // Implementation in C originally by Christophe Devine.
6
+ //
7
+ ////////////////////////////////////////////////////////////////////////////////
8
+ //////////////////////////////////////////////////////////////////////////////*/
9
+
10
+ #include <string.h>
11
+ #include <stdio.h>
12
+ #include <stdint.h>
13
+
14
+ #include "ruby.h"
15
+ #define INTEGER_PACK_MSWORD_FIRST 0x01
16
+ #define INTEGER_PACK_LSWORD_FIRST 0x02
17
+ #define INTEGER_PACK_MSBYTE_FIRST 0x10
18
+ #define INTEGER_PACK_LSBYTE_FIRST 0x20
19
+ #define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
20
+ #define INTEGER_PACK_2COMP 0x80
21
+ #define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION 0x400
22
+ /* For rb_integer_unpack: */
23
+ #define INTEGER_PACK_FORCE_BIGNUM 0x100
24
+ #define INTEGER_PACK_NEGATIVE 0x200
25
+ /* Combinations: */
26
+ #define INTEGER_PACK_LITTLE_ENDIAN \
27
+ (INTEGER_PACK_LSWORD_FIRST | \
28
+ INTEGER_PACK_LSBYTE_FIRST)
29
+ #define INTEGER_PACK_BIG_ENDIAN \
30
+ (INTEGER_PACK_MSWORD_FIRST | \
31
+ INTEGER_PACK_MSBYTE_FIRST)
32
+
33
+ #include "sayaes.h"
34
+
35
+ /* Global boolean */
36
+ int sayaes_do_gen_tables = 1;
37
+
38
+ /* Old school. Oh yeah */
39
+ #ifndef RSTRING_PTR
40
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
41
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
42
+ #endif
43
+
44
+ /* Ruby buckets */
45
+ VALUE rb_cSayaes;
46
+
47
+ void Init_sayaes()
48
+ {
49
+ rb_cSayaes = rb_define_class("Sayaes", rb_cObject);
50
+
51
+ rb_define_alloc_func(rb_cSayaes, sayaes_alloc);
52
+ rb_define_method(rb_cSayaes, "initialize", sayaes_initialize, 1);
53
+ rb_define_method(rb_cSayaes, "encrypt", sayaes_encrypt, 1);
54
+ rb_define_method(rb_cSayaes, "decrypt", sayaes_decrypt, 1);
55
+ rb_define_method(rb_cSayaes, "encipher", sayaes_encipher, 1);
56
+ rb_define_method(rb_cSayaes, "decipher", sayaes_decipher, 1);
57
+ rb_define_method(rb_cSayaes, "init_feistel_ext", sayaes_init_feistel_ext, 2);
58
+ rb_define_method(rb_cSayaes, "key", sayaes_key, 0);
59
+ rb_define_method(rb_cSayaes, "r", sayaes_r, 0);
60
+ rb_define_method(rb_cSayaes, "l", sayaes_l, 0);
61
+ rb_define_method(rb_cSayaes, "w", sayaes_w, 0);
62
+ rb_define_method(rb_cSayaes, "prf_big", sayaes_prf_big, 1);
63
+ }
64
+
65
+ VALUE sayaes_key(VALUE self)
66
+ {
67
+ /* get our "self" data structure (eg, member vars) */
68
+ sayaes_t* sayaes;
69
+ VALUE new_str;
70
+
71
+ Data_Get_Struct(self, sayaes_t, sayaes);
72
+ new_str = rb_str_new(sayaes->key, sayaes->key_bits/8);
73
+ return new_str;
74
+ }
75
+
76
+
77
+ VALUE sayaes_alloc(VALUE klass)
78
+ {
79
+ /* Initialize our structs */
80
+ sayaes_t *sayaes = malloc(sizeof(sayaes_t));
81
+
82
+ /* Clear out memory */
83
+ memset(sayaes->key, 0, sizeof(sayaes->key));
84
+ memset(sayaes->erk, 0, sizeof(sayaes->erk));
85
+ memset(sayaes->drk, 0, sizeof(sayaes->drk));
86
+ memset(sayaes->initial_erk, 0, sizeof(sayaes->initial_erk));
87
+ memset(sayaes->initial_drk, 0, sizeof(sayaes->initial_drk));
88
+
89
+ return Data_Wrap_Struct(klass, sayaes_mark, sayaes_free, sayaes);
90
+ }
91
+
92
+ VALUE sayaes_initialize(VALUE self, VALUE key)
93
+ {
94
+ /* get our "self" data structure (eg, member vars) */
95
+ sayaes_t* sayaes;
96
+ /* char error_mesg[350]; */
97
+ int key_bits;
98
+ char* key_data;
99
+
100
+ Data_Get_Struct(self, sayaes_t, sayaes);
101
+
102
+ key_data = StringValuePtr(key);
103
+
104
+ /* since the tables are global there's no need to generate them more than once
105
+ * regardless of how many instances there are of this object
106
+ */
107
+ if( sayaes_do_gen_tables == 1 )
108
+ {
109
+ sayaes_gen_tables();
110
+ sayaes_do_gen_tables = 0;
111
+ }
112
+
113
+ /* if they are trying to use a number of bits that is larger that the key
114
+ * has available, truncate the bits to the key bits.
115
+ * ie., they pass a 128 bit key but pass keytype N256 we will use N128
116
+ */
117
+ //key_bits = strlen(key_data)*8;
118
+ key_bits = RSTRING_LEN(key)*8;
119
+ switch(key_bits)
120
+ {
121
+ case 128:
122
+ case 192:
123
+ case 256:
124
+ sayaes->key_bits = key_bits;
125
+ memcpy(sayaes->key, key_data, key_bits/8);
126
+ /*printf("AES key=%s, bits=%d\n", sayaes->key, sayaes->key_bits);*/
127
+ break;
128
+ default:
129
+ //sprintf(error_mesg, "AES key must be 128, 192, or 256 bits in length (got %d): %s", key_bits, key_data);
130
+ rb_raise(rb_eArgError, "AES key must be 128, 192, or 256 bits in length");
131
+ return Qnil;
132
+ }
133
+
134
+ if (sayaes_initialize_state(sayaes)) {
135
+ rb_raise(rb_eRuntimeError, "Failed to initialize AES internal state");
136
+ return Qnil;
137
+ }
138
+
139
+ sayaes->l = 999; // the length of the set-1
140
+ sayaes->r = 12; // rounds count
141
+ sayaes->w = 10;
142
+ sayaes->h = sayaes->w >> 1;
143
+ sayaes->mask = ~( (~((uint64_t)0) << (sayaes->w-1) ) << 1);
144
+ sayaes->hmask = ~(~((uint64_t)0) << sayaes->h);
145
+
146
+ return Qtrue;
147
+ }
148
+
149
+ void sayaes_module_shutdown( sayaes_t* sayaes )
150
+ {
151
+ }
152
+
153
+ /* This method **MUST** be present even if it does nothing */
154
+ void sayaes_mark( sayaes_t* sayaes )
155
+ {
156
+ /*rb_gc_mark(??);
157
+ //should we mark each member here? */
158
+ }
159
+
160
+ void sayaes_free( sayaes_t* sayaes )
161
+ {
162
+ sayaes_module_shutdown(sayaes);
163
+ free(sayaes);
164
+ }
165
+
166
+
167
+ VALUE sayaes_init_feistel_ext(VALUE self, VALUE rb_l, VALUE rb_r)
168
+ {
169
+ /* get our "self" data structure (eg, member vars) */
170
+ sayaes_t* sayaes;
171
+ Data_Get_Struct(self, sayaes_t, sayaes);
172
+
173
+ sayaes->l = NUM2ULL(rb_l); // the length of the set-1
174
+ sayaes->r = NUM2ULL(rb_r); // rounds count
175
+ sayaes->w = (LOG2(sayaes->l)+1) & 0xfffffffffffffffe;
176
+ sayaes->h = sayaes->w >> 1;
177
+ sayaes->mask = ~( (~((uint64_t)0) << (sayaes->w-1) ) << 1); // w=64 requires << 1
178
+ sayaes->hmask = ~(~((uint64_t)0) << sayaes->h);
179
+ return Qtrue;
180
+ }
181
+ VALUE sayaes_r(VALUE self)
182
+ {
183
+ /* get our "self" data structure (eg, member vars) */
184
+ sayaes_t* sayaes;
185
+ Data_Get_Struct(self, sayaes_t, sayaes);
186
+ return ULL2NUM(sayaes->r);
187
+ }
188
+
189
+ VALUE sayaes_l(VALUE self)
190
+ {
191
+ /* get our "self" data structure (eg, member vars) */
192
+ sayaes_t* sayaes;
193
+ Data_Get_Struct(self, sayaes_t, sayaes);
194
+ return ULL2NUM(sayaes->l);
195
+ }
196
+
197
+ VALUE sayaes_w(VALUE self)
198
+ {
199
+ /* get our "self" data structure (eg, member vars) */
200
+ sayaes_t* sayaes;
201
+ Data_Get_Struct(self, sayaes_t, sayaes);
202
+ return ULL2NUM(sayaes->w);
203
+ }
204
+
205
+
206
+ VALUE sayaes_encipher(VALUE self, VALUE rb_x)
207
+ {
208
+ /* get our "self" data structure (eg, member vars) */
209
+ sayaes_t* sayaes;
210
+ uint64_t l;
211
+ uint8_t r;
212
+ uint64_t y;
213
+ uint8_t j;
214
+
215
+ Data_Get_Struct(self, sayaes_t, sayaes);
216
+
217
+ l = sayaes->l;
218
+ r = sayaes->r; // rounds count
219
+ y = NUM2ULL(rb_x); // plain text
220
+
221
+ if (y > l) // x can't be larger than l
222
+ rb_raise(rb_eArgError, "number can't be larger than the set size");
223
+
224
+ do {
225
+ for(j=0; j<r; j++) // r feistel rounds repeated
226
+ y = sayaes_round_e(sayaes, y, j);
227
+ } while( y > l); /* repeat if we aren't inside the set size l */
228
+
229
+ return ULL2NUM(y);
230
+ }
231
+ VALUE sayaes_decipher(VALUE self, VALUE rb_x)
232
+ {
233
+ /* get our "self" data structure (eg, member vars) */
234
+ sayaes_t* sayaes;
235
+ uint64_t l;
236
+ uint8_t r; // rounds count
237
+ uint64_t y; // plain text
238
+ uint8_t j;
239
+
240
+ Data_Get_Struct(self, sayaes_t, sayaes);
241
+
242
+
243
+ l = sayaes->l;
244
+ r = sayaes->r; // rounds count
245
+ y = NUM2ULL(rb_x); // plain text
246
+
247
+ if (y > l) // x can't be larger than l
248
+ rb_raise(rb_eArgError, "number can't be larger than the set size");
249
+
250
+ do {
251
+ for(j=0; j<r; j++) // r feistel rounds repeated
252
+ y = sayaes_round_d(sayaes, y, r-1-j);
253
+ } while( y > l); /* repeat if we aren't inside the set size l */
254
+
255
+ return ULL2NUM(y);
256
+ }
257
+
258
+ /* function sayaes_round, one feistel round for w=2h
259
+ x: 32bit, w: 5bit=1 to 32, j=8bit=0..255
260
+ */
261
+ uint64_t sayaes_round_e(sayaes_t* sayaes, uint64_t x, uint8_t j)
262
+ {
263
+ uint64_t left = x >> sayaes->h; // moved below
264
+ uint64_t right = x & sayaes->hmask;
265
+ uint64_t ret = ((right << sayaes->h) | ( left ^ sayaes_prf(sayaes, right, j)));
266
+ return ret & sayaes->mask;
267
+ }
268
+ uint64_t sayaes_round_d(sayaes_t* sayaes,uint64_t x, uint8_t j)
269
+ {
270
+ uint64_t left = x >> sayaes->h;
271
+ uint64_t right = x & sayaes->hmask;
272
+ uint64_t ret = ((right ^ sayaes_prf(sayaes, left, j)) << sayaes->h) | left;
273
+ return ret & sayaes->mask;
274
+ }
275
+
276
+ /* The prf gets an aes block encryption upto 120 bits + 8 bit counter */
277
+ uint64_t sayaes_prf(sayaes_t* sayaes, uint64_t x, uint8_t j)
278
+ {
279
+ uint64_t *prf;
280
+ // h=5bits, a mask of 0x000...11111
281
+ uint8_t ciphertext[16], plaintext[16];
282
+ /* set the state back to the start to allow for correct encryption
283
+ everytime we are passed data to encrypt*/
284
+ if (sayaes_reinitialize_state(sayaes)) {
285
+ rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
286
+ return Qnil;
287
+ }
288
+
289
+ memset(ciphertext, 0, sizeof(ciphertext)); /* pad with 0's */
290
+ memset(plaintext, 0, sizeof(plaintext)); /* pad with 0's */
291
+ memcpy(plaintext, &x, sizeof(x)); /*rightmost is the x, right half of plaintext*/
292
+ plaintext[15] = (uint8_t)j; /* tweak is the leftmost */
293
+ sayaes_encrypt_block(sayaes, plaintext, ciphertext);
294
+ prf = (uint64_t*)ciphertext;
295
+
296
+ // we return half bits of the result
297
+ return (*prf) & sayaes->hmask;
298
+ }
299
+
300
+ VALUE sayaes_prf_big(VALUE self, VALUE hxj)
301
+ {
302
+ sayaes_t* sayaes;
303
+ uint8_t ciphertext[16], plaintext[16];
304
+ unsigned long* pDataIn;
305
+ unsigned long* pDataOut;
306
+
307
+ Data_Get_Struct(self, sayaes_t, sayaes);
308
+
309
+ /* set the state back to the start to allow for correct encryption
310
+ everytime we are passed data to encrypt*/
311
+ if (sayaes_reinitialize_state(sayaes)) {
312
+ rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
313
+ return Qnil;
314
+ }
315
+ memset(ciphertext, 0, sizeof(ciphertext));
316
+ memset(plaintext, 0, sizeof(plaintext));
317
+ pDataIn = (unsigned long *)plaintext;
318
+ rb_integer_pack(hxj, pDataIn, 4, 1, 0, INTEGER_PACK_BIG_ENDIAN);
319
+ sayaes_encrypt_block(sayaes, plaintext, ciphertext);
320
+ pDataOut = (unsigned long *)ciphertext;
321
+ return rb_integer_unpack(pDataOut, 4, 1, 0, INTEGER_PACK_BIG_ENDIAN);
322
+ }
323
+
324
+
325
+ VALUE sayaes_encrypt(
326
+ VALUE self,
327
+ VALUE buffer
328
+ )
329
+ {
330
+ /* get our "self" data structure (eg, member vars) */
331
+ sayaes_t* sayaes;
332
+ char* pDataIn;
333
+ char* pDataOut;
334
+ int uiNumBytesIn;
335
+ unsigned char *pRead, *pWrite;
336
+ int puiNumBytesOut;
337
+ VALUE new_str;
338
+
339
+ Data_Get_Struct(self, sayaes_t, sayaes);
340
+
341
+ pDataIn = StringValuePtr(buffer);
342
+ uiNumBytesIn = RSTRING_LEN(buffer);
343
+ pDataOut = malloc((uiNumBytesIn + 15) & -16); /* auto-malloc min size in 16-byte increments */
344
+
345
+ pRead = (unsigned char*)pDataIn;
346
+ pWrite = (unsigned char*)pDataOut;
347
+
348
+ /*//////////////////////////////////////////////////////////////////////////
349
+ ////////////////////////////////////////////////////////////////////////////
350
+ // This routine will encode all input bytes in entirety (AES always "succeeds")
351
+ */
352
+ puiNumBytesOut = 0;
353
+
354
+ /* set the state back to the start to allow for correct encryption
355
+ * everytime we are passed data to encrypt
356
+ */
357
+ if (sayaes_reinitialize_state(sayaes)) {
358
+ rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
359
+ return Qnil;
360
+ }
361
+
362
+ /*//////////////////////////////////////////////////////////////////////////
363
+ ////////////////////////////////////////////////////////////////////////////
364
+ // Perform block encodes 16 bytes at a time while we still have at least
365
+ // 16 bytes of input remaining.
366
+ */
367
+ while( uiNumBytesIn >= 16 )
368
+ {
369
+ sayaes_encrypt_block(sayaes, pRead, pWrite);
370
+ pRead += 16; pWrite += 16;
371
+ uiNumBytesIn -= 16;
372
+ puiNumBytesOut += 16;
373
+ }
374
+
375
+ /*//////////////////////////////////////////////////////////////////////////
376
+ ////////////////////////////////////////////////////////////////////////////
377
+ // Have to catch any straggling bytes that are left after encoding the
378
+ // 16-byte blocks. The policy here will be to pad the input with zeros.
379
+ */
380
+ if( uiNumBytesIn > 0 )
381
+ {
382
+ unsigned char temp[16];
383
+ memset(temp, 0, sizeof(temp)); /* pad with 0's */
384
+ memcpy(temp, pRead, uiNumBytesIn);
385
+ sayaes_encrypt_block(sayaes, temp, pWrite);
386
+ puiNumBytesOut += 16;
387
+ }
388
+
389
+ /* return the encrypted string */
390
+ new_str = rb_str_new(pDataOut, puiNumBytesOut);
391
+ free(pDataOut);
392
+ return new_str;
393
+ }
394
+
395
+ VALUE sayaes_decrypt(
396
+ VALUE self,
397
+ VALUE buffer
398
+ )
399
+ {
400
+ /* get our "self" data structure (eg, member vars) */
401
+ sayaes_t* sayaes;
402
+ char* pDataIn;
403
+ int uiNumBytesIn;
404
+ char* pDataOut;
405
+ unsigned char *pRead, *pWrite;
406
+ int puiNumBytesOut;
407
+ VALUE new_str;
408
+
409
+
410
+ Data_Get_Struct(self, sayaes_t, sayaes);
411
+
412
+ pDataIn = StringValuePtr(buffer);
413
+ uiNumBytesIn = RSTRING_LEN(buffer);
414
+ pDataOut = malloc((uiNumBytesIn + 15) & -16); /* auto-malloc min size in 16-byte increments */
415
+
416
+ pRead = (unsigned char*)pDataIn;
417
+ pWrite = (unsigned char*)pDataOut;
418
+
419
+ /*//////////////////////////////////////////////////////////////////////////
420
+ ////////////////////////////////////////////////////////////////////////////
421
+ // AES does not fail, and this routine will encode all input bytes
422
+ // entirely.
423
+ */
424
+ puiNumBytesOut = 0;
425
+
426
+ /* set the state back to the start to allow for correct decryption
427
+ // everytime we are passed data to decrypt
428
+ */
429
+ if (sayaes_reinitialize_state(sayaes)) {
430
+ rb_raise(rb_eRuntimeError, "Failed to reinitialize AES internal state");
431
+ return Qnil;
432
+ }
433
+
434
+ /*//////////////////////////////////////////////////////////////////////////
435
+ ////////////////////////////////////////////////////////////////////////////
436
+ // Perform block decrypts 16 bytes at a time while we still have at least
437
+ // 16 bytes of input remaining.
438
+ */
439
+ while( uiNumBytesIn >= 16 )
440
+ {
441
+ sayaes_decrypt_block(sayaes, pRead, pWrite);
442
+ pRead += 16; pWrite += 16;
443
+ uiNumBytesIn -= 16;
444
+ puiNumBytesOut += 16;
445
+ }
446
+
447
+ /*//////////////////////////////////////////////////////////////////////////
448
+ ////////////////////////////////////////////////////////////////////////////
449
+ // Have to catch any straggling bytes that are left after decrypting the
450
+ // 16-byte blocks.
451
+ */
452
+ if( uiNumBytesIn > 0 )
453
+ {
454
+ unsigned char temp[16];
455
+ memset(temp, 0, sizeof(temp)); /* pad with 0's */
456
+ memcpy(temp, pRead, uiNumBytesIn);
457
+ sayaes_decrypt_block(sayaes, temp, pWrite);
458
+ puiNumBytesOut += 16;
459
+ }
460
+
461
+ /*//////////////////////////////////////////////////////////////////////////
462
+ ////////////////////////////////////////////////////////////////////////////
463
+ // Strip trailing zeros, simple but effective. This is something fucking
464
+ // loose-cannon rjc couldn't figure out despite being a "genius". He needs
465
+ // a punch in the junk, I swear to god.
466
+ */
467
+ while (puiNumBytesOut > 0) {
468
+ if (pDataOut[puiNumBytesOut - 1] != 0) break;
469
+ puiNumBytesOut -= 1;
470
+ }
471
+
472
+ /* return the decrypted string */
473
+ new_str = rb_str_new(pDataOut, puiNumBytesOut);
474
+ free(pDataOut);
475
+ return new_str;
476
+ }
477
+
478
+ /*//////////////////////////////////////////////////////////////////////////////
479
+ //////////////////////////////////////////////////////////////////////////////*/
480
+
481
+ /* uncomment the following line to use pre-computed tables */
482
+ /* otherwise the tables will be generated at the first run */
483
+ //#define FIXED_TABLES
484
+
485
+ #ifndef FIXED_TABLES
486
+
487
+ /* forward S-box & tables */
488
+
489
+ uint32_t FSb[256];
490
+ uint32_t FT0[256];
491
+ uint32_t FT1[256];
492
+ uint32_t FT2[256];
493
+ uint32_t FT3[256];
494
+
495
+ /* reverse S-box & tables */
496
+
497
+ uint32_t RSb[256];
498
+ uint32_t RT0[256];
499
+ uint32_t RT1[256];
500
+ uint32_t RT2[256];
501
+ uint32_t RT3[256];
502
+
503
+ /* round constants */
504
+
505
+ uint32_t RCON[10];
506
+
507
+ /* tables generation flag */
508
+
509
+ /* tables generation routine */
510
+
511
+ #define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \
512
+ ( ( x & 0xFFFFFFFF ) >> 8 ) )
513
+
514
+ #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
515
+ #define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 )
516
+
517
+ void sayaes_gen_tables( void )
518
+ {
519
+ int i;
520
+ uint8_t x, y;
521
+ uint8_t pow[256];
522
+ uint8_t log[256];
523
+
524
+ /* compute pow and log tables over GF(2^8) */
525
+
526
+ for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) )
527
+ {
528
+ pow[i] = x;
529
+ log[x] = i;
530
+ }
531
+
532
+ /* calculate the round constants */
533
+
534
+ for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) )
535
+ {
536
+ RCON[i] = (uint32_t) x << 24;
537
+ }
538
+
539
+ /* generate the forward and reverse S-boxes */
540
+
541
+ FSb[0x00] = 0x63;
542
+ RSb[0x63] = 0x00;
543
+
544
+ for( i = 1; i < 256; ++i )
545
+ {
546
+ x = pow[255 - log[i]];
547
+
548
+ y = x; y = ( y << 1 ) | ( y >> 7 );
549
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
550
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
551
+ x ^= y; y = ( y << 1 ) | ( y >> 7 );
552
+ x ^= y ^ 0x63;
553
+
554
+ FSb[i] = x;
555
+ RSb[x] = i;
556
+ }
557
+
558
+ /* generate the forward and reverse tables */
559
+
560
+ for( i = 0; i < 256; ++i )
561
+ {
562
+ x = (unsigned char) FSb[i]; y = XTIME( x );
563
+
564
+ FT0[i] = (uint32_t) ( x ^ y ) ^
565
+ ( (uint32_t) x << 8 ) ^
566
+ ( (uint32_t) x << 16 ) ^
567
+ ( (uint32_t) y << 24 );
568
+
569
+ FT0[i] &= 0xFFFFFFFF;
570
+
571
+ FT1[i] = ROTR8( FT0[i] );
572
+ FT2[i] = ROTR8( FT1[i] );
573
+ FT3[i] = ROTR8( FT2[i] );
574
+
575
+ y = (unsigned char) RSb[i];
576
+
577
+ RT0[i] = ( (uint32_t) MUL( 0x0B, y ) ) ^
578
+ ( (uint32_t) MUL( 0x0D, y ) << 8 ) ^
579
+ ( (uint32_t) MUL( 0x09, y ) << 16 ) ^
580
+ ( (uint32_t) MUL( 0x0E, y ) << 24 );
581
+
582
+ RT0[i] &= 0xFFFFFFFF;
583
+
584
+ RT1[i] = ROTR8( RT0[i] );
585
+ RT2[i] = ROTR8( RT1[i] );
586
+ RT3[i] = ROTR8( RT2[i] );
587
+ }
588
+ }
589
+
590
+ #else
591
+
592
+ /* forward S-box */
593
+
594
+ static const uint32_t FSb[256] =
595
+ {
596
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
597
+ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
598
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
599
+ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
600
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
601
+ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
602
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
603
+ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
604
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
605
+ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
606
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
607
+ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
608
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
609
+ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
610
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
611
+ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
612
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
613
+ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
614
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
615
+ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
616
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
617
+ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
618
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
619
+ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
620
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
621
+ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
622
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
623
+ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
624
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
625
+ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
626
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
627
+ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
628
+ };
629
+
630
+ /* forward tables */
631
+
632
+ #define FT \
633
+ \
634
+ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
635
+ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
636
+ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
637
+ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
638
+ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
639
+ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
640
+ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
641
+ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
642
+ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
643
+ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
644
+ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
645
+ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
646
+ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
647
+ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
648
+ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
649
+ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
650
+ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
651
+ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
652
+ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
653
+ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
654
+ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
655
+ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
656
+ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
657
+ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
658
+ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
659
+ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
660
+ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
661
+ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
662
+ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
663
+ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
664
+ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
665
+ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
666
+ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
667
+ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
668
+ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
669
+ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
670
+ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
671
+ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
672
+ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
673
+ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
674
+ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
675
+ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
676
+ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
677
+ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
678
+ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
679
+ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
680
+ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
681
+ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
682
+ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
683
+ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
684
+ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
685
+ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
686
+ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
687
+ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
688
+ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
689
+ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
690
+ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
691
+ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
692
+ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
693
+ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
694
+ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
695
+ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
696
+ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
697
+ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
698
+
699
+ #define V(a,b,c,d) 0x##a##b##c##d
700
+ static const uint32_t FT0[256] = { FT };
701
+ #undef V
702
+
703
+ #define V(a,b,c,d) 0x##d##a##b##c
704
+ static const uint32_t FT1[256] = { FT };
705
+ #undef V
706
+
707
+ #define V(a,b,c,d) 0x##c##d##a##b
708
+ static const uint32_t FT2[256] = { FT };
709
+ #undef V
710
+
711
+ #define V(a,b,c,d) 0x##b##c##d##a
712
+ static const uint32_t FT3[256] = { FT };
713
+ #undef V
714
+
715
+ #undef FT
716
+
717
+ /* reverse S-box */
718
+
719
+ static const uint32_t RSb[256] =
720
+ {
721
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
722
+ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
723
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
724
+ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
725
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
726
+ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
727
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
728
+ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
729
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
730
+ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
731
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
732
+ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
733
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
734
+ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
735
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
736
+ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
737
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
738
+ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
739
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
740
+ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
741
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
742
+ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
743
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
744
+ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
745
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
746
+ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
747
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
748
+ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
749
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
750
+ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
751
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
752
+ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
753
+ };
754
+
755
+ /* reverse tables */
756
+
757
+ #define RT \
758
+ \
759
+ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
760
+ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
761
+ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
762
+ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
763
+ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
764
+ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
765
+ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
766
+ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
767
+ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
768
+ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
769
+ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
770
+ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
771
+ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
772
+ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
773
+ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
774
+ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
775
+ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
776
+ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
777
+ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
778
+ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
779
+ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
780
+ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
781
+ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
782
+ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
783
+ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
784
+ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
785
+ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
786
+ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
787
+ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
788
+ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
789
+ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
790
+ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
791
+ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
792
+ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
793
+ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
794
+ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
795
+ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
796
+ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
797
+ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
798
+ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
799
+ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
800
+ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
801
+ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
802
+ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
803
+ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
804
+ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
805
+ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
806
+ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
807
+ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
808
+ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
809
+ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
810
+ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
811
+ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
812
+ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
813
+ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
814
+ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
815
+ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
816
+ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
817
+ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
818
+ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
819
+ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
820
+ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
821
+ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
822
+ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
823
+
824
+ #define V(a,b,c,d) 0x##a##b##c##d
825
+ static const uint32_t RT0[256] = { RT };
826
+ #undef V
827
+
828
+ #define V(a,b,c,d) 0x##d##a##b##c
829
+ static const uint32_t RT1[256] = { RT };
830
+ #undef V
831
+
832
+ #define V(a,b,c,d) 0x##c##d##a##b
833
+ static const uint32_t RT2[256] = { RT };
834
+ #undef V
835
+
836
+ #define V(a,b,c,d) 0x##b##c##d##a
837
+ static const uint32_t RT3[256] = { RT };
838
+ #undef V
839
+
840
+ #undef RT
841
+
842
+ /* round constants */
843
+
844
+ static const uint32_t RCON[10] =
845
+ {
846
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
847
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
848
+ 0x1B000000, 0x36000000
849
+ };
850
+
851
+ void aes_gen_tables( void )
852
+ {
853
+ }
854
+
855
+ #endif
856
+
857
+ /* platform-independant 32-bit integer manipulation macros */
858
+
859
+ #define GET_UINT32(n,b,i) \
860
+ { \
861
+ (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
862
+ | ( (uint32_t) (b)[(i) + 1] << 16 ) \
863
+ | ( (uint32_t) (b)[(i) + 2] << 8 ) \
864
+ | ( (uint32_t) (b)[(i) + 3] ); \
865
+ }
866
+
867
+ #define PUT_UINT32(n,b,i) \
868
+ { \
869
+ (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \
870
+ (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \
871
+ (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \
872
+ (b)[(i) + 3] = (uint8_t) ( (n) ); \
873
+ }
874
+
875
+ /* decryption key schedule tables */
876
+
877
+ int KT_init = 1;
878
+
879
+ uint32_t KT0[256];
880
+ uint32_t KT1[256];
881
+ uint32_t KT2[256];
882
+ uint32_t KT3[256];
883
+
884
+ uint32_t initial_KT0[256];
885
+ uint32_t initial_KT1[256];
886
+ uint32_t initial_KT2[256];
887
+ uint32_t initial_KT3[256];
888
+
889
+ /* AES key scheduling routine */
890
+
891
+ int
892
+ sayaes_initialize_state(sayaes_t* sayaes)
893
+ {
894
+ int i;
895
+ uint32_t *RK, *SK;
896
+
897
+ switch( sayaes->key_bits )
898
+ {
899
+ case 128: sayaes->nr = 10; break;
900
+ case 192: sayaes->nr = 12; break;
901
+ case 256: sayaes->nr = 14; break;
902
+ default : return( 1 );
903
+ }
904
+
905
+ RK = sayaes->erk;
906
+
907
+ for( i = 0; i < (sayaes->key_bits >> 5); ++i )
908
+ {
909
+ GET_UINT32(
910
+ sayaes->erk[i],
911
+ ((unsigned char*)sayaes->key),
912
+ i * 4
913
+ );
914
+ }
915
+
916
+ /* setup encryption round keys */
917
+
918
+ switch( sayaes->key_bits )
919
+ {
920
+ case 128:
921
+
922
+ for( i = 0; i < 10; ++i, RK += 4 )
923
+ {
924
+ RK[4] = RK[0] ^ RCON[i] ^
925
+ ( FSb[ (uint8_t) ( RK[3] >> 16 ) ] << 24 ) ^
926
+ ( FSb[ (uint8_t) ( RK[3] >> 8 ) ] << 16 ) ^
927
+ ( FSb[ (uint8_t) ( RK[3] ) ] << 8 ) ^
928
+ ( FSb[ (uint8_t) ( RK[3] >> 24 ) ] );
929
+
930
+ RK[5] = RK[1] ^ RK[4];
931
+ RK[6] = RK[2] ^ RK[5];
932
+ RK[7] = RK[3] ^ RK[6];
933
+ }
934
+ break;
935
+
936
+ case 192:
937
+
938
+ for( i = 0; i < 8; ++i, RK += 6 )
939
+ {
940
+ RK[6] = RK[0] ^ RCON[i] ^
941
+ ( FSb[ (uint8_t) ( RK[5] >> 16 ) ] << 24 ) ^
942
+ ( FSb[ (uint8_t) ( RK[5] >> 8 ) ] << 16 ) ^
943
+ ( FSb[ (uint8_t) ( RK[5] ) ] << 8 ) ^
944
+ ( FSb[ (uint8_t) ( RK[5] >> 24 ) ] );
945
+
946
+ RK[7] = RK[1] ^ RK[6];
947
+ RK[8] = RK[2] ^ RK[7];
948
+ RK[9] = RK[3] ^ RK[8];
949
+ RK[10] = RK[4] ^ RK[9];
950
+ RK[11] = RK[5] ^ RK[10];
951
+ }
952
+ break;
953
+
954
+ case 256:
955
+
956
+ for( i = 0; i < 7; ++i, RK += 8 )
957
+ {
958
+ RK[8] = RK[0] ^ RCON[i] ^
959
+ ( FSb[ (uint8_t) ( RK[7] >> 16 ) ] << 24 ) ^
960
+ ( FSb[ (uint8_t) ( RK[7] >> 8 ) ] << 16 ) ^
961
+ ( FSb[ (uint8_t) ( RK[7] ) ] << 8 ) ^
962
+ ( FSb[ (uint8_t) ( RK[7] >> 24 ) ] );
963
+
964
+ RK[9] = RK[1] ^ RK[8];
965
+ RK[10] = RK[2] ^ RK[9];
966
+ RK[11] = RK[3] ^ RK[10];
967
+
968
+ RK[12] = RK[4] ^
969
+ ( FSb[ (uint8_t) ( RK[11] >> 24 ) ] << 24 ) ^
970
+ ( FSb[ (uint8_t) ( RK[11] >> 16 ) ] << 16 ) ^
971
+ ( FSb[ (uint8_t) ( RK[11] >> 8 ) ] << 8 ) ^
972
+ ( FSb[ (uint8_t) ( RK[11] ) ] );
973
+
974
+ RK[13] = RK[5] ^ RK[12];
975
+ RK[14] = RK[6] ^ RK[13];
976
+ RK[15] = RK[7] ^ RK[14];
977
+ }
978
+ break;
979
+ }
980
+
981
+ /* setup decryption round keys */
982
+
983
+ if( KT_init )
984
+ {
985
+ for( i = 0; i < 256; ++i )
986
+ {
987
+ KT0[i] = RT0[ FSb[i] ];
988
+ KT1[i] = RT1[ FSb[i] ];
989
+ KT2[i] = RT2[ FSb[i] ];
990
+ KT3[i] = RT3[ FSb[i] ];
991
+ }
992
+
993
+ KT_init = 0;
994
+ }
995
+
996
+ SK = sayaes->drk;
997
+
998
+ *SK++ = *RK++;
999
+ *SK++ = *RK++;
1000
+ *SK++ = *RK++;
1001
+ *SK++ = *RK++;
1002
+
1003
+ for( i = 1; i < sayaes->nr; ++i )
1004
+ {
1005
+ RK -= 8;
1006
+
1007
+ *SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
1008
+ KT1[ (uint8_t) ( *RK >> 16 ) ] ^
1009
+ KT2[ (uint8_t) ( *RK >> 8 ) ] ^
1010
+ KT3[ (uint8_t) ( *RK ) ]; RK++;
1011
+
1012
+ *SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
1013
+ KT1[ (uint8_t) ( *RK >> 16 ) ] ^
1014
+ KT2[ (uint8_t) ( *RK >> 8 ) ] ^
1015
+ KT3[ (uint8_t) ( *RK ) ]; RK++;
1016
+
1017
+ *SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
1018
+ KT1[ (uint8_t) ( *RK >> 16 ) ] ^
1019
+ KT2[ (uint8_t) ( *RK >> 8 ) ] ^
1020
+ KT3[ (uint8_t) ( *RK ) ]; RK++;
1021
+
1022
+ *SK++ = KT0[ (uint8_t) ( *RK >> 24 ) ] ^
1023
+ KT1[ (uint8_t) ( *RK >> 16 ) ] ^
1024
+ KT2[ (uint8_t) ( *RK >> 8 ) ] ^
1025
+ KT3[ (uint8_t) ( *RK ) ]; RK++;
1026
+ }
1027
+
1028
+ RK -= 8;
1029
+
1030
+ *SK++ = *RK++;
1031
+ *SK++ = *RK++;
1032
+ *SK++ = *RK++;
1033
+ *SK++ = *RK++;
1034
+
1035
+ /* setup values for quick re-initialization */
1036
+ memcpy(sayaes->initial_erk, sayaes->erk, sizeof(sayaes->initial_erk));
1037
+ memcpy(sayaes->initial_drk, sayaes->drk, sizeof(sayaes->initial_drk));
1038
+ return 0;
1039
+ }
1040
+
1041
+ int
1042
+ sayaes_reinitialize_state(sayaes_t* sayaes)
1043
+ {
1044
+ /* put round keys for encryption and decryption back to their initial
1045
+ // states so we can encrypt and decrypt new items properly
1046
+ */
1047
+ memcpy(sayaes->erk, sayaes->initial_erk, sizeof(sayaes->initial_erk));
1048
+ memcpy(sayaes->drk, sayaes->initial_drk, sizeof(sayaes->initial_drk));
1049
+
1050
+ return 0;
1051
+ }
1052
+
1053
+ /* AES 128-bit block encryption routine */
1054
+
1055
+ void
1056
+ sayaes_encrypt_block(sayaes_t* sayaes, uint8_t input[16], uint8_t output[16])
1057
+ {
1058
+ uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1059
+
1060
+ RK = sayaes->erk;
1061
+
1062
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1063
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
1064
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
1065
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
1066
+
1067
+ #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1068
+ { \
1069
+ RK += 4; \
1070
+ \
1071
+ X0 = RK[0] ^ FT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \
1072
+ FT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \
1073
+ FT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \
1074
+ FT3[ (uint8_t) ( Y3 ) ]; \
1075
+ \
1076
+ X1 = RK[1] ^ FT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \
1077
+ FT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \
1078
+ FT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \
1079
+ FT3[ (uint8_t) ( Y0 ) ]; \
1080
+ \
1081
+ X2 = RK[2] ^ FT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \
1082
+ FT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \
1083
+ FT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \
1084
+ FT3[ (uint8_t) ( Y1 ) ]; \
1085
+ \
1086
+ X3 = RK[3] ^ FT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \
1087
+ FT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \
1088
+ FT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \
1089
+ FT3[ (uint8_t) ( Y2 ) ]; \
1090
+ }
1091
+
1092
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
1093
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
1094
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
1095
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
1096
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
1097
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
1098
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
1099
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
1100
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
1101
+
1102
+ if( sayaes->nr > 10 )
1103
+ {
1104
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
1105
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
1106
+ }
1107
+
1108
+ if( sayaes->nr > 12 )
1109
+ {
1110
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
1111
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
1112
+ }
1113
+
1114
+ /* last round */
1115
+
1116
+ RK += 4;
1117
+
1118
+ X0 = RK[0] ^ ( FSb[ (uint8_t) ( Y0 >> 24 ) ] << 24 ) ^
1119
+ ( FSb[ (uint8_t) ( Y1 >> 16 ) ] << 16 ) ^
1120
+ ( FSb[ (uint8_t) ( Y2 >> 8 ) ] << 8 ) ^
1121
+ ( FSb[ (uint8_t) ( Y3 ) ] );
1122
+
1123
+ X1 = RK[1] ^ ( FSb[ (uint8_t) ( Y1 >> 24 ) ] << 24 ) ^
1124
+ ( FSb[ (uint8_t) ( Y2 >> 16 ) ] << 16 ) ^
1125
+ ( FSb[ (uint8_t) ( Y3 >> 8 ) ] << 8 ) ^
1126
+ ( FSb[ (uint8_t) ( Y0 ) ] );
1127
+
1128
+ X2 = RK[2] ^ ( FSb[ (uint8_t) ( Y2 >> 24 ) ] << 24 ) ^
1129
+ ( FSb[ (uint8_t) ( Y3 >> 16 ) ] << 16 ) ^
1130
+ ( FSb[ (uint8_t) ( Y0 >> 8 ) ] << 8 ) ^
1131
+ ( FSb[ (uint8_t) ( Y1 ) ] );
1132
+
1133
+ X3 = RK[3] ^ ( FSb[ (uint8_t) ( Y3 >> 24 ) ] << 24 ) ^
1134
+ ( FSb[ (uint8_t) ( Y0 >> 16 ) ] << 16 ) ^
1135
+ ( FSb[ (uint8_t) ( Y1 >> 8 ) ] << 8 ) ^
1136
+ ( FSb[ (uint8_t) ( Y2 ) ] );
1137
+
1138
+ PUT_UINT32( X0, output, 0 );
1139
+ PUT_UINT32( X1, output, 4 );
1140
+ PUT_UINT32( X2, output, 8 );
1141
+ PUT_UINT32( X3, output, 12 );
1142
+ }
1143
+
1144
+ /* AES 128-bit block decryption routine */
1145
+
1146
+ void
1147
+ sayaes_decrypt_block(sayaes_t* sayaes, uint8_t input[16], uint8_t output[16])
1148
+ {
1149
+ uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1150
+
1151
+ RK = sayaes->drk;
1152
+
1153
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1154
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
1155
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
1156
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
1157
+
1158
+ #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1159
+ { \
1160
+ RK += 4; \
1161
+ \
1162
+ X0 = RK[0] ^ RT0[ (uint8_t) ( Y0 >> 24 ) ] ^ \
1163
+ RT1[ (uint8_t) ( Y3 >> 16 ) ] ^ \
1164
+ RT2[ (uint8_t) ( Y2 >> 8 ) ] ^ \
1165
+ RT3[ (uint8_t) ( Y1 ) ]; \
1166
+ \
1167
+ X1 = RK[1] ^ RT0[ (uint8_t) ( Y1 >> 24 ) ] ^ \
1168
+ RT1[ (uint8_t) ( Y0 >> 16 ) ] ^ \
1169
+ RT2[ (uint8_t) ( Y3 >> 8 ) ] ^ \
1170
+ RT3[ (uint8_t) ( Y2 ) ]; \
1171
+ \
1172
+ X2 = RK[2] ^ RT0[ (uint8_t) ( Y2 >> 24 ) ] ^ \
1173
+ RT1[ (uint8_t) ( Y1 >> 16 ) ] ^ \
1174
+ RT2[ (uint8_t) ( Y0 >> 8 ) ] ^ \
1175
+ RT3[ (uint8_t) ( Y3 ) ]; \
1176
+ \
1177
+ X3 = RK[3] ^ RT0[ (uint8_t) ( Y3 >> 24 ) ] ^ \
1178
+ RT1[ (uint8_t) ( Y2 >> 16 ) ] ^ \
1179
+ RT2[ (uint8_t) ( Y1 >> 8 ) ] ^ \
1180
+ RT3[ (uint8_t) ( Y0 ) ]; \
1181
+ }
1182
+
1183
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
1184
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
1185
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
1186
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
1187
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
1188
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
1189
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
1190
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
1191
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
1192
+
1193
+ if( sayaes->nr > 10 )
1194
+ {
1195
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
1196
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
1197
+ }
1198
+
1199
+ if( sayaes->nr > 12 )
1200
+ {
1201
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
1202
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
1203
+ }
1204
+
1205
+ /* last round */
1206
+
1207
+ RK += 4;
1208
+
1209
+ X0 = RK[0] ^ ( RSb[ (uint8_t) ( Y0 >> 24 ) ] << 24 ) ^
1210
+ ( RSb[ (uint8_t) ( Y3 >> 16 ) ] << 16 ) ^
1211
+ ( RSb[ (uint8_t) ( Y2 >> 8 ) ] << 8 ) ^
1212
+ ( RSb[ (uint8_t) ( Y1 ) ] );
1213
+
1214
+ X1 = RK[1] ^ ( RSb[ (uint8_t) ( Y1 >> 24 ) ] << 24 ) ^
1215
+ ( RSb[ (uint8_t) ( Y0 >> 16 ) ] << 16 ) ^
1216
+ ( RSb[ (uint8_t) ( Y3 >> 8 ) ] << 8 ) ^
1217
+ ( RSb[ (uint8_t) ( Y2 ) ] );
1218
+
1219
+ X2 = RK[2] ^ ( RSb[ (uint8_t) ( Y2 >> 24 ) ] << 24 ) ^
1220
+ ( RSb[ (uint8_t) ( Y1 >> 16 ) ] << 16 ) ^
1221
+ ( RSb[ (uint8_t) ( Y0 >> 8 ) ] << 8 ) ^
1222
+ ( RSb[ (uint8_t) ( Y3 ) ] );
1223
+
1224
+ X3 = RK[3] ^ ( RSb[ (uint8_t) ( Y3 >> 24 ) ] << 24 ) ^
1225
+ ( RSb[ (uint8_t) ( Y2 >> 16 ) ] << 16 ) ^
1226
+ ( RSb[ (uint8_t) ( Y1 >> 8 ) ] << 8 ) ^
1227
+ ( RSb[ (uint8_t) ( Y0 ) ] );
1228
+
1229
+ PUT_UINT32( X0, output, 0 );
1230
+ PUT_UINT32( X1, output, 4 );
1231
+ PUT_UINT32( X2, output, 8 );
1232
+ PUT_UINT32( X3, output, 12 );
1233
+ }
1234
+