1 /* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
2 * Copyright 2018 Pawel Bylica.
3 * Licensed under the Apache License, Version 2.0. See the LICENSE file.
4 */
5
6 #include <stdint.h>
7
rol(uint64_t x,unsigned s)8 static uint64_t rol(uint64_t x, unsigned s)
9 {
10 return (x << s) | (x >> (64 - s));
11 }
12
13 static const uint64_t round_constants[24] = {
14 0x0000000000000001,
15 0x0000000000008082,
16 0x800000000000808a,
17 0x8000000080008000,
18 0x000000000000808b,
19 0x0000000080000001,
20 0x8000000080008081,
21 0x8000000000008009,
22 0x000000000000008a,
23 0x0000000000000088,
24 0x0000000080008009,
25 0x000000008000000a,
26 0x000000008000808b,
27 0x800000000000008b,
28 0x8000000000008089,
29 0x8000000000008003,
30 0x8000000000008002,
31 0x8000000000000080,
32 0x000000000000800a,
33 0x800000008000000a,
34 0x8000000080008081,
35 0x8000000000008080,
36 0x0000000080000001,
37 0x8000000080008008,
38 };
39
ethash_keccakf1600(uint64_t state[25])40 void ethash_keccakf1600(uint64_t state[25])
41 {
42 /* The implementation based on the "simple" implementation by Ronny Van Keer. */
43
44 int round;
45
46 uint64_t Aba, Abe, Abi, Abo, Abu;
47 uint64_t Aga, Age, Agi, Ago, Agu;
48 uint64_t Aka, Ake, Aki, Ako, Aku;
49 uint64_t Ama, Ame, Ami, Amo, Amu;
50 uint64_t Asa, Ase, Asi, Aso, Asu;
51
52 uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
53 uint64_t Ega, Ege, Egi, Ego, Egu;
54 uint64_t Eka, Eke, Eki, Eko, Eku;
55 uint64_t Ema, Eme, Emi, Emo, Emu;
56 uint64_t Esa, Ese, Esi, Eso, Esu;
57
58 uint64_t Ba, Be, Bi, Bo, Bu;
59
60 uint64_t Da, De, Di, Do, Du;
61
62 Aba = state[0];
63 Abe = state[1];
64 Abi = state[2];
65 Abo = state[3];
66 Abu = state[4];
67 Aga = state[5];
68 Age = state[6];
69 Agi = state[7];
70 Ago = state[8];
71 Agu = state[9];
72 Aka = state[10];
73 Ake = state[11];
74 Aki = state[12];
75 Ako = state[13];
76 Aku = state[14];
77 Ama = state[15];
78 Ame = state[16];
79 Ami = state[17];
80 Amo = state[18];
81 Amu = state[19];
82 Asa = state[20];
83 Ase = state[21];
84 Asi = state[22];
85 Aso = state[23];
86 Asu = state[24];
87
88 for (round = 0; round < 24; round += 2)
89 {
90 /* Round (round + 0): Axx -> Exx */
91
92 Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
93 Be = Abe ^ Age ^ Ake ^ Ame ^ Ase;
94 Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
95 Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
96 Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
97
98 Da = Bu ^ rol(Be, 1);
99 De = Ba ^ rol(Bi, 1);
100 Di = Be ^ rol(Bo, 1);
101 Do = Bi ^ rol(Bu, 1);
102 Du = Bo ^ rol(Ba, 1);
103
104 Ba = Aba ^ Da;
105 Be = rol(Age ^ De, 44);
106 Bi = rol(Aki ^ Di, 43);
107 Bo = rol(Amo ^ Do, 21);
108 Bu = rol(Asu ^ Du, 14);
109 Eba = Ba ^ (~Be & Bi) ^ round_constants[round];
110 Ebe = Be ^ (~Bi & Bo);
111 Ebi = Bi ^ (~Bo & Bu);
112 Ebo = Bo ^ (~Bu & Ba);
113 Ebu = Bu ^ (~Ba & Be);
114
115 Ba = rol(Abo ^ Do, 28);
116 Be = rol(Agu ^ Du, 20);
117 Bi = rol(Aka ^ Da, 3);
118 Bo = rol(Ame ^ De, 45);
119 Bu = rol(Asi ^ Di, 61);
120 Ega = Ba ^ (~Be & Bi);
121 Ege = Be ^ (~Bi & Bo);
122 Egi = Bi ^ (~Bo & Bu);
123 Ego = Bo ^ (~Bu & Ba);
124 Egu = Bu ^ (~Ba & Be);
125
126 Ba = rol(Abe ^ De, 1);
127 Be = rol(Agi ^ Di, 6);
128 Bi = rol(Ako ^ Do, 25);
129 Bo = rol(Amu ^ Du, 8);
130 Bu = rol(Asa ^ Da, 18);
131 Eka = Ba ^ (~Be & Bi);
132 Eke = Be ^ (~Bi & Bo);
133 Eki = Bi ^ (~Bo & Bu);
134 Eko = Bo ^ (~Bu & Ba);
135 Eku = Bu ^ (~Ba & Be);
136
137 Ba = rol(Abu ^ Du, 27);
138 Be = rol(Aga ^ Da, 36);
139 Bi = rol(Ake ^ De, 10);
140 Bo = rol(Ami ^ Di, 15);
141 Bu = rol(Aso ^ Do, 56);
142 Ema = Ba ^ (~Be & Bi);
143 Eme = Be ^ (~Bi & Bo);
144 Emi = Bi ^ (~Bo & Bu);
145 Emo = Bo ^ (~Bu & Ba);
146 Emu = Bu ^ (~Ba & Be);
147
148 Ba = rol(Abi ^ Di, 62);
149 Be = rol(Ago ^ Do, 55);
150 Bi = rol(Aku ^ Du, 39);
151 Bo = rol(Ama ^ Da, 41);
152 Bu = rol(Ase ^ De, 2);
153 Esa = Ba ^ (~Be & Bi);
154 Ese = Be ^ (~Bi & Bo);
155 Esi = Bi ^ (~Bo & Bu);
156 Eso = Bo ^ (~Bu & Ba);
157 Esu = Bu ^ (~Ba & Be);
158
159
160 /* Round (round + 1): Exx -> Axx */
161
162 Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
163 Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
164 Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
165 Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
166 Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
167
168 Da = Bu ^ rol(Be, 1);
169 De = Ba ^ rol(Bi, 1);
170 Di = Be ^ rol(Bo, 1);
171 Do = Bi ^ rol(Bu, 1);
172 Du = Bo ^ rol(Ba, 1);
173
174 Ba = Eba ^ Da;
175 Be = rol(Ege ^ De, 44);
176 Bi = rol(Eki ^ Di, 43);
177 Bo = rol(Emo ^ Do, 21);
178 Bu = rol(Esu ^ Du, 14);
179 Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1];
180 Abe = Be ^ (~Bi & Bo);
181 Abi = Bi ^ (~Bo & Bu);
182 Abo = Bo ^ (~Bu & Ba);
183 Abu = Bu ^ (~Ba & Be);
184
185 Ba = rol(Ebo ^ Do, 28);
186 Be = rol(Egu ^ Du, 20);
187 Bi = rol(Eka ^ Da, 3);
188 Bo = rol(Eme ^ De, 45);
189 Bu = rol(Esi ^ Di, 61);
190 Aga = Ba ^ (~Be & Bi);
191 Age = Be ^ (~Bi & Bo);
192 Agi = Bi ^ (~Bo & Bu);
193 Ago = Bo ^ (~Bu & Ba);
194 Agu = Bu ^ (~Ba & Be);
195
196 Ba = rol(Ebe ^ De, 1);
197 Be = rol(Egi ^ Di, 6);
198 Bi = rol(Eko ^ Do, 25);
199 Bo = rol(Emu ^ Du, 8);
200 Bu = rol(Esa ^ Da, 18);
201 Aka = Ba ^ (~Be & Bi);
202 Ake = Be ^ (~Bi & Bo);
203 Aki = Bi ^ (~Bo & Bu);
204 Ako = Bo ^ (~Bu & Ba);
205 Aku = Bu ^ (~Ba & Be);
206
207 Ba = rol(Ebu ^ Du, 27);
208 Be = rol(Ega ^ Da, 36);
209 Bi = rol(Eke ^ De, 10);
210 Bo = rol(Emi ^ Di, 15);
211 Bu = rol(Eso ^ Do, 56);
212 Ama = Ba ^ (~Be & Bi);
213 Ame = Be ^ (~Bi & Bo);
214 Ami = Bi ^ (~Bo & Bu);
215 Amo = Bo ^ (~Bu & Ba);
216 Amu = Bu ^ (~Ba & Be);
217
218 Ba = rol(Ebi ^ Di, 62);
219 Be = rol(Ego ^ Do, 55);
220 Bi = rol(Eku ^ Du, 39);
221 Bo = rol(Ema ^ Da, 41);
222 Bu = rol(Ese ^ De, 2);
223 Asa = Ba ^ (~Be & Bi);
224 Ase = Be ^ (~Bi & Bo);
225 Asi = Bi ^ (~Bo & Bu);
226 Aso = Bo ^ (~Bu & Ba);
227 Asu = Bu ^ (~Ba & Be);
228 }
229
230 state[0] = Aba;
231 state[1] = Abe;
232 state[2] = Abi;
233 state[3] = Abo;
234 state[4] = Abu;
235 state[5] = Aga;
236 state[6] = Age;
237 state[7] = Agi;
238 state[8] = Ago;
239 state[9] = Agu;
240 state[10] = Aka;
241 state[11] = Ake;
242 state[12] = Aki;
243 state[13] = Ako;
244 state[14] = Aku;
245 state[15] = Ama;
246 state[16] = Ame;
247 state[17] = Ami;
248 state[18] = Amo;
249 state[19] = Amu;
250 state[20] = Asa;
251 state[21] = Ase;
252 state[22] = Asi;
253 state[23] = Aso;
254 state[24] = Asu;
255 }
256