diff options
| author | J08nY | 2018-07-12 15:01:38 +0200 |
|---|---|---|
| committer | J08nY | 2018-07-12 15:01:38 +0200 |
| commit | 35d80e26ca2284e20ee93eb5bf05914f73fca6d3 (patch) | |
| tree | a4b0387b523a6866b38658dbfa7c55f4dd9732d9 | |
| parent | e73dbb321629b845d37cae1b8376a8ac5a7542be (diff) | |
| download | ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.gz ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.zst ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.zip | |
| -rw-r--r-- | src/cm/cm.c | 116 | ||||
| -rw-r--r-- | src/cm/cm_any.c | 9 | ||||
| -rw-r--r-- | src/cm/cm_prime.c | 5 | ||||
| -rw-r--r-- | src/ecgen.c | 7 | ||||
| -rw-r--r-- | src/io/cli.c | 28 | ||||
| -rw-r--r-- | src/io/cli.h | 10 | ||||
| -rw-r--r-- | src/util/str.c | 7 | ||||
| -rw-r--r-- | src/util/str.h | 8 | ||||
| -rwxr-xr-x | test/ecgen.sh | 1 |
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() { |
