1 // Copyright (c) 2012-2013 The Cryptonote developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <assert.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <string.h>
9
10 #include "memory.h"
11 #include "int-util.h"
12 #include "oaes_lib.h"
13 #include "blake256.h"
14 #include "groestl.h"
15 #include "jh.h"
16 #include "keccak.h"
17 #include "sph_skein.h"
18
19 union hash_state {
20 uint8_t b[200];
21 uint64_t w[25];
22 };
23
24 void hash_permutation(union hash_state *state);
25 void hash_process(union hash_state *state, const uint8_t *buf, size_t count);
26
27 enum {
28 HASH_SIZE = 32,
29 HASH_DATA_AREA = 136
30 };
31
32 void cn_fast_hash(const void *data, size_t length, char *hash);
33 void cn_slow_hash(const void *data, size_t length, char *hash);
34
35 void hash_extra_blake(const void *data, size_t length, char *hash);
36 void hash_extra_groestl(const void *data, size_t length, char *hash);
37 void hash_extra_jh(const void *data, size_t length, char *hash);
38 void hash_extra_skein(const void *data, size_t length, char *hash);
39
40 void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash);
41
42 static void (*const extra_hashes[4])(const void *, size_t, char *) = {
43 hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
44 };
45
hash_extra_blake(const void * data,size_t length,char * hash)46 void hash_extra_blake(const void *data, size_t length, char *hash)
47 {
48 blake256_hash((uint8_t*)hash, data, length);
49 }
50
hash_extra_groestl(const void * data,size_t length,char * hash)51 void hash_extra_groestl(const void *data, size_t length, char *hash)
52 {
53 groestl(data, length * 8, (uint8_t*)hash);
54 }
55
hash_extra_jh(const void * data,size_t length,char * hash)56 void hash_extra_jh(const void *data, size_t length, char *hash)
57 {
58 jh_hash(HASH_SIZE * 8, data, 8 * length, (uint8_t*)hash);
59 }
60
hash_extra_skein(const void * data,size_t length,char * hash)61 void hash_extra_skein(const void *data, size_t length, char *hash)
62 {
63 sph_skein256_context ctx;
64
65 sph_skein256_init(&ctx);
66 sph_skein256(&ctx, data, length);
67 sph_skein256_close(&ctx, (unsigned char*)hash);
68 }
69
70 #define MEMORY (1 << 21) /* 2 MiB */
71 #define ITER (1 << 20)
72 #define AES_BLOCK_SIZE 16
73 #define AES_KEY_SIZE 32 /*16*/
74 #define INIT_SIZE_BLK 8
75 #define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE)
76
e2i(const uint8_t * a,size_t count)77 static size_t e2i(const uint8_t* a, size_t count) { return (*((uint64_t*)a) / AES_BLOCK_SIZE) & (count - 1); }
78
mul(const uint8_t * a,const uint8_t * b,uint8_t * res)79 static void mul(const uint8_t* a, const uint8_t* b, uint8_t* res) {
80 uint64_t a0, b0;
81 uint64_t hi, lo;
82
83 a0 = SWAP64LE(((uint64_t*)a)[0]);
84 b0 = SWAP64LE(((uint64_t*)b)[0]);
85 lo = mul128(a0, b0, &hi);
86 ((uint64_t*)res)[0] = SWAP64LE(hi);
87 ((uint64_t*)res)[1] = SWAP64LE(lo);
88 }
89
sum_half_blocks(uint8_t * a,const uint8_t * b)90 static void sum_half_blocks(uint8_t* a, const uint8_t* b) {
91 uint64_t a0, a1, b0, b1;
92
93 a0 = SWAP64LE(((uint64_t*)a)[0]);
94 a1 = SWAP64LE(((uint64_t*)a)[1]);
95 b0 = SWAP64LE(((uint64_t*)b)[0]);
96 b1 = SWAP64LE(((uint64_t*)b)[1]);
97 a0 += b0;
98 a1 += b1;
99 ((uint64_t*)a)[0] = SWAP64LE(a0);
100 ((uint64_t*)a)[1] = SWAP64LE(a1);
101 }
102
copy_block(uint8_t * dst,const uint8_t * src)103 static void copy_block(uint8_t* dst, const uint8_t* src) {
104 memcpy(dst, src, AES_BLOCK_SIZE);
105 }
106
swap_blocks(uint8_t * a,uint8_t * b)107 static void swap_blocks(uint8_t* a, uint8_t* b) {
108 size_t i;
109 uint8_t t;
110 for (i = 0; i < AES_BLOCK_SIZE; i++) {
111 t = a[i];
112 a[i] = b[i];
113 b[i] = t;
114 }
115 }
116
xor_blocks(uint8_t * a,const uint8_t * b)117 static void xor_blocks(uint8_t* a, const uint8_t* b) {
118 size_t i;
119 for (i = 0; i < AES_BLOCK_SIZE; i++) {
120 a[i] ^= b[i];
121 }
122 }
123
124 #pragma pack(push, 1)
125 union cn_slow_hash_state {
126 union hash_state hs;
127 struct {
128 uint8_t k[64];
129 uint8_t init[INIT_SIZE_BYTE];
130 };
131 };
132 #pragma pack(pop)
133
hash_permutation(union hash_state * state)134 void hash_permutation(union hash_state *state)
135 {
136 keccakf((uint64_t*)state, 24);
137 }
138
hash_process(union hash_state * state,const uint8_t * buf,size_t count)139 void hash_process(union hash_state *state, const uint8_t *buf, size_t count)
140 {
141 keccak1600(buf, count, (uint8_t*)state);
142 }
143
cn_fast_hash(const void * data,size_t length,char * hash)144 void cn_fast_hash(const void *data, size_t length, char *hash)
145 {
146 union hash_state state;
147 hash_process(&state, data, length);
148 memcpy(hash, &state, HASH_SIZE);
149 }
150
cn_slow_hash(const void * data,size_t length,char * hash)151 void cn_slow_hash(const void *data, size_t length, char *hash)
152 {
153 //uint8_t long_state[MEMORY]; // This is 2 MB, too large for stack
154 uint8_t *long_state = mem_alloc(MEMORY);
155 union cn_slow_hash_state state;
156 uint8_t text[INIT_SIZE_BYTE];
157 uint8_t a[AES_BLOCK_SIZE];
158 uint8_t b[AES_BLOCK_SIZE];
159 uint8_t c[AES_BLOCK_SIZE];
160 uint8_t d[AES_BLOCK_SIZE];
161 size_t i, j;
162 uint8_t aes_key[AES_KEY_SIZE];
163 OAES_CTX* aes_ctx;
164
165 hash_process(&state.hs, data, length);
166 memcpy(text, state.init, INIT_SIZE_BYTE);
167 memcpy(aes_key, state.hs.b, AES_KEY_SIZE);
168 aes_ctx = oaes_alloc();
169
170 oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE);
171 for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
172 for (j = 0; j < INIT_SIZE_BLK; j++)
173 oaes_pseudo_encrypt_ecb(aes_ctx, &text[AES_BLOCK_SIZE * j]);
174
175 memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
176 }
177
178 for (i = 0; i < 16; i++) {
179 a[i] = state.k[ i] ^ state.k[32 + i];
180 b[i] = state.k[16 + i] ^ state.k[48 + i];
181 }
182
183 for (i = 0; i < ITER / 2; i++) {
184 /* Dependency chain: address -> read value ------+
185 * written value <-+ hard function (AES or MUL) <+
186 * next address <-+
187 */
188 /* Iteration 1 */
189 j = e2i(a, MEMORY / AES_BLOCK_SIZE);
190 copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
191 oaes_encryption_round(a, c);
192 xor_blocks(b, c);
193 swap_blocks(b, c);
194 copy_block(&long_state[j * AES_BLOCK_SIZE], c);
195 assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE));
196 swap_blocks(a, b);
197 /* Iteration 2 */
198 j = e2i(a, MEMORY / AES_BLOCK_SIZE);
199 copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
200 mul(a, c, d);
201 sum_half_blocks(b, d);
202 swap_blocks(b, c);
203 xor_blocks(b, c);
204 copy_block(&long_state[j * AES_BLOCK_SIZE], c);
205 assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE));
206 swap_blocks(a, b);
207 }
208
209 memcpy(text, state.init, INIT_SIZE_BYTE);
210 oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE);
211 for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
212 for (j = 0; j < INIT_SIZE_BLK; j++) {
213 xor_blocks(&text[j * AES_BLOCK_SIZE], &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]);
214 oaes_pseudo_encrypt_ecb(aes_ctx, &text[j * AES_BLOCK_SIZE]);
215 }
216 }
217 memcpy(state.init, text, INIT_SIZE_BYTE);
218 hash_permutation(&state.hs);
219 extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
220 oaes_free(&aes_ctx);
221 MEM_FREE(long_state);
222 }
223