Well PHP also uses OpenSSL in background and it seems to force the iterations into 'int' too (
source code) - but I seem to be running 64-bit version:
> php -r 'echo PHP_INT_MAX;'
> 9223372036854775807
edit: for the lulz I am now running with 2147483647 iterations
might be not finished before I go to sleep though.
I found a native PHP one:
https://defuse.ca/php-pbkdf2.htmwhich should avoid the 32 bit problems. It passes the test-vector, and I'm testing it on the full data. Also running a native javascript one, and rebuilding openssl with using a 64 bit integer for the iteration count
I got the same as NLNico using a modified openssl version. I ran into the 32 bit integer limit too, so did this to bypass it - it saved me having to rebuild openssl - I just copied and modified the function with the 32 bit limit:
#include
#include
#include
#include
int pbkdf2(const char *pass, const unsigned char *salt, long iter, const EVP_MD *digest, unsigned char *out)
{
unsigned char digtmp[32], itmp[4];
int k, mdlen, saltlen = strlen(salt);
unsigned long j;
HMAC_CTX hctx_tpl, hctx;
mdlen = EVP_MD_size(digest);
HMAC_CTX_init(&hctx_tpl);
HMAC_Init_ex(&hctx_tpl, pass, strlen(pass), digest, NULL);
itmp[0] = itmp[1] = itmp[2] = 0; itmp[3] = 1;
HMAC_CTX_copy(&hctx, &hctx_tpl); HMAC_Update(&hctx, salt, saltlen); HMAC_Update(&hctx, itmp, 4); HMAC_Final(&hctx, digtmp, NULL); HMAC_CTX_cleanup(&hctx);
memcpy(out, digtmp, mdlen);
for (j = 1; j < iter; j++) {
HMAC_CTX_copy(&hctx, &hctx_tpl); HMAC_Update(&hctx, digtmp, mdlen); HMAC_Final(&hctx, digtmp, NULL); HMAC_CTX_cleanup(&hctx);
for (k = 0; k < mdlen; k++) out[k] ^= digtmp[k];
if (j % 10000000 == 9999999) {
int i;
printf("%lu ", (j+1)/1000000);
for (i=0;i<32;i++) printf("%02x", out[i]);
printf("\n");
}
}
HMAC_CTX_cleanup(&hctx_tpl);
return 1;
}
void main()
{
size_t i;
unsigned char out[32];
const char pwd[] = "000000000000000009b7fb236187f120a0c86eb8785f099a8d197dd34b9d2553";
pbkdf2(pwd, "pevpot", 5000000000, EVP_sha256(), out);
printf("out: "); for(i=0;i<32;i++) { printf("%02x", out[i]); } printf("\n");
}
It shows the output after every 10 million iterations, to show that it's really doing all the work:
$ gcc -O3 pbkdf2.c -lssl -lcrypto
$ ./a.out
pass: 000000000000000009b7fb236187f120a0c86eb8785f099a8d197dd34b9d2553
ITERATION: 5000000000
salt: 706576706f74
10 4e54363ee4f5a8f0a13f36fcbe46568e496c787ac24ab466e18b80f959c4e426
20 1c08cfe17c6b036075fb45ea1d5b95073ebdfdd4a329cd1a30030e34f26cb8b1
30 110a65fb8928595ad797371bf1f77db371d62af560b6431704b7e91157a89065
[...]
4980 522f0ace7099f90c9a358014500f702fb10ab7f3a0ebeb3a7c221be91309a0d8
4990 38ca9ef690e27bcef846ef9852161f8f33223499fc2c57c1f0116995cb09744c
5000 6e466cdd13cc80b1137addf46362bbe3714fc9bf7faef9aba930554d3e080ba5
out: 6e466cdd13cc80b1137addf46362bbe3714fc9bf7faef9aba930554d3e080ba5
$
That last line is the same as NLNico's PHP output, so I'm reasonably confident in it.
Then:
>>> print 0x6e466cdd13cc80b1137addf46362bbe3714fc9bf7faef9aba930554d3e080ba5 % 2370006599
2341821270
Meaning the winner only bet 0.15 BTC!
b6abba202c99971e59021cef44a03904ec847f3344067bea85f8fd12d01678ca 0.00097120 : 2336305993 - 2336403112
b83f1fa87c86f9f1ccfe4050f07d89cd42c9e6670f4ac2a50fb353b626e2cac8 0.14997120 : 2336403113 - 2351400232 <-- this guy
b96d2df7cced243d4c729e26698f48e3b6f129120767812ff84e493f5efe8e6b 0.00997120 : 2351400233 - 2352397352
I also could be wrong, and would like to see NLNico's working, since this is a relatively surprising result.