btcollider/bf/scrypt-jane/scrypt-jane-speed.c
2018-04-04 15:18:34 +02:00

121 lines
3.2 KiB
C

#define SCRYPT_TEST_SPEED
#include "scrypt-jane.c"
/* ticks - not tested on anything other than x86 */
static uint64_t
get_ticks(void) {
#if defined(CPU_X86) || defined(CPU_X86_64)
#if defined(COMPILER_INTEL)
return _rdtsc();
#elif defined(COMPILER_MSVC)
return __rdtsc();
#elif defined(COMPILER_GCC)
uint32_t lo, hi;
__asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)lo | ((uint64_t)hi << 32));
#else
need rdtsc for this compiler
#endif
#elif defined(OS_SOLARIS)
return (uint64_t)gethrtime();
#elif defined(CPU_SPARC) && !defined(OS_OPENBSD)
uint64_t t;
__asm__ __volatile__("rd %%tick, %0" : "=r" (t));
return t;
#elif defined(CPU_PPC)
uint32_t lo = 0, hi = 0;
__asm__ __volatile__("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo));
return ((uint64_t)lo | ((uint64_t)hi << 32));
#elif defined(CPU_IA64)
uint64_t t;
__asm__ __volatile__("mov %0=ar.itc" : "=r" (t));
return t;
#elif defined(OS_NIX)
timeval t2;
gettimeofday(&t2, NULL);
t = ((uint64_t)t2.tv_usec << 32) | (uint64_t)t2.tv_sec;
return t;
#else
need ticks for this platform
#endif
}
#define timeit(x,minvar) { \
ticks = get_ticks(); \
x; \
ticks = get_ticks() - ticks; \
if (ticks < minvar) \
minvar = ticks; \
}
#define maxticks 0xffffffffffffffffull
typedef struct scrypt_speed_settings_t {
const char *desc;
uint8_t Nfactor, rfactor, pfactor;
} scrypt_speed_settings;
/* scrypt_r_32kb is set to a 32kb chunk, so (1 << (scrypt_r_32kb - 5)) = 1kb chunk */
static const scrypt_speed_settings settings[] = {
{"scrypt high volume ( ~4mb)", 11, scrypt_r_32kb - 5, 0},
{"scrypt interactive (~16mb)", 13, scrypt_r_32kb - 5, 0},
{"scrypt non-interactive (~ 1gb)", 19, scrypt_r_32kb - 5, 0},
{0}
};
int main(void) {
const scrypt_speed_settings *s;
uint8_t password[64], salt[24], digest[64];
uint64_t minticks, ticks;
size_t i, passes;
size_t cpuflags, topbit;
for (i = 0; i < sizeof(password); i++)
password[i] = (uint8_t)i;
for (i = 0; i < sizeof(salt); i++)
salt[i] = 255 - (uint8_t)i;
/* warm up a little */
scrypt(password, sizeof(password), salt, sizeof(salt), 15, 3, 4, digest, sizeof(digest));
cpuflags = available_implementations();
topbit = 0;
for (i = cpuflags; i != 0; i >>= 1)
topbit++;
topbit = ((size_t)1 << topbit);
while (1) {
#if defined(SCRYPT_CHOOSE_COMPILETIME)
printf("speed test for scrypt[%s,%s]\n", SCRYPT_HASH, SCRYPT_MIX);
#else
printf("speed test for scrypt[%s,%s,%s]\n", SCRYPT_HASH, SCRYPT_MIX, get_top_cpuflag_desc(cpuflags));
#endif
cpu_detect_mask = cpuflags;
for (i = 0; settings[i].desc; i++) {
s = &settings[i];
minticks = maxticks;
for (passes = 0; passes < 16; passes++)
timeit(scrypt(password, sizeof(password), salt, sizeof(salt), s->Nfactor, s->rfactor, s->pfactor, digest, sizeof(digest)), minticks)
printf("%s, %.0f ticks\n", s->desc, (double)minticks);
}
#if defined(SCRYPT_CHOOSE_COMPILETIME)
break;
#else
while (topbit && ((cpuflags & topbit) == 0))
topbit >>= 1;
cpuflags &= ~topbit;
/* (cpuflags == 0) is the basic/portable version, don't bother timing it */
if (!cpuflags)
break;
#endif
}
printf("\n\n");
return 0;
}