diff --git a/src/pixiewps.c b/src/pixiewps.c index 6ff782b..d0a929f 100644 --- a/src/pixiewps.c +++ b/src/pixiewps.c @@ -51,7 +51,7 @@ #define GLIBC_MAX_GEN 4 #include "random/glibc_random.c" -#include "random/glibc_random_lazy.c" +#include "random/glibc_random_yura.c" static uint32_t ecos_rand_simplest(uint32_t *seed); static uint32_t ecos_rand_simple(uint32_t *seed); @@ -107,15 +107,13 @@ static struct job_control { static void crack_thread_rtl(struct crack_job *j) { - struct glibc_lazyprng glibc_lazyprng; uint32_t seed = j->start; uint32_t limit = job_control.end; uint32_t tmp[4]; while (!job_control.nonce_seed) { - glibc_lazyseed(&glibc_lazyprng, seed); - if (glibc_rand1(&glibc_lazyprng) == job_control.randr_enonce[0]) { - if (!memcmp(glibc_randfill(&glibc_lazyprng, tmp), job_control.randr_enonce, WPS_NONCE_LEN)) { + if (glibc_fast_seed(seed) == job_control.randr_enonce[0]) { + if (!memcmp(glibc_fast_nonce(seed, tmp), job_control.randr_enonce, WPS_NONCE_LEN)) { job_control.nonce_seed = seed; DEBUG_PRINT("Seed found (%10u)", seed); } diff --git a/src/random/glibc_random_yura.c b/src/random/glibc_random_yura.c new file mode 100644 index 0000000..fbe2f25 --- /dev/null +++ b/src/random/glibc_random_yura.c @@ -0,0 +1,60 @@ +/* + * Based on the code of user @1yura. + * + * See glibc_random.c for a better understanding of the code. + */ + +#include + +static const uint32_t glibc_seed_tbl[31 + 3] = { + 0x0128e83b, 0x00dafa31, 0x009f4828, 0x00f66443, 0x00bee24d, 0x00817005, 0x00cb918f, + 0x00a64845, 0x0069c3cf, 0x00a76dbd, 0x0090a848, 0x0057025f, 0x0089126c, 0x007d9a8f, + 0x0048252a, 0x006fb2d4, 0x006ccc15, 0x003c5744, 0x005a998f, 0x005df917, 0x0032ed77, + 0x00492688, 0x0050e901, 0x002b5f57, 0x003acd0b, 0x00456b7a, 0x0025413d, 0x002f11f4, + 0x003b564d, 0x00203f14, 0x002589fc, 0x003283f8, 0x001c17e4, 0x001dd823 +}; + +static inline uint32_t *glibc_fast_nonce(uint32_t seed, uint32_t *dest) +{ + uint32_t word0 = 0, word1 = 0, word2 = 0, word3 = 0; + + for (int j = 0; j < 31; j++) { + word0 += seed * glibc_seed_tbl[j + 3]; + word1 += seed * glibc_seed_tbl[j + 2]; + word2 += seed * glibc_seed_tbl[j + 1]; + word3 += seed * glibc_seed_tbl[j + 0]; + + /* This does: seed = (16807LL * seed) % 0x7fffffff + using the sum of digits method which works for mod N, base N+1 */ + const uint64_t p = 16807ULL * seed; + const uint64_t m = (p >> 31) + (p & 0x7fffffff); + + /* The result might still not fit in 31 bits, if not, repeat + (conditional seems to make it slightly faster) */ + seed = (m & 0xffffffff80000000) ? ((m >> 31) + (m & 0x7fffffff)) : m; + } + dest[0] = word0 >> 1; + dest[1] = word1 >> 1; + dest[2] = word2 >> 1; + dest[3] = word3 >> 1; + return dest; +} + +static inline uint32_t glibc_fast_seed(uint32_t seed) +{ + uint32_t word0 = 0; + + for (int j = 0; j < 31; j++) { + word0 += seed * glibc_seed_tbl[j + 3]; + + /* This does: seed = (16807LL * seed) % 0x7fffffff + using the sum of digits method which works for mod N, base N+1 */ + const uint64_t p = 16807ULL * seed; + const uint64_t m = (p >> 31) + (p & 0x7fffffff); + + /* The result might still not fit in 31 bits, if not, repeat + (conditional seems to make it slightly faster) */ + seed = (m & 0xffffffff80000000) ? ((m >> 31) + (m & 0x7fffffff)) : m; + } + return word0 >> 1; +}