diff options
| -rw-r--r-- | src/exhaustive/exhaustive.c | 7 | ||||
| -rw-r--r-- | src/gen/metadata.c | 38 | ||||
| -rw-r--r-- | src/gen/metadata.h | 19 | ||||
| -rw-r--r-- | src/invalid/invalid.c | 2 | ||||
| -rw-r--r-- | src/io/cli.c | 9 | ||||
| -rw-r--r-- | src/io/output.c | 35 | ||||
| -rw-r--r-- | src/misc/config.h | 2 | ||||
| -rw-r--r-- | src/misc/types.c | 2 | ||||
| -rw-r--r-- | src/misc/types.h | 16 | ||||
| -rwxr-xr-x | test/ecgen.sh | 3 | ||||
| -rw-r--r-- | test/src/gen/test_order.c | 4 |
11 files changed, 133 insertions, 4 deletions
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c index 28d464a..15b299a 100644 --- a/src/exhaustive/exhaustive.c +++ b/src/exhaustive/exhaustive.c @@ -15,6 +15,7 @@ #include "gen/hex.h" #include "gen/order.h" #include "gen/point.h" +#include "gen/metadata.h" #include "gen/seed.h" #include "io/output.h" #include "misc/config.h" @@ -182,6 +183,12 @@ static void exhaustive_ginit(gen_f *generators) { generators[OFFSET_CURVE] = &curve_gen_any; } + if (cfg->metadata) { + generators[OFFSET_METADATA] = &metadata_gen; + } else { + generators[OFFSET_METADATA] = &gen_skip; + } + switch (cfg->points.type) { case POINTS_RANDOM: if (cfg->points.amount) { diff --git a/src/gen/metadata.c b/src/gen/metadata.c new file mode 100644 index 0000000..512c30c --- /dev/null +++ b/src/gen/metadata.c @@ -0,0 +1,38 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017-2018 J08nY + */ +#include "gens.h" +#include "field.h" +#include "metadata.h" + +GENERATOR(metadata_gen) { + GEN j = field_elementi(ell_get_j(curve->curve)); + GEN disc = field_elementi(ell_get_disc(curve->curve)); + GEN embedding_degree; + GEN q; + if (typ(curve->field) == t_INT) { + embedding_degree = gens_get_embedding(curve->field, curve->order); + q = curve->field; + } else if (typ(curve->field) == t_FFELT){ + embedding_degree = NULL; + q = int2n(degree(FF_mod(curve->field))); + } else { + return -7; + } + GEN frobenius = negi(subii(curve->order, addis(q, 1))); + GEN cm_disc; + if (typ(curve->field) == t_INT) { + cm_disc = core(subii(mulis(q, 4), sqri(frobenius))); + } else if (typ(curve->field) == t_FFELT){ + cm_disc = NULL; + } else { + return -7; + } + curve->meta.j_invariant = j; + curve->meta.discriminant = disc; + curve->meta.embedding_degree = embedding_degree; + curve->meta.frobenius_trace = frobenius; + curve->meta.cm_discriminant = cm_disc; + return 1; +} diff --git a/src/gen/metadata.h b/src/gen/metadata.h new file mode 100644 index 0000000..914828c --- /dev/null +++ b/src/gen/metadata.h @@ -0,0 +1,19 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017-2018 J08nY + */ +#ifndef ECGEN_GEN_METADATA_H +#define ECGEN_GEN_METADATA_H + +#include "misc/types.h" + +/** + * @brief + * @param curve + * @param args + * @param state + * @return + */ +GENERATOR(metadata_gen); + +#endif //ECGEN_GEN_METADATA_H diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c index 70ecda4..9b4dcb2 100644 --- a/src/invalid/invalid.c +++ b/src/invalid/invalid.c @@ -37,6 +37,7 @@ static void invalid_original_ginit(gen_f *generators) { generators[OFFSET_GENERATORS] = &gens_gen_any; generators[OFFSET_CURVE] = &curve_gen_any; generators[OFFSET_ORDER] = &order_gen_any; + generators[OFFSET_METADATA] = &gen_skip; } static void invalid_invalid_ginit(gen_f *generators) { @@ -52,6 +53,7 @@ static void invalid_invalid_ginit(gen_f *generators) { generators[OFFSET_GENERATORS] = &gens_gen_any; } generators[OFFSET_POINTS] = &points_gen_trial; + generators[OFFSET_METADATA] = &gen_skip; } static void invalid_cinit(check_t **validators) { diff --git a/src/io/cli.c b/src/io/cli.c index 14d51f8..32888a8 100644 --- a/src/io/cli.c +++ b/src/io/cli.c @@ -39,6 +39,7 @@ enum opt_keys { OPT_TIMEOUT, OPT_ANOMALOUS, OPT_HEXCHECK, + OPT_METADATA, OPT_BRAINPOOL_RFC, OPT_TWIST, }; @@ -59,7 +60,8 @@ struct argp_option cli_options[] = { {"twist", OPT_TWIST, 0, 0, "Generate a twist of a given curve.", 2}, {0, 0, 0, 0, "Generation options:", 3}, - {"random", OPT_RANDOM, "WHAT", OPTION_ARG_OPTIONAL, "Generate a random curve (using Random approach). Optionally, only generate random parameters WHAT (seed,field,a,b,equation).", 3}, + {"random", OPT_RANDOM, "WHAT", OPTION_ARG_OPTIONAL, "Generate a random curve (using Random approach). " + "Optionally, only generate random parameters WHAT (seed,field,a,b,equation).", 3}, {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 3}, {"cofactor", OPT_COFACTOR, "VALUE", 0, "Generate a curve with cofactor of VALUE.", 3}, {"koblitz", OPT_KOBLITZ, "A", OPTION_ARG_OPTIONAL, "Generate a Koblitz curve (a in {0, 1}, b = 1).", 3}, @@ -67,6 +69,8 @@ struct argp_option cli_options[] = { {"hex-check", OPT_HEXCHECK, "HEX", 0, "Check a generated curve param hex expansion for the HEX string.", 3}, {"points", OPT_POINTS, "TYPE", 0, "Generate points of given type (random/prime/all/nonprime/none).", 3}, {"count", OPT_COUNT, "COUNT", 0, "Generate multiple curves.", 3}, + {"metadata", OPT_METADATA, 0, 0, "Compute curve metadata " + "(j-invariant, discriminant, trace of Frobenius, embedding degree, CM discriminant).", 3}, {0, 0, 0, 0, "Input/Output options:", 4}, {"input", OPT_INPUT, "FILE", 0, "Input from file.", 4}, @@ -310,6 +314,9 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { cfg->hex_check = str_start; break; } + case OPT_METADATA: + cfg->metadata = true; + break; case OPT_POINTS: { char *num_end; long amount = strtol(arg, &num_end, 10); diff --git a/src/io/output.c b/src/io/output.c index 2130614..8ad4ab0 100644 --- a/src/io/output.c +++ b/src/io/output.c @@ -5,6 +5,8 @@ #include "output.h" #include <parson/parson.h> +#include <misc/config.h> +#include <misc/types.h> #include "gen/field.h" #include "util/bits.h" #include "util/memory.h" @@ -120,6 +122,39 @@ static JSON_Value *output_jjson(curve_t *curve) { } json_object_set_value(root_object, "subgroups", gens_value); } + if (cfg->metadata) { + debug_log("here"); + if (curve->meta.j_invariant != NULL) { + char *j = pari_sprintf("%Pi", curve->meta.j_invariant); + json_object_dotset_string(root_object, "meta.j", j); + pari_free(j); + } + debug_log("here"); + if (curve->meta.discriminant != NULL) { + char *disc = pari_sprintf("%Pi", curve->meta.discriminant); + json_object_dotset_string(root_object, "meta.discriminant", disc); + pari_free(disc); + } + debug_log("here"); + if (curve->meta.embedding_degree != NULL) { + char *embedding_degree = pari_sprintf("%Pi", curve->meta.embedding_degree); + json_object_dotset_string(root_object, "meta.embedding_degree", embedding_degree); + pari_free(embedding_degree); + } + debug_log("here"); + if (curve->meta.frobenius_trace != NULL) { + char *frobenius = pari_sprintf("%Pi", curve->meta.frobenius_trace); + json_object_dotset_string(root_object, "meta.frobenius", frobenius); + pari_free(frobenius); + } + debug_log("here"); + if (curve->meta.cm_discriminant != NULL) { + char *cm_discriminant = pari_sprintf("%Pi", curve->meta.cm_discriminant); + json_object_dotset_string(root_object, "meta.cm_discriminant", cm_discriminant); + pari_free(cm_discriminant); + } + debug_log("here"); + } avma = ltop; return root_value; diff --git a/src/misc/config.h b/src/misc/config.h index 7832e88..55a3cdd 100644 --- a/src/misc/config.h +++ b/src/misc/config.h @@ -99,6 +99,8 @@ typedef struct { char *hex_check; /** @brief What points to generate on the curves. */ struct points_s points; + /** @brief Compute curve metadata. */ + bool metadata; /** @brief The datadir to use, if any. */ char *datadir; diff --git a/src/misc/types.c b/src/misc/types.c index 1554684..ca287a0 100644 --- a/src/misc/types.c +++ b/src/misc/types.c @@ -5,7 +5,7 @@ #include "types.h" const char* offset_s[OFFSET_END] = {"SEED", "FIELD", "A", "B", - "CURVE", "ORDER", "GENERATORS", "POINTS"}; + "CURVE", "ORDER", "GENERATORS", "POINTS", "METADATA"}; GENERATOR(gen_skip) { return 1; } diff --git a/src/misc/types.h b/src/misc/types.h index 4b6d8f9..89544f4 100644 --- a/src/misc/types.h +++ b/src/misc/types.h @@ -79,6 +79,17 @@ typedef struct { } subgroup_t; /** + * @brief Curve metadata. + */ +typedef struct { + GEN j_invariant; + GEN discriminant; + GEN cm_discriminant; + GEN frobenius_trace; + GEN embedding_degree; +} metadata_t; + +/** * @brief A curve type. * @param seed a seed_t * @param field a t_INT or t_FFELT @@ -87,6 +98,7 @@ typedef struct { * @param curve a t_ELL, curve object * @param order a t_INT, curve order * @param generators generators saved + * @param meta * @param ngens number of generators saved in the curve type */ typedef struct { @@ -98,8 +110,11 @@ typedef struct { GEN order; subgroup_t **generators; size_t ngens; + metadata_t meta; } curve_t; + + /** * @brief */ @@ -112,6 +127,7 @@ typedef enum { OFFSET_ORDER, OFFSET_GENERATORS, OFFSET_POINTS, + OFFSET_METADATA, OFFSET_END } offset_e; diff --git a/test/ecgen.sh b/test/ecgen.sh index 2378abd..5de7f34 100755 --- a/test/ecgen.sh +++ b/test/ecgen.sh @@ -71,6 +71,9 @@ function exhaustive() { assert_raises "${ecgen} --fp --random=seed,field,a,b,equation 10" assert_raises "${ecgen} --fp -r -c 5 10" + + assert_raises "${ecgen} --fp -r --metadata 10" + assert_raises "${ecgen} --f2m -r --metadata 10" } function ansix962() { diff --git a/test/src/gen/test_order.c b/test/src/gen/test_order.c index ba35a9a..702f052 100644 --- a/test/src/gen/test_order.c +++ b/test/src/gen/test_order.c @@ -97,8 +97,8 @@ Test(order, test_order_check_discriminant) { cfg->bits = 16; cfg->field = FIELD_PRIME; - char *min_factor = "12"; - arg_t arg = {.args = min_factor, .nargs = 1}; + char *min_disc = "12"; + arg_t arg = {.args = min_disc, .nargs = 1}; int ret = order_check_discriminant(&curve, &arg, OFFSET_ORDER); cr_assert_eq(ret, 1, ); |
