624d8b1cc96b40c91596710bd954b88b1c0519fe
[novacoin.git] / src / scrypt.cpp
1 #include <stdlib.h>
2 #include <stdint.h>
3
4 #include "scrypt.h"
5 #include "pbkdf2.h"
6
7 #include "util.h"
8 #include "net.h"
9
10 #define SCRYPT_BUFFER_SIZE (131072 + 63)
11
12 extern "C" void scrypt_core(unsigned int *X, unsigned int *V);
13
14 /* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output
15    scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes
16    r = 1, p = 1, N = 1024
17  */
18
19 uint256 scrypt_nosalt(const void* input, size_t inputlen, void *scratchpad)
20 {
21     unsigned int *V;
22     unsigned int X[32];
23     uint256 result = 0;
24     V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
25
26     PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, inputlen, 1, (uint8_t *)X, 128);
27     scrypt_core(X, V);
28     PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32);
29
30     return result;
31 }
32
33 uint256 scrypt(const void* data, size_t datalen, const void* salt, size_t saltlen, void *scratchpad)
34 {
35     unsigned int *V;
36     unsigned int X[32];
37     uint256 result = 0;
38     V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
39
40     PBKDF2_SHA256((const uint8_t*)data, datalen, (const uint8_t*)salt, saltlen, 1, (uint8_t *)X, 128);
41     scrypt_core(X, V);
42     PBKDF2_SHA256((const uint8_t*)data, datalen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32);
43
44     return result;
45 }
46
47 uint256 scrypt_hash(const void* input, size_t inputlen)
48 {
49     unsigned char scratchpad[SCRYPT_BUFFER_SIZE];
50     return scrypt_nosalt(input, inputlen, scratchpad);
51 }
52
53 uint256 scrypt_salted_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen)
54 {
55     unsigned char scratchpad[SCRYPT_BUFFER_SIZE];
56     return scrypt(input, inputlen, salt, saltlen, scratchpad);
57 }
58
59 uint256 scrypt_salted_multiround_hash(const void* input, size_t inputlen, const void* salt, size_t saltlen, const unsigned int nRounds)
60 {
61     uint256 resultHash = scrypt_salted_hash(input, inputlen, salt, saltlen);
62     uint256 transitionalHash = resultHash;
63
64     for(unsigned int i = 1; i < nRounds; i++)
65     {
66         resultHash = scrypt_salted_hash(input, inputlen, (const void*)&transitionalHash, 32);
67         transitionalHash = resultHash;
68     }
69
70     return resultHash;
71 }
72
73 uint256 scrypt_blockhash(const void* input)
74 {
75     unsigned char scratchpad[SCRYPT_BUFFER_SIZE];
76     return scrypt_nosalt(input, 80, scratchpad);
77 }
78