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
|
/* TODO: build system
* gcc -std=gnu99 -W -Wall -Werror -O3 main.c mpz.c -o pszip -lgmp -lcrypto */
#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mpz.h"
/* Hash is currently downgraded to SHA1 for now, as it is faster and there is
* not yet a reason for anything stronger. */
#define HASH_LENGTH SHA_DIGEST_LENGTH
static void hash_mpz(void *output, const mpz_t n, size_t size)
{
SHA1((void *)mpz_limbs_read(n), size, output);
}
int main(int argc, char **argv)
{
unsigned char original_hash[HASH_LENGTH];
unsigned char iteration_hash[HASH_LENGTH];
struct pszip_mpz_state mpzs;
mpz_t original;
if (argc < 2)
{
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
return 1;
}
/* Process original data */
size_t size = strlen(argv[1]);
pszip_mpz_init_data(original, argv[1], size);
mp_bitcnt_t popcnt = mpz_popcount(original);
hash_mpz(original_hash, original, size);
mpz_clear(original);
/* Display metadata */
printf("%s\n", argv[1]);
for (int i = 0; i < HASH_LENGTH; i++)
printf("%02x", original_hash[i]);
printf("\nsize = %zu\n", size);
printf("popcnt = %llu\n", (long long unsigned)popcnt);
/* Search for solution (1 thread) */
pszip_mpz_state_init(&mpzs, popcnt, size);
while (1)
{
hash_mpz(iteration_hash, mpzs.current, size);
if (memcmp(iteration_hash, original_hash, HASH_LENGTH) == 0)
break;
pszip_mpz_iterate_bithack01(&mpzs);
}
/* Results */
printf("\nFound!\n");
fwrite(mpz_limbs_read(mpzs.current), 1, size, stdout);
printf("\n");
pszip_mpz_state_clear(&mpzs);
return 0;
}
|