aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-05-07 18:06:53 +0200
committerJ08nY2017-05-07 18:06:53 +0200
commit2c6bfa342ac85cd1ec5265b217d7cb33afd91e69 (patch)
tree0b3c371c7c033b713f5c8f57e774b4f56b97e41e
parent2fe84534d7cfa5a2aebd8877222871b54e7c80c5 (diff)
downloadecgen-2c6bfa342ac85cd1ec5265b217d7cb33afd91e69.tar.gz
ecgen-2c6bfa342ac85cd1ec5265b217d7cb33afd91e69.tar.zst
ecgen-2c6bfa342ac85cd1ec5265b217d7cb33afd91e69.zip
-rw-r--r--README.md13
-rw-r--r--src/exhaustive/exhaustive.c100
-rw-r--r--src/invalid/invalid.c15
-rw-r--r--src/invalid/invalid_thread.c21
-rw-r--r--src/math/curve.c4
-rw-r--r--src/math/gens.c2
-rw-r--r--src/math/types.h2
-rw-r--r--test/common.sh9
-rwxr-xr-xtest/ecgen.sh24
m---------test/lib/assert.sh0
10 files changed, 118 insertions, 72 deletions
diff --git a/README.md b/README.md
index b06d863..25fedeb 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,10 @@ Tool for generating Elliptic curve domain parameters.
- `-c / --count=COUNT` Generate multiple curves.
- `-i / --invalid` Generate a set of invalid curves, for a given curve (using Invalid curve algorithm).
- - `-k / --cofactor=BOUND` Generate a curve with cofactor up to `BOUND`
+ - `-k / --cofactor=BOUND` Generate a curve with cofactor up to `BOUND` **TODO**
+ - `--anomalous` Generate an anomalous curve (of trace one, with field order equal to curve order).
- `-K / --koblitz` Generate a Koblitz curve (a = 0).
- - `-n / --order=ORDER` Generate a curve with given `ORDER` (using Complex Multiplication).
+ - `-n / --order=ORDER` Generate a curve with given `ORDER` (using Complex Multiplication). **TODO**
- `-p / --prime` Generate a curve with prime order.
- `--points=TYPE` Generate points of given `TYPE` (random/prime/none).
- `-r / --random` Generate a random curve (using Random approach).
@@ -26,18 +27,18 @@ Tool for generating Elliptic curve domain parameters.
#### IO options
- - `-a / --append` Append to output file (don't overwrite).
+- `-t / --format=FORMAT` Format to output in. One of [csv,json], default is json.
- `-f / --input=FILE` Input from `FILE`.
- `-o / --output=FILE` Output into `FILE`. Overwrites any existing file!
- - `-t / --format=FORMAT` Format to output in. One of [csv,json], default is json.
+ - `-a / --append` Append to output file (don't overwrite).
- `-v / --verbose[=FILE]` Verbose logging (to stdout or `FILE`).
#### Other
- `-d / --data-dir=DIR` Set PARI/GP data directory (containing seadata package).
- `-m / --memory=SIZE` Use PARI stack of `SIZE` (can have suffix k/m/g).
- - `--thread-stack=SIZE` Use PARI stack of `SIZE` (per thread, can have suffix k/m/g).
- `--threads=NUM` Use `NUM` threads.
+ - `--thread-stack=SIZE` Use PARI stack of `SIZE` (per thread, can have suffix k/m/g).
#### Examples
@@ -103,6 +104,7 @@ Three different EC curve parameters generation methods are implemented.
- `-p / --prime` generates curves until a prime order curve is found.
- `-K / --koblitz` generates a curve with fixed *A = 0* parameter.
- `-u / --unique` generates a uniquely generated curve (with one generator/cyclic group).
+ - etc..
##### Invalid curve generation
@@ -121,6 +123,7 @@ Three different EC curve parameters generation methods are implemented.
- Used with the `-n / --order` option
- [Constructing elliptic curves of prime order - [Broker, Stevenhagen]](https://arxiv.org/abs/0712.2022)
- [Generating Elliptic Curves of Prime Order - [Savas, Schmidt, Koc]](http://people.oregonstate.edu/~schmidtt/ourPapers/SavasKoc/ches01curve.pdf)
+ - *Currently not implemented.*
### Build
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 3e0209f..55d2212 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -3,11 +3,9 @@
* Copyright (C) 2017 J08nY
*/
#include "exhaustive.h"
-#include <io/config.h>
#include <math/types.h>
#include "anomalous.h"
#include "io/output.h"
-#include "math/arg.h"
#include "math/curve.h"
#include "math/equation.h"
#include "math/field.h"
@@ -92,9 +90,6 @@ static void exhaustive_ginit(gen_t *generators, const config_t *cfg) {
}
static void exhaustive_ainit(arg_t **argss, const config_t *cfg) {
- for (size_t i = 0; i < OFFSET_END; ++i) {
- argss[i] = NULL;
- }
if (cfg->anomalous) {
arg_t *field_arg = arg_new();
arg_t *eq_arg = arg_new();
@@ -116,13 +111,18 @@ static void exhaustive_ainit(arg_t **argss, const config_t *cfg) {
}
if (cfg->cofactor) {
arg_t *order_arg = arg_new();
+ arg_t *gens_arg = arg_new();
order_arg->args = &cfg->cofactor_bound;
order_arg->nargs = 1;
+ gens_arg->args = &cfg->cofactor_bound;
+ gens_arg->nargs = 1;
argss[OFFSET_ORDER] = order_arg;
+ argss[OFFSET_GENERATORS] = gens_arg;
}
}
void exhaustive_uinit(unroll_t *unrolls, const config_t *cfg) {
+ unrolls[OFFSET_SEED] = &unroll_skip;
unrolls[OFFSET_FIELD] = &unroll_skip;
unrolls[OFFSET_A] = &unroll_skip;
unrolls[OFFSET_B] = &unroll_skip;
@@ -137,64 +137,64 @@ int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
offset_e start_offset, offset_e end_offset,
int retry) {
if (start_offset == end_offset) {
- return 1;
+ return 2;
}
if (start_offset > end_offset) {
- return -1;
+ return 0;
}
- int num_gens = end_offset - start_offset;
- pari_sp tops[num_gens];
- int tries[num_gens];
- memset(tries, 0, sizeof(int) * num_gens);
+
+ pari_sp stack_tops[OFFSET_END] = {0};
+ int gen_tries[OFFSET_END] = {0};
int state = start_offset;
while (state < end_offset) {
- // remember pari stack
- tops[state - start_offset] = avma;
+ stack_tops[state] = avma;
int diff = generators[state](curve, cfg, argss ? argss[state] : NULL);
- if (diff == INT_MIN) {
- fprintf(stderr, "Error generating a curve. state = %i\n", state);
- return 0;
- }
+ int new_state = state + diff;
+ if (new_state < start_offset) new_state = start_offset;
+
+ if (diff <= 0) {
+ if (diff == INT_MIN || state + diff < 0) {
+ fprintf(stderr, "Error generating a curve. state = %i\n",
+ state);
+ return 0;
+ }
+ // record try
+ int tried = ++gen_tries[state];
+ if (retry && tried >= retry) {
+ if (cfg->verbose) {
+ fprintf(verbose, "Reached retry limit: %i, state = %i\n",
+ retry, state);
+ }
+ return 0;
+ }
- if (state + diff < start_offset) {
- // what now?
- // TODO
- } else if (diff <= 0) {
- // unroll pari stack
- int new_state = state + diff;
+ // unroll
for (int i = state; i > new_state;) {
if (unrolls && unrolls[i]) {
- i += unrolls[i](curve, cfg, tops[i], tops[i - 1]);
+ i += unrolls[i](curve, cfg, stack_tops[i],
+ stack_tops[i - 1]);
} else {
--i;
}
}
- avma = tops[new_state - start_offset];
- }
-
- if (diff <= 0) {
- int tried = ++tries[state - start_offset];
- if (retry && tried >= retry) {
- fprintf(stderr, "Reached retry limit: %i, state = %i\n", retry,
- state);
- return 0;
- }
- } else if (diff > 0) {
- tries[state - start_offset] = 0;
- }
- state += diff;
- if (cfg->verbose) {
- if (diff > 0) {
- fprintf(verbose, "+");
- } else if (diff < 0) {
- fprintf(verbose, "-");
- } else {
- fprintf(verbose, ".");
+ if (cfg->verbose) {
+ if (diff < 0) {
+ fprintf(verbose, "-");
+ } else {
+ fprintf(verbose, ".");
+ }
}
+ // unroll stack
+ avma = stack_tops[new_state];
+ } else {
+ // we are going forward, reset tries
+ gen_tries[state] = 0;
+ if (cfg->verbose) fprintf(verbose, "+");
}
+ state = new_state;
}
if (cfg->verbose) fprintf(verbose, "\n");
@@ -224,9 +224,9 @@ static void exhaustive_quit(arg_t *argss[]) {
int exhaustive_do(config_t *cfg) {
debug("# Starting Exhaustive method\n");
- gen_t generators[OFFSET_END];
- arg_t *argss[OFFSET_END];
- unroll_t unrolls[OFFSET_END];
+ gen_t generators[OFFSET_END] = {NULL};
+ arg_t *argss[OFFSET_END] = {NULL};
+ unroll_t unrolls[OFFSET_END] = {NULL};
exhaustive_ginit(generators, cfg);
exhaustive_ainit(argss, cfg);
exhaustive_uinit(unrolls, cfg);
@@ -235,8 +235,8 @@ int exhaustive_do(config_t *cfg) {
output_o_begin(cfg);
for (unsigned long i = 0; i < cfg->count; ++i) {
curve_t *curve = curve_new();
- if (!exhaustive_gen_retry(curve, cfg, generators, argss, unrolls,
- OFFSET_SEED, OFFSET_END, 10)) {
+ if (!exhaustive_gen(curve, cfg, generators, argss, unrolls, OFFSET_SEED,
+ OFFSET_END)) {
curve_free(&curve);
return 1;
}
diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c
index 18224e8..122bf4f 100644
--- a/src/invalid/invalid.c
+++ b/src/invalid/invalid.c
@@ -5,7 +5,6 @@
#include "invalid.h"
#include "exhaustive/exhaustive.h"
#include "invalid_thread.h"
-#include "io/config.h"
#include "io/output.h"
#include "math/curve.h"
#include "math/equation.h"
@@ -31,6 +30,7 @@ static void invalid_original_ginit(gen_t *generators, const config_t *cfg) {
}
static void invalid_invalid_ginit(gen_t *generators, const config_t *cfg) {
+ generators[OFFSET_SEED] = &gen_skip;
generators[OFFSET_FIELD] = &gen_skip;
generators[OFFSET_A] = &gen_skip;
generators[OFFSET_B] = &b_random;
@@ -121,6 +121,14 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
}
if (total > 0) {
+ if (!exhaustive_gen_retry(invalid, cfg, invalid_gen, NULL, unrolls,
+ OFFSET_GENERATORS, OFFSET_POINTS, 1)) {
+ curve_unroll(invalid, cfg, avma,
+ btop); // necessary to free the ellinit
+ avma = btop;
+ continue;
+ }
+
// only pass small primes that divide the curve order and those
// where we dont have a curve yet.
// this is passed to points_trial which uses trial division to find
@@ -142,7 +150,7 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
// generate prime order points, this is expensive (order needs to be
// factorised, so only do it if we want the curve)
exhaustive_gen(invalid, cfg, invalid_gen, invalid_argss, unrolls,
- OFFSET_GENERATORS, OFFSET_END);
+ OFFSET_POINTS, OFFSET_END);
size_t count = 0;
for (size_t i = nprimes; i-- > 0;) {
@@ -184,7 +192,8 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
// primes from range divided order. Thus remove it
// like it never existed.
- obj_free(invalid->curve); // necessary to free the ellinit
+ curve_unroll(invalid, cfg, avma,
+ btop); // necessary to free the ellinit
avma = btop;
}
}
diff --git a/src/invalid/invalid_thread.c b/src/invalid/invalid_thread.c
index 1539714..66aca66 100644
--- a/src/invalid/invalid_thread.c
+++ b/src/invalid/invalid_thread.c
@@ -30,8 +30,12 @@ void *invalid_thread(void *arg) {
ndivides++;
}
}
+
debug("ndivides = %lu\n", ndivides);
- if (ndivides > 0) {
+ if (ndivides > 0 &&
+ exhaustive_gen_retry(invalid, thread->cfg, thread->gens,
+ invalid_argss, thread->unrolls,
+ OFFSET_GENERATORS, OFFSET_POINTS, 1)) {
pthread_mutex_lock(thread->mutex_state);
size_t nfree = 0;
// can be up to ndivides, but also lower...
@@ -52,8 +56,8 @@ void *invalid_thread(void *arg) {
arg_t prime_divisors = {primes, nprimes};
invalid_argss[OFFSET_POINTS] = &prime_divisors;
exhaustive_gen(invalid, thread->cfg, thread->gens,
- invalid_argss, thread->unrolls,
- OFFSET_GENERATORS, OFFSET_END);
+ invalid_argss, thread->unrolls, OFFSET_POINTS,
+ OFFSET_END);
pthread_mutex_lock(thread->mutex_state);
size_t count = 0;
@@ -76,14 +80,13 @@ void *invalid_thread(void *arg) {
invalid = curve_new();
invalid->field = gcopy(thread->original_curve->field);
invalid->a = gcopy(thread->original_curve->a);
- } else {
- curve_unroll(invalid, thread->cfg, avma, btop);
- avma = btop;
+ continue;
}
- } else {
- curve_unroll(invalid, thread->cfg, avma, btop);
- avma = btop;
}
+
+ // We were unsuccessful for some reasol, unroll
+ curve_unroll(invalid, thread->cfg, avma, btop);
+ avma = btop;
}
curve_free(&invalid);
diff --git a/src/math/curve.c b/src/math/curve.c
index 633cf27..969e628 100644
--- a/src/math/curve.c
+++ b/src/math/curve.c
@@ -66,6 +66,8 @@ curve_t *curve_new_clone(const curve_t *src) {
void curve_free(curve_t **curve) {
if (*curve) {
seed_free(&(*curve)->seed);
+ points_free_deep(&(*curve)->generators, (*curve)->ngens);
+ points_free_deep(&(*curve)->points, (*curve)->npoints);
if ((*curve)->curve) {
// TODO, this is possibly dangerous...
@@ -88,8 +90,6 @@ void curve_free(curve_t **curve) {
gunclone((*curve)->order);
}
- points_free_deep(&(*curve)->generators, (*curve)->ngens);
- points_free_deep(&(*curve)->points, (*curve)->npoints);
pari_free(*curve);
*curve = NULL;
}
diff --git a/src/math/gens.c b/src/math/gens.c
index 5965f9a..119c22b 100644
--- a/src/math/gens.c
+++ b/src/math/gens.c
@@ -6,8 +6,6 @@
#include "point.h"
static int gens_put(curve_t *curve, GEN generators, long len) {
- points_free_deep(&curve->generators, curve->ngens);
-
curve->generators = points_new((size_t)len);
curve->ngens = (size_t)len;
diff --git a/src/math/types.h b/src/math/types.h
index 64b9c99..ab4b224 100644
--- a/src/math/types.h
+++ b/src/math/types.h
@@ -63,7 +63,7 @@ typedef struct {
* @brief
*/
typedef enum {
- OFFSET_SEED,
+ OFFSET_SEED = 0,
OFFSET_FIELD,
OFFSET_A,
OFFSET_B,
diff --git a/test/common.sh b/test/common.sh
index d637e9f..d446f79 100644
--- a/test/common.sh
+++ b/test/common.sh
@@ -8,4 +8,13 @@ JSON="lib/JSON.sh/JSON.sh"
start_test() {
echo
printf "[*] Test %-20s" "${FUNCNAME[1]}"
+}
+
+strip_num() {
+ num="$1"
+ num="${num%\"}"
+ num="${num#\"}"
+ num="${num:2}"
+ num="${num##+(0)}"
+ echo $num
} \ No newline at end of file
diff --git a/test/ecgen.sh b/test/ecgen.sh
index 6e1dd0a..bfdce03 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -35,8 +35,32 @@ function json() {
assert_matches "${JSON} -x \\\"order\\\"" "0x3de" "${f2m}"
}
+function exhaustive() {
+ start_test
+ assert_raises "${ecgen} --fp -r 10"
+ assert_raises "${ecgen} --f2m -r 10"
+ assert_raises "${ecgen} --fp -r -i 10"
+ assert_raises "${ecgen} --f2m -r -i 10"
+ assert_raises "${ecgen} --fp -r -p 10"
+ assert_raises "${ecgen} --f2m -r -u 10"
+ assert_raises "${ecgen} --fp -r -i -u 10"
+ assert_raises "${ecgen} --f2m -r -i -u 10"
+ assert_raises "${ecgen} --fp -r -k 10 10"
+}
+
+function anomalous() {
+ start_test
+ assert_raises "${ecgen} --fp --anomalous -r 20"
+ out=$(${ecgen} --fp -tjson --anomalous -r 20)
+ p=$(echo $out | ${JSON} -x field\",\"p | cut -f 2)
+ order=$(echo $out | ${JSON} -x ^0,\"order\" | cut -f 2)
+ assert "strip_num $p" $(strip_num $order)
+}
+
. ${ASSERT} -v
runs
csv
json
+exhaustive
+anomalous
assert_end ecgen
diff --git a/test/lib/assert.sh b/test/lib/assert.sh
-Subproject b8da4c93c2d0a3d11c385c3d0619330228412e4
+Subproject 679ed662f008eaceff2ce78002398ab850a0714