diff options
| author | J08nY | 2024-11-30 00:18:22 +0100 |
|---|---|---|
| committer | J08nY | 2024-11-30 00:18:22 +0100 |
| commit | 8395408db3d707be8573203b07625175e005ef74 (patch) | |
| tree | 70727f1940e074206c0675b8017ad13da3b9587d | |
| parent | e1af97551fde2efbd847e872fbcde9380e24fe42 (diff) | |
| download | ecgen-8395408db3d707be8573203b07625175e005ef74.tar.gz ecgen-8395408db3d707be8573203b07625175e005ef74.tar.zst ecgen-8395408db3d707be8573203b07625175e005ef74.zip | |
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | docs/readme.md | 1 | ||||
| -rw-r--r-- | src/cm/cm.c | 21 | ||||
| -rw-r--r-- | src/exhaustive/exhaustive.c | 47 | ||||
| -rw-r--r-- | src/invalid/invalid.c | 7 | ||||
| -rw-r--r-- | src/io/cli.c | 31 | ||||
| -rw-r--r-- | src/misc/config.c | 91 | ||||
| -rw-r--r-- | src/misc/config.h | 32 |
8 files changed, 225 insertions, 23 deletions
@@ -184,6 +184,15 @@ Generate a prime field, uniquely generated random curve, of size 192 bits, also } }] + +> [!NOTE] +> The command-line interface is quite tricky and **will** ignore options somewhat silently, +> meaning that the computation will go on and some properties of the output curve will be wrong. +> +> If this happens, you will get a warning such as: +> > Warning: Ignored command-line argument prime (-p/--prime). + + ### Docs See [docs](docs/readme.md). Also: @@ -236,11 +245,14 @@ Four different EC curve parameters generation methods are implemented. #### Supersingular curves + - Generates curves of order equal to prime + 1 (trace of Frobenius equal to zero). + - Used with the `--supersingular` option. + - These curves are **NOT SECURE** and are useful for implementation testing. - [CONSTRUCTING SUPERSINGULAR ELLIPTIC CURVES - [Broker]](https://pdfs.semanticscholar.org/56c5/5b9cf0b218f93b8d263cc9f64ccb5fb97f52.pdf) #### Anomalous curve generation - - Generates curves of order equal to field order. + - Generates curves of order equal to field order (trace of Frobenius equal to 1). - Used with the `--anomalous` option. - These curves are **NOT SECURE** and are useful for implementation testing. - [Elliptic curves over F_p suitable for cryptosystems - [Miyaji]](https://dspace.jaist.ac.jp/dspace/bitstream/10119/4464/1/73-61.pdf) @@ -251,8 +263,8 @@ Four different EC curve parameters generation methods are implemented. ecgen can be built using Make or CMake. ecgen uses git submodules for testing at: - `test/lib/assert.sh` pointing at <https://github.com/J08nY/assert.sh> - - `test/lib/JSON.sh` pointing at <https://github.com/jimklimov/JSON.sh> - - `test/lib/criterion` pointing at <https://github.com/Snaipe/Criterion> + - `test/lib/JSON.sh` pointing at <https://github.com/J08nY/JSON.sh> + - `test/lib/criterion` pointing at <https://github.com/Snaipe/Criterion>, its build requires meson. these need to be initialized for `make test` to work. diff --git a/docs/readme.md b/docs/readme.md index 2fc5335..a5a2436 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,4 +1,5 @@ # ecgen docs +There is little information here. I am sorry about that :( - [Output](output.md) - [Points](points.md) diff --git a/src/cm/cm.c b/src/cm/cm.c index d49ec76..b606f83 100644 --- a/src/cm/cm.c +++ b/src/cm/cm.c @@ -19,22 +19,25 @@ #include "util/str.h" static void cm_ginit(gen_f *generators, bool prime) { + GET(field); + // SEED unused. generators[OFFSET_SEED] = &gen_skip; // Setup stuff so it can be overridden. - if (cfg->unique) { + if (GET_BOOL(unique)) { generators[OFFSET_GENERATORS] = &gens_gen_one; } else { generators[OFFSET_GENERATORS] = &gens_gen_any; } - if (cfg->metadata) { + if (GET_BOOL(metadata)) { generators[OFFSET_METADATA] = &metadata_gen; } else { generators[OFFSET_METADATA] = &gen_skip; } + GET(points); switch (cfg->points.type) { case POINTS_RANDOM: if (cfg->points.amount) { @@ -58,6 +61,7 @@ static void cm_ginit(gen_f *generators, bool prime) { } // Now do the actual CM setup. + GET(method); if (cfg->method == METHOD_CM) { generators[OFFSET_FIELD] = &gen_skip; generators[OFFSET_A] = &gen_skip; @@ -76,6 +80,7 @@ static void cm_ginit(gen_f *generators, bool prime) { generators[OFFSET_CURVE] = &curve_gen_any; generators[OFFSET_ORDER] = &anomalous_gen_order; } else if (cfg->method == METHOD_SUPERSINGULAR) { + GET(random); if (cfg->random & RANDOM_FIELD) { generators[OFFSET_FIELD] = &field_gen_random; } else { @@ -123,13 +128,20 @@ static void cm_ainit(arg_t **gen_argss, arg_t **check_argss, points_arg->nargs = 1; gen_argss[OFFSET_POINTS] = points_arg; } + + if (cfg->hex_check) { + arg_t *point_arg = arg_new(); + point_arg->args = cfg->hex_check; + point_arg->nargs = 1; + check_argss[OFFSET_POINTS] = point_arg; + } } static void cm_cinit(check_t **validators) { check_t *curve_check = check_new(curve_check_nonzero, NULL); validators[OFFSET_CURVE] = curve_check; - if (cfg->hex_check) { + if (GET_BOOL(hex_check)) { check_t *hex_check = check_new(hex_check_param, NULL); validators[OFFSET_POINTS] = hex_check; } @@ -140,6 +152,7 @@ static int cm_init(exhaustive_t *setup) { char *order_s = NULL; if (cfg->method == METHOD_CM) { + GET(cm_order); size_t delims = str_cnt(cfg->cm_order, ','); GEN order; if (delims == 0) { @@ -234,7 +247,7 @@ int cm_do() { if (result) { return result; } - + config_report_unused(); result = exhaustive_generate(&setup); cm_quit(&setup); diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c index 4eba6bd..413f93b 100644 --- a/src/exhaustive/exhaustive.c +++ b/src/exhaustive/exhaustive.c @@ -43,20 +43,22 @@ void exhaustive_clear(exhaustive_t *setup) { } static void exhaustive_ginit(gen_f *generators) { - if (cfg->seed_algo) { - if (cfg->prime) { + GET(field); + + if (GET_BOOL(seed_algo)) { + if (GET_BOOL(prime)) { generators[OFFSET_ORDER] = &order_gen_prime; - } else if (cfg->cofactor) { + } else if (GET_BOOL(cofactor)) { generators[OFFSET_ORDER] = &order_gen_cofactor; - } else if (cfg->smooth) { + } else if (GET_BOOL(smooth)) { generators[OFFSET_ORDER] = &order_gen_smooth; } else { generators[OFFSET_ORDER] = &order_gen_any; } - if (cfg->unique) { + if (GET_BOOL(unique)) { generators[OFFSET_GENERATORS] = &gens_gen_one; - } else if (cfg->cofactor) { + } else if (GET_BOOL(cofactor)) { generators[OFFSET_GENERATORS] = &gens_gen_cofactor; } else { generators[OFFSET_GENERATORS] = &gens_gen_any; @@ -65,15 +67,18 @@ static void exhaustive_ginit(gen_f *generators) { switch (cfg->seed_algo) { case SEED_ANSI: { // setup ANSI X9.62 generators + GET(seed); if (cfg->seed) { generators[OFFSET_SEED] = &ansi_gen_seed_argument; } else { + GET(random); if (cfg->random & RANDOM_SEED) { generators[OFFSET_SEED] = &ansi_gen_seed_random; } else { generators[OFFSET_SEED] = &ansi_gen_seed_input; } } + GET(random); if (cfg->random & RANDOM_FIELD) { generators[OFFSET_FIELD] = &field_gen_random; } else { @@ -83,9 +88,11 @@ static void exhaustive_ginit(gen_f *generators) { generators[OFFSET_B] = &ansi_gen_equation; } break; case SEED_BRAINPOOL: { + GET(seed); if (cfg->seed) { generators[OFFSET_SEED] = &brainpool_gen_seed_argument; } else { + GET(random); if (cfg->random & RANDOM_SEED) { generators[OFFSET_SEED] = &brainpool_gen_seed_random; } else { @@ -99,9 +106,11 @@ static void exhaustive_ginit(gen_f *generators) { generators[OFFSET_GENERATORS] = &brainpool_gen_gens; } break; case SEED_BRAINPOOL_RFC: { + GET(seed); if (cfg->seed) { generators[OFFSET_SEED] = &brainpool_rfc_gen_seed_argument; } else { + GET(random); if (cfg->random & RANDOM_SEED) { generators[OFFSET_SEED] = &brainpool_rfc_gen_seed_random; @@ -132,13 +141,15 @@ static void exhaustive_ginit(gen_f *generators) { // setup normal generators generators[OFFSET_SEED] = &gen_skip; + GET(random); if (cfg->random & RANDOM_FIELD) { generators[OFFSET_FIELD] = &field_gen_random; } else { generators[OFFSET_FIELD] = &field_gen_input; } - if (cfg->koblitz) { + if (GET_BOOL(koblitz)) { + GET(koblitz_value); switch (cfg->koblitz_value) { case 0: generators[OFFSET_A] = &a_gen_zero; @@ -151,12 +162,14 @@ static void exhaustive_ginit(gen_f *generators) { } generators[OFFSET_B] = &b_gen_one; } else { + GET(random); if (cfg->random & RANDOM_A) { generators[OFFSET_A] = &a_gen_random; } else { generators[OFFSET_A] = &a_gen_input; } + GET(random); if (cfg->random & RANDOM_B) { generators[OFFSET_B] = &b_gen_random; } else { @@ -164,21 +177,21 @@ static void exhaustive_ginit(gen_f *generators) { } } - if (cfg->prime) { + if (GET_BOOL(prime)) { generators[OFFSET_ORDER] = &order_gen_prime; - } else if (cfg->cofactor) { + } else if (GET_BOOL(cofactor)) { generators[OFFSET_ORDER] = &order_gen_cofactor; - } else if (cfg->smooth) { + } else if (GET_BOOL(smooth)) { generators[OFFSET_ORDER] = &order_gen_smooth; - } else if (cfg->koblitz) { + } else if (GET_BOOL(koblitz)) { generators[OFFSET_ORDER] = &order_gen_koblitz; } else { generators[OFFSET_ORDER] = &order_gen_any; } - if (cfg->unique) { + if (GET_BOOL(unique)) { generators[OFFSET_GENERATORS] = &gens_gen_one; - } else if (cfg->cofactor) { + } else if (GET_BOOL(cofactor)) { generators[OFFSET_GENERATORS] = &gens_gen_cofactor; } else { generators[OFFSET_GENERATORS] = &gens_gen_any; @@ -186,18 +199,21 @@ static void exhaustive_ginit(gen_f *generators) { } // setup common generators + GET(method); if (cfg->method == METHOD_TWIST) { generators[OFFSET_CURVE] = &curve_gen_any_twist; } else { generators[OFFSET_CURVE] = &curve_gen_any; } + GET(metadata); if (cfg->metadata) { generators[OFFSET_METADATA] = &metadata_gen; } else { generators[OFFSET_METADATA] = &gen_skip; } + GET(points); switch (cfg->points.type) { case POINTS_RANDOM: if (cfg->points.amount) { @@ -225,12 +241,14 @@ static void exhaustive_cinit(check_t **validators) { check_t *curve_check = check_new(curve_check_nonzero, NULL); validators[OFFSET_CURVE] = curve_check; - if (cfg->hex_check) { + if (GET_BOOL(hex_check)) { check_t *hex_check = check_new(hex_check_param, NULL); validators[OFFSET_POINTS] = hex_check; } + GET(method); if (cfg->method == METHOD_SEED) { + GET(seed_algo); switch (cfg->seed_algo) { case SEED_ANSI: break; @@ -466,6 +484,7 @@ int exhaustive_do() { .check_argss = check_argss, .unrolls = unrolls}; exhaustive_init(&setup); + config_report_unused(); int result = exhaustive_generate(&setup); exhaustive_quit(&setup); debug_log_end("Finished Exhaustive method"); diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c index da2a0b3..d7433fc 100644 --- a/src/invalid/invalid.c +++ b/src/invalid/invalid.c @@ -17,7 +17,10 @@ #include "util/memory.h" static void invalid_original_ginit(gen_f *generators) { + GET(field); + generators[OFFSET_SEED] = &gen_skip; + GET(random); if (cfg->random & RANDOM_FIELD) { generators[OFFSET_FIELD] = &field_gen_random; } else { @@ -46,7 +49,7 @@ static void invalid_invalid_ginit(gen_f *generators) { generators[OFFSET_B] = &b_gen_random; generators[OFFSET_CURVE] = &curve_gen_any; generators[OFFSET_ORDER] = &order_gen_any; - if (cfg->unique) { + if (GET_BOOL(unique)) { generators[OFFSET_GENERATORS] = &gens_gen_one; } else { generators[OFFSET_GENERATORS] = &gens_gen_any; @@ -74,6 +77,7 @@ static size_t invalid_primes(GEN order, pari_ulong **primes) { pari_ulong upper = 0; size_t nprimes = 0; + GET(invalid_primes); if (cfg->invalid_primes) { char *end = NULL; last = (pari_ulong)strtol(cfg->invalid_primes, &end, 10) - 1; @@ -349,6 +353,7 @@ int invalid_do() { .check_argss = common_check_argss, .unrolls = common_unrolls}; invalid_invalid_ginit(invalid_gens); + config_report_unused(); debug_log_start("Starting to create curve to invalidate"); curve_t *curve = invalid_original_curve(&original_setup); diff --git a/src/io/cli.c b/src/io/cli.c index d6bb9e0..5307d70 100644 --- a/src/io/cli.c +++ b/src/io/cli.c @@ -226,41 +226,51 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { /* Field options */ case OPT_FP: cfg->field |= FIELD_PRIME; + SET(field); break; case OPT_F2M: cfg->field |= FIELD_BINARY; + SET(field); break; /* Generation method */ case OPT_INVALID: cfg->method |= METHOD_INVALID; + SET(method); if (arg) { size_t span = strspn(arg, "0123456789-"); if (span != strlen(arg)) { argp_failure(state, 1, 0, "Invalid range %s", arg); } cfg->invalid_primes = arg; + SET(invalid_primes); } break; case OPT_ORDER: cfg->method |= METHOD_CM; + SET(method); 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; + SET(cm_order); } break; case OPT_ANOMALOUS: cfg->method |= METHOD_ANOMALOUS; + SET(method); break; case OPT_SUPERSINGULAR: cfg->method |= METHOD_SUPERSINGULAR; + SET(method); break; case OPT_ANSI: cfg->method |= METHOD_SEED; + SET(method); cfg->seed_algo = SEED_ANSI; + SET(seed_algo); if (arg) { if (!ansi_seed_valid(arg)) { argp_failure( @@ -268,11 +278,14 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { "SEED must be at least 160 bits (40 characters)."); } cfg->seed = arg; + SET(seed); } break; case OPT_BRAINPOOL: cfg->method |= METHOD_SEED; + SET(method); cfg->seed_algo = SEED_BRAINPOOL; + SET(seed_algo); if (arg) { if (!brainpool_seed_valid(arg)) { argp_failure( @@ -280,15 +293,20 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { "SEED must be exactly 160 bits (40 hex characters)."); } cfg->seed = arg; + SET(seed); } break; case OPT_NUMS: cfg->method |= METHOD_SEED; + SET(method); cfg->seed_algo = SEED_NUMS; + SET(seed_algo); break; case OPT_BRAINPOOL_RFC: cfg->method |= METHOD_SEED; + SET(method); cfg->seed_algo = SEED_BRAINPOOL_RFC; + SET(seed_algo); if (arg) { if (!brainpool_seed_valid(arg)) { argp_failure( @@ -296,15 +314,18 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { "SEED must be exactly 160 bits (40 hex characters)."); } cfg->seed = arg; + SET(seed); } break; case OPT_TWIST: cfg->method |= METHOD_TWIST; + SET(method); break; /* Generation options */ case OPT_COUNT: cfg->count = strtoul(arg, NULL, 10); + SET(count); break; case OPT_RANDOM: if (arg) { @@ -329,22 +350,28 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { } else { cfg->random = RANDOM_ALL; } + SET(random); break; case OPT_PRIME: cfg->prime = true; + SET(prime); break; case OPT_SMOOTH: cfg->smooth = true; + SET(smooth); cfg->smooth_value = strtol(arg, NULL, 10); break; case OPT_COFACTOR: cfg->cofactor = true; + SET(cofactor); cfg->cofactor_value = strtol(arg, NULL, 10); break; case OPT_KOBLITZ: cfg->koblitz = true; + SET(koblitz); if (arg) { cfg->koblitz_value = strtol(arg, NULL, 10); + SET(koblitz_value); if (cfg->koblitz_value != 0 && cfg->koblitz_value != 1) { argp_failure(state, 1, 0, "Wrong value for a = %li", cfg->koblitz_value); @@ -353,6 +380,7 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { break; case OPT_UNIQUE: cfg->unique = true; + SET(unique); break; case OPT_HEXCHECK: { char *str_start = arg; @@ -371,10 +399,12 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { } } cfg->hex_check = str_start; + SET(hex_check); break; } case OPT_METADATA: cfg->metadata = true; + SET(metadata); break; case OPT_POINTS: { char *num_end; @@ -393,6 +423,7 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { } else { argp_failure(state, 1, 0, "Unknown point type. %s", num_end); } + SET(points); break; } /* IO options */ diff --git a/src/misc/config.c b/src/misc/config.c index 78b44ca..8beeae0 100644 --- a/src/misc/config.c +++ b/src/misc/config.c @@ -3,6 +3,95 @@ * Copyright (C) 2017-2018 J08nY */ #include "config.h" +#include <stdio.h> config_t cfg_s; -config_t *cfg = &cfg_s;
\ No newline at end of file +config_t *cfg = &cfg_s; + +config_names_t cfg_used_s = {0}; +config_names_t *cfg_used = &cfg_used_s; + +config_names_t cfg_set_s = {0}; +config_names_t *cfg_set = &cfg_set_s; + +void config_report_unused() { + if (cfg_set->field && !cfg_used->field) { + fprintf( + stderr, + "Warning: Ignored command-line argument \"field\" (--fp/--f2m).\n"); + } + if (cfg_set->method && !cfg_used->method) { + fprintf(stderr, "Warning: Ignored command-line argument method.\n"); + } + if (cfg_set->count && !cfg_used->count) { + fprintf(stderr, + "Warning: Ignored command-line argument count (-c/--count).\n"); + } + if (cfg_set->random && !cfg_used->random) { + fprintf( + stderr, + "Warning: Ignored command-line argument random (-r/--random).\n"); + } + if (cfg_set->prime && !cfg_used->prime) { + fprintf(stderr, + "Warning: Ignored command-line argument prime (-p/--prime).\n"); + } + if (cfg_set->cm_order && !cfg_used->cm_order) { + fprintf( + stderr, + "Warning: Ignored command-line argument cm_order (-n/--order).\n"); + } + if (cfg_set->koblitz && !cfg_used->koblitz) { + fprintf( + stderr, + "Warning: Ignored command-line argument koblitz (-K/--koblitz).\n"); + } + if (cfg_set->koblitz_value && !cfg_used->koblitz_value) { + fprintf(stderr, + "Warning: Ignored command-line argument koblitz_value " + "(-K/--koblitz).\n"); + } + if (cfg_set->smooth && !cfg_used->smooth) { + fprintf( + stderr, + "Warning: Ignored command-line argument smooth (-B/--smooth).\n"); + } + if (cfg_set->cofactor && !cfg_used->cofactor) { + fprintf(stderr, + "Warning: Ignored command-line argument cofactor " + "(-k/--cofactor).\n"); + } + if (cfg_set->invalid_primes && !cfg_used->invalid_primes) { + fprintf(stderr, + "Warning: Ignored command-line argument invalid_primes " + "(-i/--invalid).\n"); + } + if (cfg_set->seed_algo && !cfg_used->seed_algo) { + fprintf( + stderr, + "Warning: Ignored command-line argument seed_algo (-s/--ansi).\n"); + } + if (cfg_set->seed && !cfg_used->seed) { + fprintf(stderr, + "Warning: Ignored command-line argument seed (-s/--ansi).\n"); + } + if (cfg_set->unique && !cfg_used->unique) { + fprintf( + stderr, + "Warning: Ignored command-line argument unique (-u/--unique).\n"); + } + if (cfg_set->hex_check && !cfg_used->hex_check) { + fprintf(stderr, + "Warning: Ignored command-line argument hex_check " + "(--hex-check).\n"); + } + if (cfg_set->points && !cfg_used->points) { + fprintf(stderr, + "Warning: Ignored command-line argument points (--points).\n"); + } + if (cfg_set->metadata && !cfg_used->metadata) { + fprintf( + stderr, + "Warning: Ignored command-line argument metadata (--metadata).\n"); + } +}
\ No newline at end of file diff --git a/src/misc/config.h b/src/misc/config.h index dcdca58..0c0a5ca 100644 --- a/src/misc/config.h +++ b/src/misc/config.h @@ -142,4 +142,36 @@ typedef struct { extern config_t cfg_s; extern config_t *cfg; +typedef struct { + bool field; + bool method; + bool count; + bool random; + bool prime; + bool cm_order; + bool koblitz; + bool koblitz_value; + bool smooth; + bool cofactor; + bool invalid_primes; + bool seed_algo; + bool seed; + bool unique; + bool hex_check; + bool points; + bool metadata; +} config_names_t; + +extern config_names_t cfg_used_s; +extern config_names_t *cfg_used; + +extern config_names_t cfg_set_s; +extern config_names_t *cfg_set; + +#define GET(x) cfg_used->x = true +#define GET_BOOL(x) ((cfg_used->x = true) && cfg->x) +#define SET(x) cfg_set->x = true + +void config_report_unused(); + #endif // ECGEN_MISC_CONFIG_H |
