cryptopals

Cryptopals Challenges
git clone https://git.pngu.org/cryptopals
Log | Files | Refs

commit d51c2413fea0bc38bcf09fef04101aa58a2b6d7a
parent 245c17d8ba7951a8feab3a43604a39169d2e1a69
Author: Jack Sangdahl <jack@pngu.org>
Date:   Thu, 23 Oct 2025 22:39:05 -0600

challenge 22: crack an mt19937 seed

Diffstat:
Asrc/22_crack_mt19937_seed.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+), 0 deletions(-)

diff --git a/src/22_crack_mt19937_seed.c b/src/22_crack_mt19937_seed.c @@ -0,0 +1,47 @@ +// Crack an MT19937 seed +#include "mt19937.h" +#include "random.h" +#include <stdio.h> +#include <time.h> +#include <unistd.h> + +/* + * make sure your mt19937 accepts an integer seed value. test it (verify that + * you're getting the same sequence of outputs given a seed). write a routine + * that performs the following operation: wait a random number of seconds + * between, 40 and 1000, seed the rng with the current unix timestamp, waits a + * random number of seconds again, and return the first 32 bit output of the + * rng. you get the idea. simulate the passage of time, although you're missing + * some of the fun of the exercise if you do that. from the 32 bit rng output, + * discover the seed + */ + +#define MIN_DELAY 40 +#define MAX_DELAY 1000 + +void delay(int min, int max) { + int wait = random_int_inclusive(min, max); + printf("Waiting %d seconds... (%d minutes)\n", wait, wait / 60); + sleep(wait); +} + +uint32_t output_seed(uint32_t seed) { + struct mt19937_state mt = mt19937_init(seed); + return mt19937_extract(&mt); +} + +int main(void) { + srand(time(NULL)); + delay(MIN_DELAY, MAX_DELAY); + int seed = (int)time(NULL); + uint32_t first = output_seed(seed); + printf("Seeded PRNG...\n"); + delay(MIN_DELAY, MAX_DELAY); + int end = (int)time(NULL); + uint32_t curr; + for (curr = end; output_seed(curr) != first; curr--) + if (!(curr % 10)) + printf("."); + printf("\nFound seed: %d\n", curr); + return 0; +}