mirror of
https://github.com/wiire-a/pixiewps.git
synced 2025-07-28 08:14:39 +02:00
Improvement in glibc PRNG cracking
The code is based on a precomputed initial seed table, instead of re-seeding from scratch everytime the whole state. On my x86 test machine this new code seems to be ~60% faster. Some further testing and tuning may be needed. Credits to @1yura.
This commit is contained in:
parent
c14f1227af
commit
7738fda7d8
@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
#define GLIBC_MAX_GEN 4
|
#define GLIBC_MAX_GEN 4
|
||||||
#include "random/glibc_random.c"
|
#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_simplest(uint32_t *seed);
|
||||||
static uint32_t ecos_rand_simple(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)
|
static void crack_thread_rtl(struct crack_job *j)
|
||||||
{
|
{
|
||||||
struct glibc_lazyprng glibc_lazyprng;
|
|
||||||
uint32_t seed = j->start;
|
uint32_t seed = j->start;
|
||||||
uint32_t limit = job_control.end;
|
uint32_t limit = job_control.end;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
while (!job_control.nonce_seed) {
|
while (!job_control.nonce_seed) {
|
||||||
glibc_lazyseed(&glibc_lazyprng, seed);
|
if (glibc_fast_seed(seed) == job_control.randr_enonce[0]) {
|
||||||
if (glibc_rand1(&glibc_lazyprng) == job_control.randr_enonce[0]) {
|
if (!memcmp(glibc_fast_nonce(seed, tmp), job_control.randr_enonce, WPS_NONCE_LEN)) {
|
||||||
if (!memcmp(glibc_randfill(&glibc_lazyprng, tmp), job_control.randr_enonce, WPS_NONCE_LEN)) {
|
|
||||||
job_control.nonce_seed = seed;
|
job_control.nonce_seed = seed;
|
||||||
DEBUG_PRINT("Seed found (%10u)", seed);
|
DEBUG_PRINT("Seed found (%10u)", seed);
|
||||||
}
|
}
|
||||||
|
60
src/random/glibc_random_yura.c
Normal file
60
src/random/glibc_random_yura.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Based on the code of user @1yura.
|
||||||
|
*
|
||||||
|
* See glibc_random.c for a better understanding of the code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user