1 /*
2  *   Copyright (c) 2015, Andrew Romanenko <melanhit@gmail.com>
3  *   All rights reserved.
4  *
5  *   Redistribution and use in source and binary forms, with or without
6  *   modification, are permitted provided that the following conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright notice, this
9  *      list of conditions and the following disclaimer.
10  *   2. Redistributions in binary form must reproduce the above copyright notice,
11  *      this list of conditions and the following disclaimer in the documentation
12  *      and/or other materials provided with the distribution.
13  *   3. Neither the name of the project nor the names of its contributors
14  *      may be used to endorse or promote products derived from this software
15  *      without specific prior written permission.
16  *
17  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
18  *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  *   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21  *   ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef AKMOS_ALGO_THREEFISH_MIX_H
30 #define AKMOS_ALGO_THREEFISH_MIX_H
31 
32 #define threefish_256_emix(x, d1, d2, d3, d4)                   \
33 {                                                               \
34     x[0] += x[1]; x[1] = ROTL64(x[1], d1) ^ x[0];               \
35     x[2] += x[3]; x[3] = ROTL64(x[3], d2) ^ x[2];               \
36                                                                 \
37     x[0] += x[3]; x[3] = ROTL64(x[3], d3) ^ x[0];               \
38     x[2] += x[1]; x[1] = ROTL64(x[1], d4) ^ x[2];               \
39 }
40 
41 #define threefish_256_dmix(x, d1, d2, d3, d4)                   \
42 {                                                               \
43     x[3] ^= x[0]; x[3] = ROTR64(x[3], d1); x[0] -= x[3];        \
44     x[1] ^= x[2]; x[1] = ROTR64(x[1], d2); x[2] -= x[1];        \
45                                                                 \
46     x[1] ^= x[0]; x[1] = ROTR64(x[1], d3); x[0] -= x[1];        \
47     x[3] ^= x[2]; x[3] = ROTR64(x[3], d4); x[2] -= x[3];        \
48 }
49 
50 #define threefish_512_emix1(x, d1, d2, d3, d4)                  \
51 {                                                               \
52     x[0] += x[1]; x[1] = ROTL64(x[1], d1) ^ x[0];               \
53     x[2] += x[3]; x[3] = ROTL64(x[3], d2) ^ x[2];               \
54     x[4] += x[5]; x[5] = ROTL64(x[5], d3) ^ x[4];               \
55     x[6] += x[7]; x[7] = ROTL64(x[7], d4) ^ x[6];               \
56 }
57 
58 #define threefish_512_emix2(x, d1, d2, d3, d4)                  \
59 {                                                               \
60     x[2] += x[1]; x[1] = ROTL64(x[1], d1) ^ x[2];               \
61     x[4] += x[7]; x[7] = ROTL64(x[7], d2) ^ x[4];               \
62     x[6] += x[5]; x[5] = ROTL64(x[5], d3) ^ x[6];               \
63     x[0] += x[3]; x[3] = ROTL64(x[3], d4) ^ x[0];               \
64 }
65 
66 #define threefish_512_emix3(x, d1, d2, d3, d4)                  \
67 {                                                               \
68     x[4] += x[1]; x[1] = ROTL64(x[1], d1) ^ x[4];               \
69     x[6] += x[3]; x[3] = ROTL64(x[3], d2) ^ x[6];               \
70     x[0] += x[5]; x[5] = ROTL64(x[5], d3) ^ x[0];               \
71     x[2] += x[7]; x[7] = ROTL64(x[7], d4) ^ x[2];               \
72 }
73 
74 #define threefish_512_emix4(x, d1, d2, d3, d4)                  \
75 {                                                               \
76     x[6] += x[1]; x[1] = ROTL64(x[1], d1) ^ x[6];               \
77     x[0] += x[7]; x[7] = ROTL64(x[7], d2) ^ x[0];               \
78     x[2] += x[5]; x[5] = ROTL64(x[5], d3) ^ x[2];               \
79     x[4] += x[3]; x[3] = ROTL64(x[3], d4) ^ x[4];               \
80 }
81 
82 #define threefish_512_dmix1(x, d1, d2, d3, d4)                  \
83 {                                                               \
84     x[3] ^= x[4]; x[3] = ROTR64(x[3], d1); x[4] -= x[3];        \
85     x[5] ^= x[2]; x[5] = ROTR64(x[5], d2); x[2] -= x[5];        \
86     x[7] ^= x[0]; x[7] = ROTR64(x[7], d3); x[0] -= x[7];        \
87     x[1] ^= x[6]; x[1] = ROTR64(x[1], d4); x[6] -= x[1];        \
88 }
89 
90 #define threefish_512_dmix2(x, d1, d2, d3, d4)                  \
91 {                                                               \
92     x[7] ^= x[2]; x[7] = ROTR64(x[7], d1); x[2] -= x[7];        \
93     x[5] ^= x[0]; x[5] = ROTR64(x[5], d2); x[0] -= x[5];        \
94     x[3] ^= x[6]; x[3] = ROTR64(x[3], d3); x[6] -= x[3];        \
95     x[1] ^= x[4]; x[1] = ROTR64(x[1], d4); x[4] -= x[1];        \
96 }
97 
98 #define threefish_512_dmix3(x, d1, d2, d3, d4)                  \
99 {                                                               \
100     x[3] ^= x[0]; x[3] = ROTR64(x[3], d1); x[0] -= x[3];        \
101     x[5] ^= x[6]; x[5] = ROTR64(x[5], d2); x[6] -= x[5];        \
102     x[7] ^= x[4]; x[7] = ROTR64(x[7], d3); x[4] -= x[7];        \
103     x[1] ^= x[2]; x[1] = ROTR64(x[1], d4); x[2] -= x[1];        \
104 }
105 
106 #define threefish_512_dmix4(x, d1, d2, d3, d4)                  \
107 {                                                               \
108     x[7] ^= x[6]; x[7] = ROTR64(x[7], d1); x[6] -= x[7];        \
109     x[5] ^= x[4]; x[5] = ROTR64(x[5], d2); x[4] -= x[5];        \
110     x[3] ^= x[2]; x[3] = ROTR64(x[3], d3); x[2] -= x[3];        \
111     x[1] ^= x[0]; x[1] = ROTR64(x[1], d4); x[0] -= x[1];        \
112 }
113 
114 #define threefish_1024_emix1(x, d1, d2, d3, d4, d5, d6, d7, d8) \
115 {                                                               \
116     x[ 0] += x[ 1]; x[ 1] = ROTL64(x[ 1], d1) ^ x[ 0];          \
117     x[ 2] += x[ 3]; x[ 3] = ROTL64(x[ 3], d2) ^ x[ 2];          \
118     x[ 4] += x[ 5]; x[ 5] = ROTL64(x[ 5], d3) ^ x[ 4];          \
119     x[ 6] += x[ 7]; x[ 7] = ROTL64(x[ 7], d4) ^ x[ 6];          \
120     x[ 8] += x[ 9]; x[ 9] = ROTL64(x[ 9], d5) ^ x[ 8];          \
121     x[10] += x[11]; x[11] = ROTL64(x[11], d6) ^ x[10];          \
122     x[12] += x[13]; x[13] = ROTL64(x[13], d7) ^ x[12];          \
123     x[14] += x[15]; x[15] = ROTL64(x[15], d8) ^ x[14];          \
124 }
125 
126 #define threefish_1024_emix2(x, d1, d2, d3, d4, d5, d6, d7, d8) \
127 {                                                               \
128     x[ 0] += x[ 9]; x[ 9] = ROTL64(x[ 9], d1) ^ x[ 0];          \
129     x[ 2] += x[13]; x[13] = ROTL64(x[13], d2) ^ x[ 2];          \
130     x[ 6] += x[11]; x[11] = ROTL64(x[11], d3) ^ x[ 6];          \
131     x[ 4] += x[15]; x[15] = ROTL64(x[15], d4) ^ x[ 4];          \
132     x[10] += x[ 7]; x[ 7] = ROTL64(x[ 7], d5) ^ x[10];          \
133     x[12] += x[ 3]; x[ 3] = ROTL64(x[ 3], d6) ^ x[12];          \
134     x[14] += x[ 5]; x[ 5] = ROTL64(x[ 5], d7) ^ x[14];          \
135     x[ 8] += x[ 1]; x[ 1] = ROTL64(x[ 1], d8) ^ x[ 8];          \
136 }
137 
138 #define threefish_1024_emix3(x, d1, d2, d3, d4, d5, d6, d7, d8) \
139 {                                                               \
140     x[ 0] += x[ 7]; x[ 7] = ROTL64(x[ 7], d1) ^ x[ 0];          \
141     x[ 2] += x[ 5]; x[ 5] = ROTL64(x[ 5], d2) ^ x[ 2];          \
142     x[ 4] += x[ 3]; x[ 3] = ROTL64(x[ 3], d3) ^ x[ 4];          \
143     x[ 6] += x[ 1]; x[ 1] = ROTL64(x[ 1], d4) ^ x[ 6];          \
144     x[12] += x[15]; x[15] = ROTL64(x[15], d5) ^ x[12];          \
145     x[14] += x[13]; x[13] = ROTL64(x[13], d6) ^ x[14];          \
146     x[ 8] += x[11]; x[11] = ROTL64(x[11], d7) ^ x[ 8];          \
147     x[10] += x[ 9]; x[ 9] = ROTL64(x[ 9], d8) ^ x[10];          \
148 }
149 
150 #define threefish_1024_emix4(x, d1, d2, d3, d4, d5, d6, d7, d8) \
151 {                                                               \
152     x[ 0] += x[15]; x[15] = ROTL64(x[15], d1) ^ x[ 0];          \
153     x[ 2] += x[11]; x[11] = ROTL64(x[11], d2) ^ x[ 2];          \
154     x[ 6] += x[13]; x[13] = ROTL64(x[13], d3) ^ x[ 6];          \
155     x[ 4] += x[ 9]; x[ 9] = ROTL64(x[ 9], d4) ^ x[ 4];          \
156     x[14] += x[ 1]; x[ 1] = ROTL64(x[ 1], d5) ^ x[14];          \
157     x[ 8] += x[ 5]; x[ 5] = ROTL64(x[ 5], d6) ^ x[ 8];          \
158     x[10] += x[ 3]; x[ 3] = ROTL64(x[ 3], d7) ^ x[10];          \
159     x[12] += x[ 7]; x[ 7] = ROTL64(x[ 7], d8) ^ x[12];          \
160 }
161 
162 #define threefish_1024_dmix1(x, d1, d2, d3, d4, d5, d6, d7, d8) \
163 {                                                               \
164     x[ 7] ^= x[12]; x[ 7] = ROTR64(x[ 7], d1); x[12] -= x[ 7];  \
165     x[ 3] ^= x[10]; x[ 3] = ROTR64(x[ 3], d2); x[10] -= x[ 3];  \
166     x[ 5] ^= x[ 8]; x[ 5] = ROTR64(x[ 5], d3); x[ 8] -= x[ 5];  \
167     x[ 1] ^= x[14]; x[ 1] = ROTR64(x[ 1], d4); x[14] -= x[ 1];  \
168     x[ 9] ^= x[ 4]; x[ 9] = ROTR64(x[ 9], d5); x[ 4] -= x[ 9];  \
169     x[13] ^= x[ 6]; x[13] = ROTR64(x[13], d6); x[ 6] -= x[13];  \
170     x[11] ^= x[ 2]; x[11] = ROTR64(x[11], d7); x[ 2] -= x[11];  \
171     x[15] ^= x[ 0]; x[15] = ROTR64(x[15], d8); x[ 0] -= x[15];  \
172 }
173 
174 #define threefish_1024_dmix2(x, d1, d2, d3, d4, d5, d6, d7, d8) \
175 {                                                               \
176     x[ 9] ^= x[10]; x[ 9] = ROTR64(x[ 9], d1); x[10] -= x[ 9];  \
177     x[11] ^= x[ 8]; x[11] = ROTR64(x[11], d2); x[ 8] -= x[11];  \
178     x[13] ^= x[14]; x[13] = ROTR64(x[13], d3); x[14] -= x[13];  \
179     x[15] ^= x[12]; x[15] = ROTR64(x[15], d4); x[12] -= x[15];  \
180     x[ 1] ^= x[ 6]; x[ 1] = ROTR64(x[ 1], d5); x[ 6] -= x[ 1];  \
181     x[ 3] ^= x[ 4]; x[ 3] = ROTR64(x[ 3], d6); x[ 4] -= x[ 3];  \
182     x[ 5] ^= x[ 2]; x[ 5] = ROTR64(x[ 5], d7); x[ 2] -= x[ 5];  \
183     x[ 7] ^= x[ 0]; x[ 7] = ROTR64(x[ 7], d8); x[ 0] -= x[ 7];  \
184 }
185 
186 #define threefish_1024_dmix3(x, d1, d2, d3, d4, d5, d6, d7, d8) \
187 {                                                               \
188     x[ 1] ^= x[ 8]; x[ 1] = ROTR64(x[ 1], d1); x[ 8] -= x[ 1];  \
189     x[ 5] ^= x[14]; x[ 5] = ROTR64(x[ 5], d2); x[14] -= x[ 5];  \
190     x[ 3] ^= x[12]; x[ 3] = ROTR64(x[ 3], d3); x[12] -= x[ 3];  \
191     x[ 7] ^= x[10]; x[ 7] = ROTR64(x[ 7], d4); x[10] -= x[ 7];  \
192     x[15] ^= x[ 4]; x[15] = ROTR64(x[15], d5); x[ 4] -= x[15];  \
193     x[11] ^= x[ 6]; x[11] = ROTR64(x[11], d6); x[ 6] -= x[11];  \
194     x[13] ^= x[ 2]; x[13] = ROTR64(x[13], d7); x[ 2] -= x[13];  \
195     x[ 9] ^= x[ 0]; x[ 9] = ROTR64(x[ 9], d8); x[ 0] -= x[ 9];  \
196 }
197 
198 #define threefish_1024_dmix4(x, d1, d2, d3, d4, d5, d6, d7, d8) \
199 {                                                               \
200     x[15] ^= x[14]; x[15] = ROTR64(x[15], d1); x[14] -= x[15];  \
201     x[13] ^= x[12]; x[13] = ROTR64(x[13], d2); x[12] -= x[13];  \
202     x[11] ^= x[10]; x[11] = ROTR64(x[11], d3); x[10] -= x[11];  \
203     x[ 9] ^= x[ 8]; x[ 9] = ROTR64(x[ 9], d4); x[ 8] -= x[ 9];  \
204     x[ 7] ^= x[ 6]; x[ 7] = ROTR64(x[ 7], d5); x[ 6] -= x[ 7];  \
205     x[ 5] ^= x[ 4]; x[ 5] = ROTR64(x[ 5], d6); x[ 4] -= x[ 5];  \
206     x[ 3] ^= x[ 2]; x[ 3] = ROTR64(x[ 3], d7); x[ 2] -= x[ 3];  \
207     x[ 1] ^= x[ 0]; x[ 1] = ROTR64(x[ 1], d8); x[ 0] -= x[ 1];  \
208 }
209 
210 #endif  /* AKMOS_ALGO_THREEFISH_MIX_H */
211