diff options
| author | J08nY | 2017-09-29 16:50:13 +0200 |
|---|---|---|
| committer | J08nY | 2018-04-07 14:38:24 +0200 |
| commit | 99e192422d95240adbe806a53caabfa9ddb258c3 (patch) | |
| tree | 0903938e52b62a494b3f00e8d4b04a1d7c761e0c /src | |
| parent | 962e197004b19e0b8e42dc977dc0ec1a85f407c1 (diff) | |
| download | ecgen-99e192422d95240adbe806a53caabfa9ddb258c3.tar.gz ecgen-99e192422d95240adbe806a53caabfa9ddb258c3.tar.zst ecgen-99e192422d95240adbe806a53caabfa9ddb258c3.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/cm/cm.c | 7 | ||||
| -rw-r--r-- | src/cm/custom.c | 129 | ||||
| -rw-r--r-- | src/cm/custom.h | 24 |
3 files changed, 158 insertions, 2 deletions
diff --git a/src/cm/cm.c b/src/cm/cm.c index f6a593f..04fbd9b 100644 --- a/src/cm/cm.c +++ b/src/cm/cm.c @@ -4,21 +4,24 @@ */ #include "cm.h" #include "io/output.h" -#include "p1363.h" +#include "custom.h" int cm_do() { debug_log_start("Starting Complex Multiplication method"); fprintf(err, "This is *NOT IMPLEMENTED* currently.\n"); + /* GEN D = stoi(71); p1363_form_t **forms; size_t nforms = p1363_forms(D, &forms); for (size_t i = 0; i < nforms; ++i) { p1363_invariant(D, forms[i]); } - p1363_free(&forms, nforms); + */ + custom_curve(); + debug_log_start("Finished Complex Multiplication method"); return 0; } diff --git a/src/cm/custom.c b/src/cm/custom.c new file mode 100644 index 0000000..fc403e5 --- /dev/null +++ b/src/cm/custom.c @@ -0,0 +1,129 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "custom.h" +#include "io/input.h" + +static bool custom_is_disc(GEN test) { + bool result = true; + long md4; + pari_CATCH(e_DOMAIN) + { + result = false; + } + pari_TRY{ check_quaddisc_imag(test, &md4, ""); }; + pari_ENDCATCH + return result; +} + +static GEN custom_disc(GEN order, GEN prime) { + pari_sp ltop = avma; + + GEN t = subii(order, addii(prime, gen_1)); + GEN v2D = subii(mulis(prime, 4), sqri(t)); + + GEN max_divisor = gen_1; + GEN min_D = v2D; + + // Optional part that sometimes makes the discriminant smaller, at the cost + // factoring v2D. + GEN fctr = factor(v2D); + long len = glength(gel(fctr, 1)); + for (long i = 1; i <= len; ++i) { + GEN value = gmael(fctr, 1, i); + GEN mul = gmael(fctr, 2, i); + GEN pow; + if (mod2(mul) == 0) { + pow = mul; + } else { + pow = subis(mul, 1); + } + if (equalis(pow, 0)) { + continue; + } + GEN divi = powii(value, pow); + if (mpcmp(divi, max_divisor) > 0) { + GEN candidate_D = divii(v2D, divi); + if (signe(candidate_D) == 1) { + setsigne(candidate_D, -1); + } + if (custom_is_disc(candidate_D)) { + max_divisor = divi; + min_D = candidate_D; + } + } + } + + if (signe(min_D) == 1) { + setsigne(min_D, -1); + } + if (custom_is_disc(min_D)) { + return gerepileupto(ltop, min_D); + } else { + avma = ltop; + return NULL; + } +} + +static custom_quadr_t custom_prime_input(GEN order) { + pari_sp ltop = avma; + custom_quadr_t result = {0}; + GEN p; + GEN D; + do { + p = input_prime("p:", cfg->bits); + if (gequalm1(p)) { + continue; + } + D = custom_disc(order, p); + } while (D == NULL); + + gerepileall(ltop, 2, &p, &D); + result.p = p; + result.D = D; + return result; +} + +static custom_quadr_t custom_prime_random(GEN order) { + pari_sp ltop = avma; + custom_quadr_t result = {0}; + GEN p; + GEN t = gen_0; + GEN v = gen_0; + GEN D; + long i = 2; + //TODO: this is wrong, order = p + 1 +- t is not kept. + while (gequal0(t)) { + D = stoi(-4 * (i / 2) + (i % 2)); + for (long j = 0; j < 100; ++j) { + p = random_prime(cfg->bits); + if (cornacchia2(negi(D), p, &t, &v)) { + break; + } + } + }; + + gerepileall(ltop, 4, &p, &t, &v, &D); + result.p = p; + result.t = t; + result.v = v; + result.D = D; + return result; +} + +curve_t *custom_curve() { + GEN order = strtoi(cfg->cm_order); + + custom_quadr_t quadr; + if (cfg->random) { + quadr = custom_prime_random(order); + } else { + quadr = custom_prime_input(order); + } + pari_printf("p = %Pi, D = %Pi, ", quadr.p, quadr.D); + GEN H = polclass(quadr.D, 0, 0); + pari_printf("H = %Ps\n", H); + + return NULL; +}
\ No newline at end of file diff --git a/src/cm/custom.h b/src/cm/custom.h new file mode 100644 index 0000000..ed6f3d3 --- /dev/null +++ b/src/cm/custom.h @@ -0,0 +1,24 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_CUSTOM_H +#define ECGEN_CUSTOM_H + +#include "misc/types.h" +#include "misc/config.h" + +typedef struct { + GEN p; + GEN t; + GEN v; + GEN D; +} custom_quadr_t; + +/** + * @brief + * @return + */ +curve_t * custom_curve(); + +#endif //ECGEN_CUSTOM_H |
