Witam,
Mam dwa pytania dotyczące kodu, który zamieszczam pod pytaniami:
- W którym miejscu ustawić pozycję startową do tworzenia HASH TABLE od np. liczby 1048576 [w celu oszczędności pamięci]
- Jak bardzo skomplikowane/czasochłonne będzie przerobienie kodu w sposób taki, aby mógł działać na większych liczbach poprzez np. dzielenie na partie danych [partia 1 => check partii 1 => clean partii 1 => tworzenie partii 2 => check partii 2 => clean memory partii 2 itd.]
Poniżej wspomniany kod którego dotyczą pytania:
#include "libsecp256k1-config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "include/secp256k1.h"
#include "secp256k1.c"
#define GSTEP ((uint128_t)1<<30)
#define NUMPUBKEYS 5
unsigned char rawpubkeys[NUMPUBKEYS][33] = {
{ 0x03,0x72,0x6b,0x57,0x4f,0x19,0x3e,0x37,0x46,0x86,0xd8,0xe1,0x2b,0xc6,0xe4,0x14,0x2a,0xde,0xb0,0x67,0x70,0xe0,0xa2,0x85,0x6f,0x5e,0x4a,0xd8,0x9f,0x66,0x04,0x47,0x55 },
{ 0x03,0x7e,0x12,0x38,0xf7,0xb1,0xce,0x75,0x7d,0xf9,0x4f,0xaa,0x9a,0x2e,0xb2,0x61,0xbf,0x0a,0xeb,0x9f,0x84,0xdb,0xf8,0x12,0x12,0x10,0x4e,0x78,0x93,0x1c,0x2a,0x19,0xdc },
{ 0x03,0x29,0xc4,0x57,0x4a,0x4f,0xd8,0xc8,0x10,0xb7,0xe4,0x2a,0x4b,0x39,0x88,0x82,0xb3,0x81,0xbc,0xd8,0x5e,0x40,0xc6,0x88,0x37,0x12,0x91,0x2d,0x16,0x7c,0x83,0xe7,0x3a },
{ 0x03,0x5c,0x38,0xbd,0x9a,0xe4,0xb1,0x0e,0x8a,0x25,0x08,0x57,0x00,0x6f,0x3c,0xfd,0x98,0xab,0x15,0xa6,0x19,0x6d,0x9f,0x4d,0xfd,0x25,0xbc,0x7e,0xcc,0x77,0xd7,0x88,0xd5 },
{ 0x02,0x96,0x7a,0x59,0x05,0xd6,0xf3,0xb4,0x20,0x95,0x9a,0x02,0x78,0x9f,0x96,0xab,0x4c,0x32,0x23,0xa2,0xc4,0xd2,0x76,0x2f,0x81,0x7b,0x78,0x95,0xc5,0xbc,0x88,0xa0,0x45 },
};
typedef struct hashtable_entry {
uint128_t x;
uint128_t exponent;
} hashtable_entry;
#define HASH_SIZE (2*GSTEP)
hashtable_entry table[HASH_SIZE];
secp256k1_ge pubkeys[NUMPUBKEYS];
int main(int argc, char **argv) {
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
int next = 1;
for (int i = 1; i < NUMPUBKEYS; i++) {
if (!secp256k1_eckey_pubkey_parse(&pubkeys[i], rawpubkeys[i], 33)) {
printf("Unparsable pubkey %2d\n", i);
return -1;
}
}
printf("Build Hash\n");
secp256k1_gej pt;
secp256k1_gej_set_ge(&pt, &secp256k1_ge_const_g);
for (size_t i = 1; i < GSTEP; i++) {
secp256k1_fe x,zinv;
secp256k1_fe_storage xst;
secp256k1_fe_inv_var(&zinv, &pt.z);
secp256k1_fe_sqr(&zinv, &zinv);
secp256k1_fe_mul(&x, &pt.x, &zinv);
secp256k1_fe_to_storage(&xst, &x);
uint64_t entry = xst.n[0] & (HASH_SIZE-1);
while (table[entry].exponent != 0) {
entry = (entry + (xst.n[1] | 1)) & (HASH_SIZE - 1);
}
table[entry].exponent = i;
table[entry].x = xst.n[2];
secp256k1_gej_add_ge_var(&pt, &pt, &secp256k1_ge_const_g, NULL);
}
printf("Search Keys\n");
secp256k1_ge ptgstep;
secp256k1_gej_neg(&pt, &pt);
secp256k1_gej_double_var(&pt, &pt, NULL);
secp256k1_ge_set_gej(&ptgstep, &pt);
secp256k1_gej_set_infinity(&pt);
for (size_t i = 1; i < 2*GSTEP; i++) {
for (int j = next; j < NUMPUBKEYS; j++) {
secp256k1_gej diff;
secp256k1_fe x,zinv;
secp256k1_fe_storage xst;
secp256k1_gej_add_ge_var(&diff, &pt, &pubkeys[j], NULL);
secp256k1_fe_inv_var(&zinv, &diff.z);
secp256k1_fe_sqr(&zinv, &zinv);
secp256k1_fe_mul(&x, &diff.x, &zinv);
secp256k1_fe_to_storage(&xst, &x);
uint64_t entry = xst.n[0] & (HASH_SIZE-1);
while (table[entry].exponent != 0) {
if (table[entry].x == (uint64_t) xst.n[2]) {
uint128_t key = (uint128_t) i * (uint128_t) (2 * GSTEP);
uint128_t key1 = key - table[entry].exponent ;
uint128_t key2 = key + table[entry].exponent;
uint64_t key1lo = key1;
uint64_t key1hi = (key1 >> 64);
uint64_t key2lo = key2;
uint64_t key2hi = (key2 >> 64);
printf("Found private key %2d: %lx %lx or %lx %lx\n", j + 1, key1hi,key1lo,key2hi,key2lo);
next++;
if (next == NUMPUBKEYS)
return 0;
}
entry = (entry + (xst.n[1] | 1)) & (HASH_SIZE - 1);
}
if (j == next)
break;
}
secp256k1_gej_add_ge_var(&pt, &pt, &ptgstep, NULL);
}
return 0;
}