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 /src/cm/cm.c | |
| parent | e73dbb321629b845d37cae1b8376a8ac5a7542be (diff) | |
| download | ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.gz ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.tar.zst ecgen-35d80e26ca2284e20ee93eb5bf05914f73fca6d3.zip | |
Diffstat (limited to 'src/cm/cm.c')
| -rw-r--r-- | src/cm/cm.c | 116 |
1 files changed, 93 insertions, 23 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; |
