diff --git a/dtlp.c b/dtlp.c index 616235d..6461e89 100644 --- a/dtlp.c +++ b/dtlp.c @@ -27,7 +27,7 @@ main (int argc, char *argv[]) if (!strcmp(argv[i], "-h")) usage(); else if (!strcmp(argv[i], "-v")) { - puts("simple time lock puzzle decrypter v0.2"); + puts("simple time lock puzzle decrypter v0.3"); exit(EX_OK); } else if (!strcmp(argv[i], "-f")) { fp = fopen(argv[++i], "r"); @@ -44,15 +44,15 @@ main (int argc, char *argv[]) mpz_init(n); mpz_init(key); - /* read crypted key from stdin or file */ - mpz_inp_str(Ck, fp, 16); - mpz_inp_str(a, fp, 16); - mpz_inp_str(t, fp, 16); - mpz_inp_str(n, fp, 16); + /* read encrypted key from stdin or file */ + mpz_inp_str(Ck, fp, BASE16); + mpz_inp_str(a, fp, BASE16); + mpz_inp_str(t, fp, BASE16); + mpz_inp_str(n, fp, BASE16); if (fp) fclose(fp); - /* resolv time lock puzzle */ + /* resolve time lock puzzle */ while (mpz_cmp_ui(t, 0UL)) { mpz_powm_ui(a, a, 2UL, n); mpz_sub_ui(t, t, 1UL); diff --git a/etlp.1 b/etlp.1 index 5bc9100..5191c93 100644 --- a/etlp.1 +++ b/etlp.1 @@ -8,16 +8,18 @@ etlp \- encrypt time lock puzzle .IR test_time ] .RB [ \-f .IR key_file ] +.RB [ \-b +.IR bits ] .IR time_encrypted .SH DESCRIPTION .B etlp is a tool from the time lock puzzle cryptosystem suite .B stlp -(simple time lock puzzle) that encrypts a hexadecimal key (read from stdin by default) and prints the time lock puzzle to stdout so, when decrypted with +(simple time lock puzzle) that encrypts a hexadecimal key (read from stdin by default) and prints the time lock puzzle to stdout so decryption by .IR dtlp(1) -it will take +will take approximately .IR time_encrypted -seconds in host machine. +seconds on the host machine. .SH OPTIONS .TP .B \-h @@ -27,19 +29,23 @@ prints usage format to stdout as help. prints version information to stdout, then exits. .TP .B \-t " test_time" -time in seconds to invest in performance test. +time in seconds to invest in the performance test. .IP -This encryption requires to do a performance test on the machine with the random values generated. By default the test time will be 1 second. But this can be increased with an arbitrary +To estimate the time it will take this machine to decrypt, a performance test is run prior to encryption. By default the test time will be 1 second, but this can be changed to .IR test_time -seconds. It is recommended to increase the -.IR test_time -value for enough time to include the average workload in the performance test so the decryption time will be more close to the desired +seconds. To get a better estimate, which is mostly relevant for large values of .IR time_encrypted +it is recommended to increase +.IR test_time +to get a more accurate result. . .TP .B \-f " key_file" reads the key to encrypt from a file instead of stdin. .TP +.B \-b " bits" +length of the RSA modulus in bits. Must be a multiple of 2. +.TP .B "time_encrypted" sets the time lock puzzle challenge so when decrypted it will require those seconds to obtain the key back. .SH EXAMPLES diff --git a/etlp.c b/etlp.c index 971b168..ab3f0af 100644 --- a/etlp.c +++ b/etlp.c @@ -7,22 +7,22 @@ #include #define DEF_TESTIME 1 /* seconds */ -#define SQUARES_PER_CICLE 1000UL /* squares to do each cicle */ -#define PRIME_LEN 512 /* prime bit length */ +#define SQUARES_PER_CYCLE 1000UL /* squares to do each cycle */ #define BASE16 16 #define BASE10 10 static FILE *key_file; static unsigned long int time_enc, test_time = DEF_TESTIME; +static unsigned long int bit_length = 1024; /* modulus length */ static unsigned long int S; static gmp_randstate_t random_gen; -static mpz_t n, fi_n; +static mpz_t n, phi_n; static mpz_t Ck, b, a, e, t; static void usage(void) { - fputs("usage: etlp [-h] [-v] [-t test_time] [-f key_file] time_encrypted\n", stderr); + fputs("usage: etlp [-h] [-v] [-t test_time] [-f key_file] [-b bits] time_encrypted\n", stderr); exit(EX_USAGE); } @@ -31,7 +31,7 @@ setup(void) { /* Initialize mpz_t global variables */ mpz_init(n); - mpz_init(fi_n); + mpz_init(phi_n); mpz_init(Ck); mpz_init(a); mpz_init(b); @@ -50,20 +50,20 @@ setup(void) gmp_randseed_ui(random_gen, random_seed); } -/* Obtain the modulus n and fi(n) by creating two big random primes values - * (p, q) and multiply them. +/* Obtain the modulus n and phi(n) by creating two large random primes + * (p, q) and multiplying them. * * n = p * q - * fi(n) = (p - 1) * (q - 1) */ + * phi(n) = (p - 1) * (q - 1) */ static void -gen_modulos(void) +gen_modulus(void) { mpz_t p, q; mpz_init(p); mpz_init(q); - mpz_urandomb(p, random_gen, PRIME_LEN); - mpz_urandomb(q, random_gen, PRIME_LEN); + mpz_urandomb(p, random_gen, bit_length/2); + mpz_urandomb(q, random_gen, bit_length/2); mpz_nextprime(p, p); mpz_nextprime(q, q); @@ -73,7 +73,7 @@ gen_modulos(void) mpz_sub_ui(p, p, 1UL); mpz_sub_ui(q, q, 1UL); - mpz_mul(fi_n, p, q); + mpz_mul(phi_n, p, q); mpz_clear(p); mpz_clear(q); @@ -83,7 +83,7 @@ gen_modulos(void) static void gen_base(void) { - mpz_urandomb(a, random_gen, PRIME_LEN*2); + mpz_urandomb(a, random_gen, bit_length); mpz_sub_ui(n, n, 2UL); mpz_mod(a, a, n); @@ -95,7 +95,7 @@ gen_base(void) static void test_perf(void) { - unsigned long cicles = 0; + unsigned long cycles = 0; clock_t t0, ticks, t_test; mpz_set(b, a); @@ -103,26 +103,26 @@ test_perf(void) t0 = clock(); t_test = t0 + ticks; do { - mpz_set_ui(t, SQUARES_PER_CICLE); + mpz_set_ui(t, SQUARES_PER_CYCLE); while(mpz_cmp_ui(t, 0) > 0) { mpz_powm_ui(b, b, 2UL, n); mpz_sub_ui(t, t, 1UL); } - cicles++; + cycles++; } while(clock() < t_test); - S = (unsigned long)((SQUARES_PER_CICLE * cicles)/test_time); + S = (unsigned long)((SQUARES_PER_CYCLE * cycles)/test_time); } /* Encrypt efficiently by solving: Ck = k + b * b = a ^ e mod n - * e = 2 ^ t mod fi_n */ + * e = 2 ^ t mod phi_n */ static void encrypt(void) { - unsigned int key; - mpz_t T, two; + mpz_t T, two, key; mpz_init(T); mpz_init(two); + mpz_init(key); /* calculate challenge to reach desired time */ mpz_set_ui(T, time_enc); @@ -130,17 +130,22 @@ encrypt(void) /* calculate b */ mpz_set_ui(two, 2UL); - mpz_powm(e, two, t, fi_n); + mpz_powm(e, two, t, phi_n); mpz_powm(b, a, e, n); /* read key from stdin */ - if (fscanf(key_file, "%x", &key) == EOF) { + if (mpz_inp_str(key, key_file, BASE16) == 0) { fputs("Error reading key from stdin", stderr); exit(EX_IOERR); } + if (mpz_cmp(key, n) >= 0) { + fputs("Key is too large for modulus length", stderr); + exit(EX_USAGE); + } + /* encrypt key with b */ - mpz_add_ui(Ck, b, key); + mpz_add(Ck, b, key); mpz_clear(T); mpz_clear(two); @@ -152,7 +157,7 @@ unsetup(void) if(key_file != stdin) fclose(key_file); mpz_clear(n); - mpz_clear(fi_n); + mpz_clear(phi_n); mpz_clear(Ck); mpz_clear(t); mpz_clear(a); @@ -168,27 +173,38 @@ main (int argc, char *argv[]) int i; key_file = stdin; + time_enc = 0; /* process input */ for (i = 1; i < argc; i++) if (!strcmp(argv[i], "-h")) usage(); else if (!strcmp(argv[i], "-v")) { - puts("simple time lock puzzle encrypter v0.2"); + puts("simple time lock puzzle encrypter v0.3"); exit(EX_OK); } else if (!strcmp(argv[i], "-t")) test_time = strtoul(argv[++i], NULL, BASE10); - else if (!strcmp(argv[i], "-f")) { + else if (!strcmp(argv[i], "-b")) { + bit_length = strtoul(argv[++i], NULL, BASE10); + if (bit_length % 2) { + fputs("Bit length should be a multiple of 2", stderr); + exit(EX_USAGE); + } + } else if (!strcmp(argv[i], "-f")) { key_file = fopen(argv[++i], "r"); if (!key_file) { fprintf(stderr, "Error opening %s\n", argv[i]); exit(EX_NOINPUT); } - } - time_enc = strtoul(argv[argc-1], NULL, BASE10); + } else if (time_enc == 0) + time_enc = strtoul(argv[i], NULL, BASE10); + else + usage(); + + if (time_enc == 0) usage(); setup(); - gen_modulos(); + gen_modulus(); gen_base(); test_perf();