Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/scryptjane/scrypt-jane-pbkdf2.h
1201 views
1
typedef struct scrypt_hmac_state_t {
2
scrypt_hash_state inner, outer;
3
} scrypt_hmac_state;
4
5
6
static void
7
scrypt_hash(scrypt_hash_digest hash, const uint8_t *m, size_t mlen) {
8
scrypt_hash_state st;
9
scrypt_hash_init(&st);
10
scrypt_hash_update(&st, m, mlen);
11
scrypt_hash_finish(&st, hash);
12
}
13
14
/* hmac */
15
static void
16
scrypt_hmac_init(scrypt_hmac_state *st, const uint8_t *key, size_t keylen) {
17
uint8_t pad[SCRYPT_HASH_BLOCK_SIZE] = {0};
18
size_t i;
19
20
scrypt_hash_init(&st->inner);
21
scrypt_hash_init(&st->outer);
22
23
if (keylen <= SCRYPT_HASH_BLOCK_SIZE) {
24
/* use the key directly if it's <= blocksize bytes */
25
memcpy(pad, key, keylen);
26
} else {
27
/* if it's > blocksize bytes, hash it */
28
scrypt_hash(pad, key, keylen);
29
}
30
31
/* inner = (key ^ 0x36) */
32
/* h(inner || ...) */
33
for (i = 0; i < SCRYPT_HASH_BLOCK_SIZE; i++)
34
pad[i] ^= 0x36;
35
scrypt_hash_update(&st->inner, pad, SCRYPT_HASH_BLOCK_SIZE);
36
37
/* outer = (key ^ 0x5c) */
38
/* h(outer || ...) */
39
for (i = 0; i < SCRYPT_HASH_BLOCK_SIZE; i++)
40
pad[i] ^= (0x5c ^ 0x36);
41
scrypt_hash_update(&st->outer, pad, SCRYPT_HASH_BLOCK_SIZE);
42
43
#ifdef SCRYPT_PREVENT_STATE_LEAK
44
scrypt_ensure_zero(pad, sizeof(pad));
45
#endif
46
}
47
48
static void
49
scrypt_hmac_update(scrypt_hmac_state *st, const uint8_t *m, size_t mlen) {
50
/* h(inner || m...) */
51
scrypt_hash_update(&st->inner, m, mlen);
52
}
53
54
static void
55
scrypt_hmac_finish(scrypt_hmac_state *st, scrypt_hash_digest mac) {
56
/* h(inner || m) */
57
scrypt_hash_digest innerhash;
58
scrypt_hash_finish(&st->inner, innerhash);
59
60
/* h(outer || h(inner || m)) */
61
scrypt_hash_update(&st->outer, innerhash, sizeof(innerhash));
62
scrypt_hash_finish(&st->outer, mac);
63
64
#ifdef SCRYPT_PREVENT_STATE_LEAK
65
scrypt_ensure_zero(st, sizeof(*st));
66
#endif
67
}
68
69
static void
70
scrypt_pbkdf2(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint64_t N, uint8_t *out, size_t bytes) {
71
scrypt_hmac_state hmac_pw, hmac_pw_salt, work;
72
scrypt_hash_digest ti, u;
73
uint8_t be[4];
74
uint32_t i, j, blocks;
75
uint64_t c;
76
77
/* bytes must be <= (0xffffffff - (SCRYPT_HASH_DIGEST_SIZE - 1)), which they will always be under scrypt */
78
79
/* hmac(password, ...) */
80
scrypt_hmac_init(&hmac_pw, password, password_len);
81
82
/* hmac(password, salt...) */
83
hmac_pw_salt = hmac_pw;
84
scrypt_hmac_update(&hmac_pw_salt, salt, salt_len);
85
86
blocks = ((uint32_t)bytes + (SCRYPT_HASH_DIGEST_SIZE - 1)) / SCRYPT_HASH_DIGEST_SIZE;
87
for (i = 1; i <= blocks; i++) {
88
/* U1 = hmac(password, salt || be(i)) */
89
U32TO8_BE(be, i);
90
work = hmac_pw_salt;
91
scrypt_hmac_update(&work, be, 4);
92
scrypt_hmac_finish(&work, ti);
93
memcpy(u, ti, sizeof(u));
94
95
/* T[i] = U1 ^ U2 ^ U3... */
96
for (c = 0; c < N - 1; c++) {
97
/* UX = hmac(password, U{X-1}) */
98
work = hmac_pw;
99
scrypt_hmac_update(&work, u, SCRYPT_HASH_DIGEST_SIZE);
100
scrypt_hmac_finish(&work, u);
101
102
/* T[i] ^= UX */
103
for (j = 0; j < sizeof(u); j++)
104
ti[j] ^= u[j];
105
}
106
107
memcpy(out, ti, (bytes > SCRYPT_HASH_DIGEST_SIZE) ? SCRYPT_HASH_DIGEST_SIZE : bytes);
108
out += SCRYPT_HASH_DIGEST_SIZE;
109
bytes -= SCRYPT_HASH_DIGEST_SIZE;
110
}
111
112
#ifdef SCRYPT_PREVENT_STATE_LEAK
113
scrypt_ensure_zero(ti, sizeof(ti));
114
scrypt_ensure_zero(u, sizeof(u));
115
scrypt_ensure_zero(&hmac_pw, sizeof(hmac_pw));
116
scrypt_ensure_zero(&hmac_pw_salt, sizeof(hmac_pw_salt));
117
#endif
118
}
119
120
/*
121
* Special version where N = 1
122
* - mikaelh
123
*/
124
static void
125
scrypt_pbkdf2_1(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint8_t *out, size_t bytes) {
126
scrypt_hmac_state hmac_pw, hmac_pw_salt, work;
127
scrypt_hash_digest ti, u;
128
uint8_t be[4];
129
uint32_t i, /*j,*/ blocks;
130
//uint64_t c;
131
132
/* bytes must be <= (0xffffffff - (SCRYPT_HASH_DIGEST_SIZE - 1)), which they will always be under scrypt */
133
134
/* hmac(password, ...) */
135
scrypt_hmac_init(&hmac_pw, password, password_len);
136
137
/* hmac(password, salt...) */
138
hmac_pw_salt = hmac_pw;
139
scrypt_hmac_update(&hmac_pw_salt, salt, salt_len);
140
141
blocks = ((uint32_t)bytes + (SCRYPT_HASH_DIGEST_SIZE - 1)) / SCRYPT_HASH_DIGEST_SIZE;
142
for (i = 1; i <= blocks; i++) {
143
/* U1 = hmac(password, salt || be(i)) */
144
U32TO8_BE(be, i);
145
work = hmac_pw_salt;
146
scrypt_hmac_update(&work, be, 4);
147
scrypt_hmac_finish(&work, ti);
148
memcpy(u, ti, sizeof(u));
149
150
memcpy(out, ti, (bytes > SCRYPT_HASH_DIGEST_SIZE) ? SCRYPT_HASH_DIGEST_SIZE : bytes);
151
out += SCRYPT_HASH_DIGEST_SIZE;
152
bytes -= SCRYPT_HASH_DIGEST_SIZE;
153
}
154
155
#ifdef SCRYPT_PREVENT_STATE_LEAK
156
scrypt_ensure_zero(ti, sizeof(ti));
157
scrypt_ensure_zero(u, sizeof(u));
158
scrypt_ensure_zero(&hmac_pw, sizeof(hmac_pw));
159
scrypt_ensure_zero(&hmac_pw_salt, sizeof(hmac_pw_salt));
160
#endif
161
}
162
163