Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions dtlp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
Expand Down
22 changes: 14 additions & 8 deletions etlp.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
74 changes: 45 additions & 29 deletions etlp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
#include <gmp.h>

#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);
}

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -95,52 +95,57 @@ 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);
ticks = CLOCKS_PER_SEC * test_time;
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);
mpz_mul_ui(t, T, S);

/* 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);
Expand All @@ -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);
Expand All @@ -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();

Expand Down