Added another simpler glibc PRNG

With these changes I was able to get a 9% increase in speed on my
laptop.
This commit is contained in:
wiire-a 2017-11-16 14:38:45 +01:00
parent ceea7143cb
commit edd5d30b4c
5 changed files with 122 additions and 83 deletions

View File

@ -1,68 +0,0 @@
/*
* pixiewps: offline WPS brute-force utility that exploits low entropy PRNGs
*
* Copyright (c) 2015-2017, wiire <wi7ire@gmail.com>
* SPDX-License-Identifier: GPL-3.0+
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define GLIBC_PRNG_SIZE 344
#define GLIBC_FAST_MAX_GEN 3
#if GLIBC_MAX_GEN < GLIBC_FAST_MAX_GEN
#error "GLIBC_MAX_GEN must be >= GLIBC_FAST_MAX_GEN"
#endif
/*
* The +1 is used to keep the index inside the array after the increment,
* it doesn't really have a purpose besides that
*/
struct glibc_prng {
int index;
int state[GLIBC_PRNG_SIZE + GLIBC_MAX_GEN - GLIBC_FAST_MAX_GEN + 1];
};
/*
* If only 3 numbers are generated then there's no need to store new values
*/
unsigned int glibc_rand_fast(struct glibc_prng *prng)
{
const int *state = prng->state;
const int i = prng->index++;
return ((unsigned int)(state[i - 31] + state[i - 3])) >> 1;
}
/*
* There are no checks of bounds (GLIBC_MAX_GEN is the maximum number of times it can be called)
*/
unsigned int glibc_rand(struct glibc_prng *prng)
{
int *state = prng->state;
const int i = prng->index++;
state[i] = state[i - 31] + state[i - 3];
return (unsigned int)state[i] >> 1;
}
void glibc_seed(struct glibc_prng *prng, int seed)
{
int i;
int *state = prng->state;
prng->index = GLIBC_PRNG_SIZE;
state[0] = seed;
for (i = 1; i < 31; i++) {
state[i] = (16807LL * state[i - 1]) % 2147483647;
if (state[i] < 0)
state[i] += 2147483647;
}
for (i = 31; i < 34; i++) state[i] = state[i - 31];
for (i = 34; i < 344; i++) state[i] = state[i - 31] + state[i - 3];
}

View File

@ -42,7 +42,8 @@
#include "version.h"
#define GLIBC_MAX_GEN 4
#include "glibc_random.c"
#include "random/glibc_random.c"
#include "random/glibc_random_lazy.c"
uint32_t ecos_rand_simplest(uint32_t *seed);
uint32_t ecos_rand_simple(uint32_t *seed);
@ -92,23 +93,20 @@ static struct job_control {
} job_control;
static void *crack_thread(void *arg) {
struct glibc_prng glibc_prng;
struct glibc_lazyprng glibc_lazyprng;
struct crack_job *j = arg;
uint32_t seed = j->start;
uint32_t limit = job_control.end;
uint32_t tmp[4];
while (!job_control.nonce_seed) {
unsigned int i;
glibc_seed(&glibc_prng, seed);
for (i = 0; i < GLIBC_FAST_MAX_GEN; i++) {
const unsigned int res = glibc_rand_fast(&glibc_prng);
if (res != job_control.randr_enonce[i])
break;
}
if (i == GLIBC_FAST_MAX_GEN) {
job_control.nonce_seed = seed;
DEBUG_PRINT("Seed found %u", 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, 4)) {
job_control.nonce_seed = seed;
DEBUG_PRINT("Seed found %u", seed);
}
}
if (seed == 0) break;

58
src/random/glibc_random.c Normal file
View File

@ -0,0 +1,58 @@
/*
* Based on the code of Peter Selinger
* Reference: http://www.mathstat.dal.ca/~selinger/random/
*
* The original code was modified to achieve better speed
*/
#define GLIBC_PRNG_SIZE 344
#define GLIBC_FAST_MAX_GEN 3
#if GLIBC_MAX_GEN < GLIBC_FAST_MAX_GEN
#error "GLIBC_MAX_GEN must be >= GLIBC_FAST_MAX_GEN"
#endif
/*
* The +1 is used to keep the index inside the array after the increment,
* it doesn't really have a purpose besides that
*/
struct glibc_prng {
int index;
int state[GLIBC_PRNG_SIZE + GLIBC_MAX_GEN - GLIBC_FAST_MAX_GEN + 1];
};
/*
* If only 3 numbers are generated then there's no need to store new values
*/
static unsigned int glibc_rand_fast(struct glibc_prng *prng)
{
const int *state = prng->state;
const int i = prng->index++;
return ((unsigned int)(state[i - 31] + state[i - 3])) >> 1;
}
/*
* There are no checks of bounds (GLIBC_MAX_GEN is the maximum number of times it can be called)
*/
static unsigned int glibc_rand(struct glibc_prng *prng)
{
int *state = prng->state;
const int i = prng->index++;
state[i] = state[i - 31] + state[i - 3];
return (unsigned int)state[i] >> 1;
}
static void glibc_seed(struct glibc_prng *prng, int seed)
{
int i = 0;
int *state = prng->state;
prng->index = GLIBC_PRNG_SIZE;
state[i++] = seed;
for ( ; i < 31; i++) {
state[i] = (16807LL * state[i - 1]) % 2147483647;
if (state[i] < 0)
state[i] += 2147483647;
}
for (i = 31; i < 34; i++) state[i] = state[i - 31];
for (i = 34; i < 344; i++) state[i] = state[i - 31] + state[i - 3];
}

View File

@ -0,0 +1,51 @@
/*
* Based on the code of Peter Selinger
* Reference: http://www.mathstat.dal.ca/~selinger/random/
*
* The original code was modified to achieve better speed
*/
#include <stdint.h>
struct glibc_lazyprng {
int state[344];
};
/*
* Return 1st generated element only
*/
static unsigned int glibc_rand1(struct glibc_lazyprng *prng)
{
const int *state = prng->state;
return ((unsigned int)(state[344 - 31] + state[344 - 3])) >> 1;
}
/*
* Fill a 4 elements array (to use with memcmp)
*/
static int *glibc_randfill(struct glibc_lazyprng *prng, uint32_t *arr)
{
int *state = prng->state;
arr[0] = ((unsigned int)(state[344 - 31] + state[344 - 3])) >> 1;
arr[1] = ((unsigned int)(state[344 - 31 + 1] + state[344 - 3 + 1])) >> 1;
arr[2] = ((unsigned int)(state[344 - 31 + 2] + state[344 - 3 + 2])) >> 1;
arr[3] = ((unsigned int)(state[344 - 31 + 3] + arr[0])) >> 1;
return arr;
}
/*
* Lazy seeding (stay 2 shorter)
*/
static void glibc_lazyseed(struct glibc_lazyprng *prng, int seed)
{
int *state = prng->state;
int i = 0;
state[i++] = seed;
for ( ; i < 31; i++) {
state[i] = (16807LL * state[i - 1]) % 2147483647;
if (state[i] < 0)
state[i] += 2147483647;
}
for (i = 31; i < 34; i++) state[i] = state[i - 31];
for (i = 34; i < 344 - 3 + 1; i++) state[i] = state[i - 31] + state[i - 3];
}

View File

@ -52,7 +52,7 @@ struct m_random_data {
Note: The code takes advantage of the fact that both the front and
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
void m_random_r(struct m_random_data *buf, int32_t *result)
static void m_random_r(struct m_random_data *buf, int32_t *result)
{
int32_t *state = buf->state;
int32_t *fptr = buf->fptr;
@ -82,7 +82,7 @@ void m_random_r(struct m_random_data *buf, int32_t *result)
information a given number of times to get rid of any initial dependencies
introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
for default usage relies on values produced by this routine. */
void m_srandom_r(unsigned int seed, struct m_random_data *buf)
static void m_srandom_r(unsigned int seed, struct m_random_data *buf)
{
long int word;
int i, kc;
@ -128,7 +128,7 @@ void m_srandom_r(unsigned int seed, struct m_random_data *buf)
Note: The first thing we do is save the current state, if any, just like
setstate so that it doesn't matter when initstate is called.
Returns a pointer to the old state. */
void m_initstate_r(unsigned int seed, char *arg_state, struct m_random_data *buf)
static void m_initstate_r(unsigned int seed, char *arg_state, struct m_random_data *buf)
{
int32_t *state = &((int32_t *)arg_state)[1]; /* First location */