c9bd359ee42d745237f73cf5b525ba0fb0286adb
[trex.git] /
1 /*
2 version 20080912
3 D. J. Bernstein
4 Public domain.
5 */
6
7 #include "api.h"
8
9 #define ROUNDS 20
10
11 typedef unsigned int uint32;
12
13 static uint32 rotate(uint32 u,int c)
14 {
15   return (u << c) | (u >> (32 - c));
16 }
17
18 static uint32 load_littleendian(const unsigned char *x)
19 {
20   return
21       (uint32) (x[0]) \
22   | (((uint32) (x[1])) << 8) \
23   | (((uint32) (x[2])) << 16) \
24   | (((uint32) (x[3])) << 24)
25   ;
26 }
27
28 static void store_littleendian(unsigned char *x,uint32 u)
29 {
30   x[0] = u; u >>= 8;
31   x[1] = u; u >>= 8;
32   x[2] = u; u >>= 8;
33   x[3] = u;
34 }
35
36 int crypto_core(
37         unsigned char *out,
38   const unsigned char *in,
39   const unsigned char *k,
40   const unsigned char *c
41 )
42 {
43   uint32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
44   int i;
45
46   x0 = load_littleendian(c + 0);
47   x1 = load_littleendian(k + 0);
48   x2 = load_littleendian(k + 4);
49   x3 = load_littleendian(k + 8);
50   x4 = load_littleendian(k + 12);
51   x5 = load_littleendian(c + 4);
52   x6 = load_littleendian(in + 0);
53   x7 = load_littleendian(in + 4);
54   x8 = load_littleendian(in + 8);
55   x9 = load_littleendian(in + 12);
56   x10 = load_littleendian(c + 8);
57   x11 = load_littleendian(k + 16);
58   x12 = load_littleendian(k + 20);
59   x13 = load_littleendian(k + 24);
60   x14 = load_littleendian(k + 28);
61   x15 = load_littleendian(c + 12);
62
63   for (i = ROUNDS;i > 0;i -= 2) {
64      x4 ^= rotate( x0+x12, 7);
65      x8 ^= rotate( x4+ x0, 9);
66     x12 ^= rotate( x8+ x4,13);
67      x0 ^= rotate(x12+ x8,18);
68      x9 ^= rotate( x5+ x1, 7);
69     x13 ^= rotate( x9+ x5, 9);
70      x1 ^= rotate(x13+ x9,13);
71      x5 ^= rotate( x1+x13,18);
72     x14 ^= rotate(x10+ x6, 7);
73      x2 ^= rotate(x14+x10, 9);
74      x6 ^= rotate( x2+x14,13);
75     x10 ^= rotate( x6+ x2,18);
76      x3 ^= rotate(x15+x11, 7);
77      x7 ^= rotate( x3+x15, 9);
78     x11 ^= rotate( x7+ x3,13);
79     x15 ^= rotate(x11+ x7,18);
80      x1 ^= rotate( x0+ x3, 7);
81      x2 ^= rotate( x1+ x0, 9);
82      x3 ^= rotate( x2+ x1,13);
83      x0 ^= rotate( x3+ x2,18);
84      x6 ^= rotate( x5+ x4, 7);
85      x7 ^= rotate( x6+ x5, 9);
86      x4 ^= rotate( x7+ x6,13);
87      x5 ^= rotate( x4+ x7,18);
88     x11 ^= rotate(x10+ x9, 7);
89      x8 ^= rotate(x11+x10, 9);
90      x9 ^= rotate( x8+x11,13);
91     x10 ^= rotate( x9+ x8,18);
92     x12 ^= rotate(x15+x14, 7);
93     x13 ^= rotate(x12+x15, 9);
94     x14 ^= rotate(x13+x12,13);
95     x15 ^= rotate(x14+x13,18);
96   }
97
98   store_littleendian(out + 0,x0);
99   store_littleendian(out + 4,x5);
100   store_littleendian(out + 8,x10);
101   store_littleendian(out + 12,x15);
102   store_littleendian(out + 16,x6);
103   store_littleendian(out + 20,x7);
104   store_littleendian(out + 24,x8);
105   store_littleendian(out + 28,x9);
106
107   return 0;
108 }