121 lines
3.2 KiB
C
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;
|
|
}
|
|
|