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