@@ -17,6 +17,7 @@ static void (*const extra_hashes[4])(const void *, size_t, char *) = {
1717
1818#define MEMORY (1 << 21) /* 2 MiB */
1919#define ITER (1 << 20)
20+ #define ITER_SLD (1 << 16)
2021#define AES_BLOCK_SIZE 16
2122#define AES_KEY_SIZE 32 /*16*/
2223#define INIT_SIZE_BLK 8
@@ -150,3 +151,75 @@ void cn_slow_hash(const void *data, size_t length, char *hash) {
150151 oaes_free (& aes_ctx );
151152 free (long_state );
152153}
154+
155+ void cn_slow_hash_sld (const void * data , size_t length , char * hash ) {
156+ uint8_t * long_state = malloc (MEMORY );
157+ union cn_slow_hash_state state ;
158+ uint8_t text [INIT_SIZE_BYTE ];
159+ uint8_t a [AES_BLOCK_SIZE ];
160+ uint8_t b [AES_BLOCK_SIZE ];
161+ uint8_t c [AES_BLOCK_SIZE ];
162+ uint8_t d [AES_BLOCK_SIZE ];
163+ size_t i , j ;
164+ uint8_t aes_key [AES_KEY_SIZE ];
165+ OAES_CTX * aes_ctx ;
166+
167+ hash_process (& state .hs , data , length );
168+ memcpy (text , state .init , INIT_SIZE_BYTE );
169+ memcpy (aes_key , state .hs .b , AES_KEY_SIZE );
170+ aes_ctx = oaes_alloc ();
171+
172+ oaes_key_import_data (aes_ctx , aes_key , AES_KEY_SIZE );
173+ for (i = 0 ; i < MEMORY / INIT_SIZE_BYTE ; i ++ ) {
174+ for (j = 0 ; j < INIT_SIZE_BLK ; j ++ ) {
175+ oaes_pseudo_encrypt_ecb (aes_ctx , & text [AES_BLOCK_SIZE * j ]);
176+ }
177+ memcpy (& long_state [i * INIT_SIZE_BYTE ], text , INIT_SIZE_BYTE );
178+ }
179+
180+ for (i = 0 ; i < 16 ; i ++ ) {
181+ a [i ] = state .k [ i ] ^ state .k [32 + i ];
182+ b [i ] = state .k [16 + i ] ^ state .k [48 + i ];
183+ }
184+
185+ for (i = 0 ; i < ITER_SLD / 2 ; i ++ ) {
186+ /* Dependency chain: address -> read value ------+
187+ * written value <-+ hard function (AES or MUL) <+
188+ * next address <-+
189+ */
190+ /* Iteration 1 */
191+ j = e2i (a , MEMORY / AES_BLOCK_SIZE );
192+ copy_block (c , & long_state [j * AES_BLOCK_SIZE ]);
193+ oaes_encryption_round (a , c );
194+ xor_blocks (b , c );
195+ swap_blocks (b , c );
196+ copy_block (& long_state [j * AES_BLOCK_SIZE ], c );
197+ assert (j == e2i (a , MEMORY / AES_BLOCK_SIZE ));
198+ swap_blocks (a , b );
199+ /* Iteration 2 */
200+ j = e2i (a , MEMORY / AES_BLOCK_SIZE );
201+ copy_block (c , & long_state [j * AES_BLOCK_SIZE ]);
202+ mul (a , c , d );
203+ sum_half_blocks (b , d );
204+ swap_blocks (b , c );
205+ xor_blocks (b , c );
206+ copy_block (& long_state [j * AES_BLOCK_SIZE ], c );
207+ assert (j == e2i (a , MEMORY / AES_BLOCK_SIZE ));
208+ swap_blocks (a , b );
209+ }
210+
211+ memcpy (text , state .init , INIT_SIZE_BYTE );
212+ oaes_key_import_data (aes_ctx , & state .hs .b [32 ], AES_KEY_SIZE );
213+ for (i = 0 ; i < MEMORY / INIT_SIZE_BYTE ; i ++ ) {
214+ for (j = 0 ; j < INIT_SIZE_BLK ; j ++ ) {
215+ xor_blocks (& text [j * AES_BLOCK_SIZE ], & long_state [i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE ]);
216+ oaes_pseudo_encrypt_ecb (aes_ctx , & text [j * AES_BLOCK_SIZE ]);
217+ }
218+ }
219+ memcpy (state .init , text , INIT_SIZE_BYTE );
220+ hash_permutation (& state .hs );
221+ /*memcpy(hash, &state, 32);*/
222+ extra_hashes [state .hs .b [0 ] & 3 ](& state , 200 , hash );
223+ oaes_free (& aes_ctx );
224+ free (long_state );
225+ }
0 commit comments