forked from floodyberry/scrypt-jane
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scrypt-jane-speed.c
126 lines (109 loc) · 3.31 KB
/
scrypt-jane-speed.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#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)
#include <sys/time.h>
struct timeval t2;
if (gettimeofday(&t2, NULL))
return 0;
uint64_t t = (uint64_t)t2.tv_sec * 1000000 + t2.tv_usec;
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;
uint64_t allticks = 0;
for (passes = 0; passes < 16; passes++) {
timeit(scrypt(password, sizeof(password), salt, sizeof(salt), s->Nfactor, s->rfactor, s->pfactor, digest, sizeof(digest)), minticks)
allticks += ticks;
}
printf("%s, %.0f min ticks, %.0f avg ticks\n", s->desc, (double)minticks, (double)allticks / passes);
}
#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;
}