aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2018-07-12 15:01:38 +0200
committerJ08nY2018-07-12 15:01:38 +0200
commit35d80e26ca2284e20ee93eb5bf05914f73fca6d3 (patch)
treea4b0387b523a6866b38658dbfa7c55f4dd9732d9
parente73dbb321629b845d37cae1b8376a8ac5a7542be (diff)
downloadecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.gz
ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.zst
ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.zip
-rw-r--r--src/cm/cm.c116
-rw-r--r--src/cm/cm_any.c9
-rw-r--r--src/cm/cm_prime.c5
-rw-r--r--src/ecgen.c7
-rw-r--r--src/io/cli.c28
-rw-r--r--src/io/cli.h10
-rw-r--r--src/util/str.c7
-rw-r--r--src/util/str.h8
-rwxr-xr-xtest/ecgen.sh1
9 files changed, 163 insertions, 28 deletions
diff --git a/src/cm/cm.c b/src/cm/cm.c
index 239bb5d..c604876 100644
--- a/src/cm/cm.c
+++ b/src/cm/cm.c
@@ -16,6 +16,7 @@
#include "gen/point.h"
#include "obj/curve.h"
#include "supersingular.h"
+#include "util/str.h"
static void cm_ginit(gen_f *generators, bool prime) {
// SEED unused.
@@ -87,7 +88,21 @@ static void cm_ginit(gen_f *generators, bool prime) {
}
}
-static void cm_ainit(arg_t **gen_argss, arg_t **check_argss) {
+static void cm_ainit(arg_t **gen_argss, arg_t **check_argss,
+ const char *order_s) {
+ if (cfg->method == METHOD_CM) {
+ arg_t *curve_arg = arg_new();
+ arg_t *order_arg = arg_new();
+ char *order = try_strdup(order_s);
+ curve_arg->args = order;
+ curve_arg->nargs = 1;
+ order_arg->args = order;
+ order_arg->nargs = 1;
+ order_arg->allocd = order;
+ gen_argss[OFFSET_CURVE] = curve_arg;
+ gen_argss[OFFSET_ORDER] = order_arg;
+ }
+
if (cfg->method == METHOD_ANOMALOUS) {
arg_t *field_arg = arg_new();
arg_t *eq_arg = arg_new();
@@ -120,6 +135,78 @@ static void cm_cinit(check_t **validators) {
}
}
+static int cm_init(exhaustive_t *setup) {
+ bool ord_prime = false;
+
+ char *order_s = NULL;
+ if (cfg->method == METHOD_CM) {
+ size_t delims = str_cnt(cfg->cm_order, ',');
+ GEN order;
+ if (delims == 0) {
+ order = strtoi(cfg->cm_order);
+ order_s = cfg->cm_order;
+ } else {
+ GEN factors = gtovec0(gen_0, delims + 1);
+ char *delim;
+ char *s_start = try_strdup(cfg->cm_order);
+ char *s = s_start;
+ long i = 1;
+ while (true) {
+ if ((delim = strchr(s, ',')) != NULL) {
+ *delim = 0;
+ gel(factors, i++) = strtoi(s);
+ s = delim + 1;
+ } else {
+ gel(factors, i++) = strtoi(s);
+ break;
+ }
+ }
+
+ order = gen_1;
+ long len = glength(factors);
+ for (long j = 1; j <= len; ++j) {
+ GEN factor = gel(factors, j);
+ if (isprime(factor)) {
+ addprimes(gtovec(factor));
+ } else {
+ GEN factored = Z_factor(order);
+ addprimes(gel(factored, 1));
+ }
+ order = mulii(order, factor);
+ }
+ try_free(s_start);
+ order_s = pari_sprintf("%Pi", order);
+ }
+ if (gequal0(order)) {
+ fprintf(err, "Order requested not a number: %s\n", cfg->cm_order);
+ return 1;
+ }
+ if (delims == 0) {
+ ord_prime = (bool)isprime(order);
+ } else {
+ ord_prime = false;
+ }
+ }
+
+ if (cfg->method == METHOD_ANOMALOUS) {
+ anomalous_init();
+ }
+
+ cm_ginit(setup->generators, ord_prime);
+ cm_ainit(setup->gen_argss, setup->check_argss, order_s);
+ cm_cinit(setup->validators);
+ exhaustive_uinit(setup->unrolls);
+
+ return 0;
+}
+
+static void cm_quit(exhaustive_t *setup) {
+ if (cfg->method == METHOD_ANOMALOUS) {
+ anomalous_quit();
+ }
+ exhaustive_clear(setup);
+}
+
int cm_do() {
debug_log_start("Starting Complex Multiplication method");
@@ -135,31 +222,14 @@ int cm_do() {
.check_argss = check_argss,
.unrolls = unrolls};
- bool ord_prime = false;
- if (cfg->method == METHOD_CM) {
- GEN order = strtoi(cfg->cm_order);
- if (gequal0(order)) {
- fprintf(err, "Order requested not a number: %s\n", cfg->cm_order);
- return 1;
- }
- ord_prime = (bool)isprime(order);
- }
-
- if (cfg->method == METHOD_ANOMALOUS) {
- anomalous_init();
+ int result = cm_init(&setup);
+ if (result) {
+ return result;
}
- cm_ginit(setup.generators, ord_prime);
- cm_ainit(setup.gen_argss, setup.check_argss);
- cm_cinit(setup.validators);
- exhaustive_uinit(setup.unrolls);
-
- int result = exhaustive_generate(&setup);
+ result = exhaustive_generate(&setup);
- if (cfg->method == METHOD_ANOMALOUS) {
- anomalous_quit();
- }
- exhaustive_clear(&setup);
+ cm_quit(&setup);
debug_log_start("Finished Complex Multiplication method");
return result;
diff --git a/src/cm/cm_any.c b/src/cm/cm_any.c
index 2cab060..fef4cff 100644
--- a/src/cm/cm_any.c
+++ b/src/cm/cm_any.c
@@ -3,6 +3,7 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "cm_any.h"
+#include "exhaustive/arg.h"
#include "io/output.h"
#include "obj/curve.h"
#include "util/memory.h"
@@ -204,8 +205,10 @@ GEN cm_construct_curve(GEN order, GEN d, GEN p, bool ord_prime) {
}
GENERATOR(cm_gen_curve_any) {
+ HAS_ARG(args);
pari_sp ltop = avma;
- GEN order = strtoi(cfg->cm_order);
+ const char *order_s = (const char *)args->args;
+ GEN order = strtoi(order_s);
cm_any_qdisc_t min_disc = {0};
good_qdisc_minimal(&min_disc, order);
debug_log("Got min D = %Pi", min_disc.d);
@@ -223,6 +226,8 @@ GENERATOR(cm_gen_curve_any) {
}
GENERATOR(cm_gen_order) {
- curve->order = strtoi(cfg->cm_order);
+ HAS_ARG(args);
+ const char *order_s = (const char *)args->args;
+ curve->order = strtoi(order_s);
return 1;
} \ No newline at end of file
diff --git a/src/cm/cm_prime.c b/src/cm/cm_prime.c
index 383229b..33d2a12 100644
--- a/src/cm/cm_prime.c
+++ b/src/cm/cm_prime.c
@@ -4,6 +4,7 @@
*/
#include "cm_prime.h"
#include "cm_any.h"
+#include "exhaustive/arg.h"
#include "io/output.h"
#include "obj/curve.h"
#include "obj/point.h"
@@ -138,7 +139,9 @@ static void qdisc_next(cm_prime_qdisc_t *qdisc) {
static void qdisc_free(cm_prime_qdisc_t *qdisc) { try_free(qdisc->Sp); }
GENERATOR(cm_gen_curve_prime) {
- GEN order = strtoi(cfg->cm_order);
+ HAS_ARG(args);
+ const char *order_s = (const char *)args->args;
+ GEN order = strtoi(order_s);
GEN e = NULL;
cm_prime_qdisc_t qdisc = {0};
diff --git a/src/ecgen.c b/src/ecgen.c
index b3a2190..bfc2dee 100644
--- a/src/ecgen.c
+++ b/src/ecgen.c
@@ -72,6 +72,9 @@ bool init(void) {
pari_TRY { ellmodulareqn(2, -1, -1); }
pari_ENDCATCH avma = ltop;
+ // Fix the mysterious isprime bug.
+ isprime(stoi(1));
+
// open outfile
if (!output_init()) return false;
@@ -142,7 +145,11 @@ int quit(int status) {
*/
int main(int argc, char *argv[]) {
memset(cfg, 0, sizeof(config_t));
+ if (!cli_init()) {
+ return quit(EXIT_FAILURE);
+ }
argp_parse(&argp, argc, argv, 0, 0, cfg);
+ cli_quit();
if (!init()) {
return quit(EXIT_FAILURE);
diff --git a/src/io/cli.c b/src/io/cli.c
index 940de84..de1fd12 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -3,10 +3,10 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "cli.h"
+#include <regex.h>
#include <string.h>
#include "exhaustive/ansi.h"
#include "exhaustive/brainpool.h"
-#include "misc/config.h"
char cli_doc[] =
"ecgen, tool for generating Elliptic curve domain parameters.\v(C) "
@@ -90,6 +90,24 @@ struct argp_option cli_options[] = {
};
// clang-format on
+static regex_t re_cm_order;
+
+bool cli_init() {
+ int error = regcomp(
+ &re_cm_order,
+ "((0[xX][0-9a-fA-F]+)|([0-9]+))(,((0[xX][0-9a-fA-F]+)|([0-9]+)))*",
+ REG_EXTENDED);
+ if (error) {
+ size_t length = regerror(error, &re_cm_order, NULL, 0);
+ char msg[length + 1];
+ regerror(error, &re_cm_order, msg, length + 1);
+ fprintf(stderr, "Error compiling regex: %s\n", msg);
+ return false;
+ }
+
+ return true;
+}
+
static unsigned long cli_parse_memory(const char *str,
struct argp_state *state) {
char *suffix = NULL;
@@ -184,7 +202,7 @@ static void cli_end(struct argp_state *state) {
error_t cli_parse(int key, char *arg, struct argp_state *state) {
switch (key) {
- /* Field options */
+ /* Field options */
case OPT_FP:
cfg->field |= FIELD_PRIME;
break;
@@ -206,6 +224,10 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
case OPT_ORDER:
cfg->method |= METHOD_CM;
if (arg) {
+ int error = regexec(&re_cm_order, arg, 0, NULL, 0);
+ if (error != 0) {
+ argp_failure(state, 1, 0, "Invalid order %s", arg);
+ }
cfg->cm_order = arg;
}
break;
@@ -418,3 +440,5 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
char *cli_filter(int key, const char *text, void *input) {
return (char *)text;
}
+
+void cli_quit() { regfree(&re_cm_order); } \ No newline at end of file
diff --git a/src/io/cli.h b/src/io/cli.h
index f480f7f..abeb6e6 100644
--- a/src/io/cli.h
+++ b/src/io/cli.h
@@ -18,6 +18,11 @@ extern struct argp_option cli_options[];
/**
* @brief
+ */
+bool cli_init();
+
+/**
+ * @brief
* @param key
* @param arg
* @param state
@@ -34,4 +39,9 @@ error_t cli_parse(int key, char *arg, struct argp_state *state);
*/
char *cli_filter(int key, const char *text, void *input);
+/**
+ *
+ */
+void cli_quit();
+
#endif // ECGEN_IO_CLI_H
diff --git a/src/util/str.c b/src/util/str.c
index 7293538..ff075f2 100644
--- a/src/util/str.c
+++ b/src/util/str.c
@@ -65,3 +65,10 @@ char *str_joinv(char *separator, ...) {
char *str_concat(char **strings, size_t len) {
return str_join(NULL, strings, len);
}
+
+size_t str_cnt(const char *str, const char c) {
+ size_t result = 0;
+ for (; str[result]; str[result] == c ? result++ : *str++)
+ ;
+ return result;
+}
diff --git a/src/util/str.h b/src/util/str.h
index 2e2feba..a489116 100644
--- a/src/util/str.h
+++ b/src/util/str.h
@@ -42,4 +42,12 @@ char *str_joinv(char *separator, ...);
*/
char *str_concat(char **strings, size_t len);
+/**
+ * @brief
+ * @param str
+ * @param c
+ * @return
+ */
+size_t str_cnt(const char *str, const char c);
+
#endif // ECGEN_UTIL_STR_H
diff --git a/test/ecgen.sh b/test/ecgen.sh
index fd1da25..c084bbc 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -155,6 +155,7 @@ function cm() {
start_test
assert_raises "${ecgen} --fp --order=2147483723 32"
assert_raises "${ecgen} --fp --order=123456789012345678901234567890123456789012345678901234568197 137"
+ assert_raises "${ecgen} --fp --order=46874566546,3546,3125 64"
}
function secg() {