diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | README.md | 34 | ||||
| -rw-r--r-- | src/Makefile | 2 | ||||
| -rw-r--r-- | src/cli.c | 48 | ||||
| -rw-r--r-- | src/cli.h | 3 | ||||
| -rw-r--r-- | src/curve.c | 212 | ||||
| -rw-r--r-- | src/curve.h | 87 | ||||
| -rw-r--r-- | src/ecgen.c | 52 | ||||
| -rw-r--r-- | src/equation.c | 47 | ||||
| -rw-r--r-- | src/equation.h | 27 | ||||
| -rw-r--r-- | src/field.c | 26 | ||||
| -rw-r--r-- | src/field.h | 21 | ||||
| -rw-r--r-- | src/generators.c | 39 | ||||
| -rw-r--r-- | src/generators.h | 25 | ||||
| -rw-r--r-- | src/gp.h | 2 | ||||
| -rw-r--r-- | src/input.c | 88 | ||||
| -rw-r--r-- | src/input.h | 11 | ||||
| -rw-r--r-- | src/output.c | 5 | ||||
| -rw-r--r-- | src/output.h | 6 | ||||
| -rw-r--r-- | src/point.c | 1 | ||||
| -rw-r--r-- | src/point.h | 8 | ||||
| -rw-r--r-- | src/poly.c | 5 | ||||
| -rw-r--r-- | src/poly.h | 5 | ||||
| -rw-r--r-- | src/random.c | 26 | ||||
| -rw-r--r-- | src/random.h | 3 | ||||
| -rw-r--r-- | src/seed.c | 86 | ||||
| -rw-r--r-- | src/seed.h | 21 | ||||
| -rw-r--r-- | src/types.h | 31 |
28 files changed, 526 insertions, 397 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e53579..bb331a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ add_custom_target(gp2c ALL DEPENDS gp.c gp.h) include_directories(src) include_directories(lib) -file(GLOB SOURCES "src/*.c") +file(GLOB SOURCES "src/*.c" "src/*.h") add_executable(ecgen ${SOURCES}) @@ -6,24 +6,30 @@ Tool for generating Elliptic curve domain parameters. #### ecgen The main binary of the tool, does the hard work. -``` -ecgen --fp/--f2m -r BITS -``` - - `--fp`/`--f2m` specifies the field type(prime/binary). - - `-r` requests a random curve to be generated, currently only supported feature. - - `-o/--output FILE` writes output to `FILE`. - - `-i/--input FILE` reads input from `FILE`. - - `-a/--append` appends to output file(doesn't overwrite it). - - `-d/--datadir DIR` specifies the PARI/GP datadir containing the `seadata` package. + +` +ecgen --fp/--f2m -r -p BITS +` + + - `--fp`/`--f2m` specifies the field type (prime/binary). + - `-r/--random` requests a random curve to be generated. + - `-p/--prime` requests the curve order to be prime. + - `-s/--seed=[SEED]` requests to generate a curve based on the ANSI X9.62 generation process and seed `SEED`. + - `-o/--output=FILE` writes output to `FILE`. + - `-f/--input=FILE` reads input from `FILE`. + - `-a/--append` appends to output file (doesn't overwrite it). + - `-d/--datadir=DIR` specifies the PARI/GP datadir containing the `seadata` package. ### Build -``` + +` git clone https://github.com/J08nY/ecgen.git cd ecgen make -``` +` ### Requirements + - PARI/GP - parson @@ -34,7 +40,8 @@ additional [seadata](http://pari.math.u-bordeaux.fr/packages.html) package (sead [parson](https://github.com/kgabis/parson) is used to output curve parameters in JSON format. ### License -``` + +` This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -47,5 +54,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. -``` +` + *© Eastern Seaboard Phishing Authority* diff --git a/src/Makefile b/src/Makefile index 3a4b559..2c333ab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,7 +24,7 @@ GPC = $(addsuffix .c, $(GP)) GPO = $(addsuffix .o, $(GP)) GPH = $(addsuffix .h, $(GP)) -SRC = cli input output poly field curve random +SRC = cli input output poly field equation curve point random seed generators OBJ = $(addsuffix .o, $(SRC)) HDR = $(addsuffix .h, $(SRC)) @@ -3,6 +3,7 @@ * Copyright (C) 2017 J08nY */ #include "cli.h" +#include <string.h> char doc[] = "ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 " @@ -14,8 +15,9 @@ enum opt_keys { OPT_PRIME = 'p', OPT_RANDOM = 'r', OPT_SEED = 's', + OPT_INVALID = 'i', OPT_OUTPUT = 'o', - OPT_INPUT = 'i', + OPT_INPUT = 'f', OPT_APPEND = 'a', OPT_FP = 1, OPT_F2M = 2, @@ -29,12 +31,13 @@ struct argp_option options[] = { // Curve specification {"random", OPT_RANDOM, 0, 0, "Generate a random curve."}, {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order."}, - {"seed", OPT_SEED, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED(ANSI X9.62 verifiable procedure)."}, + {"seed", OPT_SEED, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure)."}, + {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves (for a given curve)."}, // Other - {"data-dir", OPT_DATADIR, "DIR", 0, "PARI/GP data directory (containing seadata and elldata)."}, + {"data-dir", OPT_DATADIR, "DIR", 0, "PARI/GP data directory (containing seadata package)."}, {"input", OPT_INPUT, "FILE", 0, "Input from file."}, {"output", OPT_OUTPUT, "FILE", 0, "Output into file. Overwrites any existing file!"}, - {"append", OPT_APPEND, 0, 0, "Append to output file(don't overwrite)."}, + {"append", OPT_APPEND, 0, 0, "Append to output file (don't overwrite)."}, {0}}; // clang-format on @@ -60,25 +63,26 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { case OPT_PRIME: cfg->prime = true; break; + case OPT_INVALID: + cfg->invalid = true; + break; case OPT_SEED: cfg->from_seed = true; - cfg->seed = arg; + if (arg) { + // ANSI X9.62 specifies seed as at least 160 bits in length. + if (strlen(arg) < 20) { + argp_failure( + state, 1, 0, + "SEED must be at least 160 bits(20 characters)."); + } + cfg->seed = arg; + } break; case OPT_FP: - if (cfg->binary_field) { - argp_failure( - state, 1, 0, - "Either specify prime field or binary field, not both."); - } cfg->field = FIELD_PRIME; cfg->prime_field = true; break; case OPT_F2M: - if (cfg->prime_field) { - argp_failure( - state, 1, 0, - "Either specify binary field or prime field, not both."); - } cfg->field = FIELD_BINARY; cfg->binary_field = true; break; @@ -91,10 +95,18 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { break; case ARGP_KEY_END: // validate all option states here. + // Only one field if (!cfg->prime_field && !cfg->binary_field) { - argp_failure( - state, 1, 0, - "Specify field type, prime or binary, with --fp / --f2m."); + argp_failure(state, 1, 0, + "Specify field type, prime or binary, with --fp / " + "--f2m(but not both)."); + } + // Invalid is not prime or seed or random by definition. + if (cfg->invalid && (cfg->prime || cfg->from_seed || cfg->random)) { + // not seed, not prime + argp_failure(state, 1, 0, + "Invalid curve generation can not generate curves " + "from seed, random or prime order."); } break; case ARGP_KEY_NO_ARGS: @@ -13,7 +13,7 @@ extern char doc[]; extern char args_doc[]; extern struct argp_option options[]; -enum field_e { FIELD_PRIME, FIELD_BINARY } ; +enum field_e { FIELD_PRIME, FIELD_BINARY }; typedef struct config_t { enum field_e field; @@ -21,6 +21,7 @@ typedef struct config_t { bool prime_field; bool random; bool prime; + bool invalid; bool from_seed; char *seed; char *datadir; diff --git a/src/curve.c b/src/curve.c index 7c3ae9d..812f688 100644 --- a/src/curve.c +++ b/src/curve.c @@ -3,9 +3,11 @@ * Copyright (C) 2017 J08nY */ #include "curve.h" +#include "field.h" +#include "seed.h" -curve_t *new_curve() { - curve_t *curve = malloc(sizeof(curve_t)); +curve_t *curve_new() { + curve_t *curve = pari_malloc(sizeof(curve_t)); if (!curve) { perror("Couldn't malloc."); exit(1); @@ -14,197 +16,99 @@ curve_t *new_curve() { return curve; } -void free_curve(curve_t **curve) { +void curve_free(curve_t **curve) { if (*curve) { - free((*curve)->points); - free(*curve); + seed_free(&(*curve)->seed); + pari_free((*curve)->points); + pari_free(*curve); *curve = NULL; } } -curve_t *curve_random(GEN field) { - curve_t *result = new_curve(); +int curve_init(curve_t *curve, config_t *config) { pari_sp ltop = avma; - - GEN curve, a, b; - a = genrand(field); - b = genrand(field); - GEN v = gen_0; - switch (typ(field)) { + switch (typ(curve->field)) { case t_INT: v = gtovec0(gen_0, 2); - gel(v, 1) = a; - gel(v, 2) = b; + gel(v, 1) = curve->a; + gel(v, 2) = curve->b; break; case t_FFELT: v = gtovec0(gen_0, 5); gel(v, 1) = gen_1; - gel(v, 4) = a; - gel(v, 5) = b; + gel(v, 4) = curve->a; + gel(v, 5) = curve->b; break; default: - pari_err_TYPE("curve_random", field); + pari_err_TYPE("curve_init", curve->field); } - curve = ellinit(v, field, -1); - - result->field = field; - gerepileall(ltop, 3, &a, &b, &curve); - result->a = a; - result->b = b; - result->curve = curve; - return result; -} -curve_t *curve_randomf(enum field_e t, long bits) { - GEN field = field_random(t, bits); - return curve_random(field); + curve->curve = gerepilecopy(ltop, ellinit(v, curve->field, -1)); + return 1; } -curve_t *curve_nonzero(GEN field) { +int curve_nonzero(curve_t *curve, config_t *config) { pari_sp ltop = avma; - - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - result = curve_random(field); - } while (gequal0(ell_get_disc(result->curve))); - - return result; -} - -curve_t *curve_nonzerof(enum field_e t, long bits) { - pari_sp ltop = avma; - - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - result = curve_randomf(t, bits); - } while(gequal0(ell_get_disc(result->curve))); - - return result; -} - -curve_t *curve_prime(GEN field) { - pari_sp ltop = avma; - - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - result = curve_nonzero(field); - result->order = ellsea(result->curve, 1); - } while (gequal0(result->order) || !isprime(result->order)); - - return result; + curve_init(curve, config); + if (gequal0(ell_get_disc(curve->curve))) { + avma = ltop; + return -3; + } else { + return 1; + } } -curve_t *curve_primef(enum field_e t, long bits) { +int curve_prime(curve_t *curve, config_t *config) { pari_sp ltop = avma; - - curve_t *result = NULL; - do { - if (result) { + int nonzero = curve_nonzero(curve, config); + if (nonzero == 1) { + curve->order = ellsea(curve->curve, 1); + if (gequal0(curve->order) || !(isprime(curve->order))) { avma = ltop; - free_curve(&result); + return -3; + } else { + return 1; } - result = curve_nonzerof(t, bits); - result->order = ellsea(result->curve, 1); - } while (gequal0(result->order) || !isprime(result->order)); - - return result; + } else { + avma = ltop; + return nonzero; + } } -GEN curve_invalid(GEN field, GEN a, GEN b) { - return gen_m1; -} +int curve_seed_fp(curve_t *curve, config_t *config) {} -curve_t *curve_seed_Fp(GEN field, GEN seed) { - return NULL; -} +int curve_seed_f2m(curve_t *curve, config_t *config) {} -curve_t *curve_seed_F2m(GEN field, GEN seed) { - return NULL; -} - -curve_t *curve_seed(GEN field, GEN seed) { - switch (typ(field)) { +int curve_seed(curve_t *curve, config_t *config) { + switch (typ(curve->field)) { case t_INT: - return curve_seed_Fp(field, seed); + return curve_seed_fp(curve, config); case t_FFELT: - return curve_seed_F2m(field, seed); + return curve_seed_f2m(curve, config); default: - pari_err_TYPE("curve_seed", field); - return NULL; /* NOT REACHED */ + pari_err_TYPE("curve_seed", curve->field); + return 0; /* NOT REACHABLE */ } } -curve_t *curve_seedr(GEN field) { - pari_sp ltop = avma; - - GEN seed; - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - seed = random_int(160); - result = curve_seed(field, seed); - } while(gequal0(ell_get_disc(result->curve))); - - return result; -} - -curve_t *curve_seedf(GEN seed, enum field_e t, long bits) { - pari_sp ltop = avma; - - GEN field; - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - field = field_random(t, bits); - result = curve_seed(field, seed); - } while(gequal0(ell_get_disc(result->curve))); - - return result; -} - -curve_t *curve_seedrf(enum field_e t, long bits) { - pari_sp ltop = avma; - - GEN seed, field; - curve_t *result = NULL; - do { - if (result) { - avma = ltop; - free_curve(&result); - } - seed = random_int(160); - field = field_random(t, bits); - result = curve_seed(field, seed); - } while(gequal0(ell_get_disc(result->curve))); - - return result; +int curve_g(curve_t *curve, config_t *config) { + if (config->from_seed) { + return curve_seed(curve, config); + } else if (config->prime) { + return curve_prime(curve, config); + } else { + return curve_nonzero(curve, config); + } } GEN curve_params(curve_t *curve) { pari_sp ltop = avma; - GEN field = field_params(curve->field); - GEN a = gtovec(field_elementi(curve->a)); - GEN b = gtovec(field_elementi(curve->b)); + GEN result = field_params(curve->field); + if (curve->a) result = gconcat(result, field_elementi(curve->a)); + if (curve->b) result = gconcat(result, field_elementi(curve->b)); + if (curve->order) result = gconcat(result, gtovec(curve->order)); - return gerepilecopy(ltop, gconcat(gconcat(field, a), b)); + return gerepilecopy(ltop, result); } diff --git a/src/curve.h b/src/curve.h index 5002f45..e4e973c 100644 --- a/src/curve.h +++ b/src/curve.h @@ -6,110 +6,65 @@ #define ECGEN_CURVE_H #include <pari/pari.h> -#include "field.h" -#include "point.h" - -typedef struct curve_t { - GEN seed; - GEN field; - GEN a; - GEN b; - GEN curve; - GEN order; - point_t **points; - size_t npoints; -} curve_t; - -/** - * - * @param field - * @return - */ -curve_t *curve_random(GEN field); - -/** - * - * @param t - * @param bits - * @return - */ -curve_t *curve_randomf(enum field_e t, long bits); - -/** - * - * @param field - * @return - */ -curve_t *curve_nonzero(GEN field); +#include "cli.h" +#include "types.h" /** * - * @param t - * @param bits - * @return - */ -curve_t *curve_nonzerof(enum field_e t, long bits); - -/** - * - * @param field + * @param curve + * @param config * @return */ -curve_t *curve_prime(GEN field); +int curve_init(curve_t *curve, config_t *config); /** * - * @param t - * @param bits + * @param curve + * @param config * @return */ -curve_t *curve_primef(enum field_e t, long bits); +int curve_nonzero(curve_t *curve, config_t *config); /** - * ANSI X9.62 Verifiable random curve over field with seed. * - * @param field - * @param seed + * @param curve + * @param config * @return */ -curve_t *curve_seed(GEN field, GEN seed); +int curve_prime(curve_t *curve, config_t *config); /** * - * @param field + * @param curve + * @param config * @return */ -curve_t *curve_seedr(GEN field); +int curve_seed(curve_t *curve, config_t *config); /** * - * @param seed - * @param t - * @param bits + * @param curve + * @param config * @return */ -curve_t *curve_seedf(GEN seed, enum field_e t, long bits); +int curve_g(curve_t *curve, config_t *config); /** - * - * @param t - * @param bits + * @param curve * @return */ -curve_t *curve_seedrf(enum field_e t, long bits); +GEN curve_params(curve_t *curve); /** * - * @param curve * @return */ -GEN curve_params(curve_t *curve); +curve_t *curve_new(); /** * * @param curve */ -void free_curve(curve_t **curve); - +void curve_free(curve_t **curve); #endif // ECGEN_CURVE_H diff --git a/src/ecgen.c b/src/ecgen.c index 320cd0b..5f73c7e 100644 --- a/src/ecgen.c +++ b/src/ecgen.c @@ -24,10 +24,13 @@ */ #include <time.h> -#include "cli.h" #include "curve.h" -#include "output.h" +#include "equation.h" +#include "field.h" +#include "generators.h" #include "input.h" +#include "output.h" +#include "seed.h" const char *argp_program_version = "ecgen 0.2\n" @@ -40,34 +43,13 @@ const char *argp_program_bug_address = "<johny@neuromancer.sk>"; static struct argp argp = {options, parse_opt, args_doc, doc}; static struct config_t cfg; -static FILE *in; -static FILE *out; bool init() { // Init PARI, 1GB stack, 1M primes pari_init(1000000000, 1000000); // Init PARI PRNG - pari_ulong seed = 0; - // Try urandom first - FILE *rand = fopen("/dev/urandom", "rb"); - if (rand) { - fread(&seed, sizeof(char), sizeof(pari_ulong), rand); - fclose(rand); - } - // Try worse methods later - if (seed == 0) { - struct timespec t; - if (!clock_gettime(CLOCK_REALTIME, &t)) { - seed = (pari_ulong)t.tv_nsec; - } else { - seed = (pari_ulong)time(NULL); - } - } - - pari_sp ltop = avma; - setrand(utoi(seed)); - avma = ltop; + if (!random_init()) return false; // set datadir if specified if (cfg.datadir) { @@ -101,21 +83,17 @@ int main(int argc, char *argv[]) { return quit(1); } - if (cfg.random) { - curve_t *curve; - if (cfg.prime) { - curve = curve_primef(cfg.field, cfg.bits); - } else { - curve = curve_nonzerof(cfg.field, cfg.bits); - } - - output_csv(out, "%Px", ',', curve_params(curve)); - - free_curve(&curve); + gen_t generators[5]; + gen_init(generators, &cfg); - } else { - fprintf(stderr, "Currently unsupported."); + curve_t *curve = curve_new(); + int state = 0; + while (state != 5) { + int diff = generators[state](curve, &cfg); + state += diff; } + output_csv(out, "%Px", ';', curve_params(curve)); + curve_free(&curve); return quit(0); } diff --git a/src/equation.c b/src/equation.c new file mode 100644 index 0000000..d7fa63c --- /dev/null +++ b/src/equation.c @@ -0,0 +1,47 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "equation.h" + +int eq_random(curve_t *curve, config_t *config) { + int r = a_random(curve, config) + b_random(curve, config); + if (r == 2) { + return r; + } + return -1; +} + +int a_random(curve_t *curve, config_t *config) { + curve->a = genrand(curve->field); + return 1; +} + +int a_zero(curve_t *curve, config_t *config) { + curve->a = gen_0; + return 1; +} + +int a_one(curve_t *curve, config_t *config) { + curve->a = gen_1; + return 1; +} + +int a_seed(curve_t *curve, config_t *config) {} + +int b_random(curve_t *curve, config_t *config) { + curve->b = genrand(curve->field); + return 1; +} + +int b_zero(curve_t *curve, config_t *config) { + curve->b = gen_0; + return 1; +} + +int b_one(curve_t *curve, config_t *config) { + curve->b = gen_1; + return 1; +} + +int b_seed(curve_t *curve, config_t *config) {} diff --git a/src/equation.h b/src/equation.h new file mode 100644 index 0000000..7acb7d0 --- /dev/null +++ b/src/equation.h @@ -0,0 +1,27 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_EQUATION_H +#define ECGEN_EQUATION_H + +#include "cli.h" +#include "types.h" + +int a_random(curve_t *curve, config_t *config); + +int a_zero(curve_t *curve, config_t *config); + +int a_one(curve_t *curve, config_t *config); + +int a_seed(curve_t *curve, config_t *config); + +int b_random(curve_t *curve, config_t *config); + +int b_zero(curve_t *curve, config_t *config); + +int b_one(curve_t *curve, config_t *config); + +int b_seed(curve_t *curve, config_t *config); + +#endif // ECGEN_EQUATION_H diff --git a/src/field.c b/src/field.c index c2cfdf8..f761b8f 100644 --- a/src/field.c +++ b/src/field.c @@ -3,6 +3,8 @@ * Copyright (C) 2017 J08nY */ #include "field.h" +#include "poly.h" +#include "random.h" GEN field_primer(long bits) { return random_prime(bits); } @@ -16,17 +18,23 @@ GEN field_binaryr(long bits) { } } -GEN field_random(enum field_e t, long bits) { - switch(t) { +int field_random(curve_t *curve, config_t *config) { + switch (config->field) { case FIELD_PRIME: - return field_primer(bits); + curve->field = field_primer(config->bits); + return 1; case FIELD_BINARY: - return field_binaryr(bits); + curve->field = field_binaryr(config->bits); + return 1; default: - return gen_0; /* NOT REACHABLE */ + return 0; /* NOT REACHABLE */ } } +int field_input(curve_t *curve, config_t *config) { + return -1; // NOT IMPLEMENTED +} + GEN field_params(GEN field) { pari_sp ltop = avma; @@ -42,13 +50,13 @@ GEN field_params(GEN field) { long l2 = glength(member_mod(field)) - 2; { pari_sp btop = avma; - for (GEN i = gen_1; gcmpgs(i, l2) <= 0; i = gaddgs(i, 1)) { - GEN c = polcoeff0(member_mod(field), gtos(i), -1); + for (long i = 0; i <= l2; ++i) { + GEN c = polcoeff0(member_mod(field), i, -1); if (cmpis(c, 0) != 0) { - gel(out, j) = gcopy(i); + gel(out, j) = stoi(i); j++; } - if (gc_needed(btop, 1)) gerepileall(btop, 4, &out, &c, &i); + if (gc_needed(btop, 1)) gerepileall(btop, 3, &out, &c); } } return gerepilecopy(ltop, out); diff --git a/src/field.h b/src/field.h index e09ea62..f7adca1 100644 --- a/src/field.h +++ b/src/field.h @@ -5,31 +5,24 @@ #ifndef ECGEN_FIELD_H #define ECGEN_FIELD_H -#include "poly.h" -#include "random.h" #include "cli.h" +#include "types.h" /** * - * @param bits + * @param curve + * @param config * @return */ -GEN field_primer(long bits); +int field_random(curve_t *curve, config_t *config); /** * - * @param bits + * @param curve + * @param config * @return */ -GEN field_binaryr(long bits); - -/** - * - * @param t - * @param bits - * @return - */ -GEN field_random(enum field_e t, long bits); +int field_input(curve_t *curve, config_t *config); /** * Extract a field representation from a field. diff --git a/src/generators.c b/src/generators.c new file mode 100644 index 0000000..79320f2 --- /dev/null +++ b/src/generators.c @@ -0,0 +1,39 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "generators.h" +#include "curve.h" +#include "equation.h" +#include "field.h" +#include "seed.h" + +int gen_skip(curve_t *curve, config_t *config) { return 1; } + +void gen_init(gen_t generators[], config_t *config) { + if (config->from_seed) { + if (config->seed) { + generators[OFFSET_SEED] = &seed_argument; + } else { + if (config->random) { + generators[OFFSET_SEED] = &seed_random; + } else { + generators[OFFSET_SEED] = &seed_input; + } + } + generators[OFFSET_A] = &a_seed; + generators[OFFSET_B] = &b_seed; + generators[OFFSET_CURVE] = &curve_seed; + } else { + generators[OFFSET_SEED] = &gen_skip; + generators[OFFSET_A] = &a_random; + generators[OFFSET_B] = &b_random; + if (config->prime) { + generators[OFFSET_CURVE] = &curve_prime; + } else { + generators[OFFSET_CURVE] = &curve_nonzero; + } + } + + generators[OFFSET_FIELD] = &field_random; +}
\ No newline at end of file diff --git a/src/generators.h b/src/generators.h new file mode 100644 index 0000000..87e599b --- /dev/null +++ b/src/generators.h @@ -0,0 +1,25 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_GENERATORS_H +#define ECGEN_GENERATORS_H + +#include "types.h" + +enum gen_offset { + OFFSET_SEED, + OFFSET_FIELD, + OFFSET_A, + OFFSET_B, + OFFSET_CURVE, + OFFSET_POINTS +}; + +/** + * + * @param generators + */ +void gen_init(gen_t generators[], config_t *config); + +#endif // ECGEN_GENERATORS_H @@ -11,4 +11,4 @@ GP;install("init_gp","v","init_gp","./gp/gp.gp.so"); */ void init_gp(void); /*End of prototype*/ -#endif //GP_H +#endif // GP_H diff --git a/src/input.c b/src/input.c index e49eae6..beff9e5 100644 --- a/src/input.c +++ b/src/input.c @@ -4,72 +4,13 @@ */ #include "input.h" -/* - * - *char *prime_prompts[] = {"p:", "a:", "b:"}; - param_t prime_params[] = {PARAM_PRIME, PARAM_INT, PARAM_INT}; - - char *binary_prompts[] = {"e1:", "e2:", "e3:", "a:", "b:"}; - param_t binary_params[] = {PARAM_SHORT, PARAM_SHORT, PARAM_SHORT, PARAM_INT, - PARAM_INT}; - - char **prompts; - param_t *params; - size_t length; - if (cfg.prime_field) { - prompts = prime_prompts; - params = prime_params; - length = 3; - } else { - prompts = binary_prompts; - params = binary_params; - length = 5; - } - GEN field; - GEN domain[length]; - - if (cfg.random) { - //random domain, might not define a curve... check disc - if (cfg.prime_field) { - field = ifield_prime(cfg.bits); - } else { - field = ifield_binary(cfg.bits); - } - } else { - for (size_t i = 0; i < length; ++i) { - domain[i] = fread_param(params[i], in, prompts[i], cfg.bits, in == - stdin ? '\n' : ','); - if (equalii(domain[i], gen_m1)) { - fprintf(stderr, "Whoops?"); - return quit(1); - } - } - if (cfg.prime_field) { - field = field_prime(domain[0]); - } else { - field = field_binary(cfg.bits, domain[0], domain[1], domain[2]); - } - } - pari_fprintf(out, "%Ps", field_params(field)); - - if (cfg.prime_field) { - GEN field = prime_field(p); - GEN curve = prime_weierstrass(a, b, field, 0); - } else if (cfg.binary_field) { - GEN e[3]; - for (size_t i = 0; i < 3; ++i) { - char prompt[] = {'e', (char) ('1' + i), ':', 0}; - e[i] = read_short(prompt, '\n'); - } - GEN a = read_int("a:", cfg.bits, '\n'); - - GEN field = binary_field(cfg.bits, e[0], e[1], e[2]); - } -*/ +FILE *in; GEN fread_i(FILE *stream, const char *prompt, long bits, int delim, GEN (*rand_func)(long)) { - printf("%s ", prompt); + if (prompt) { + printf("%s ", prompt); + } char *line = NULL; size_t n = 0; @@ -118,6 +59,25 @@ GEN fread_short(FILE *stream, const char *prompt, int delim) { return fread_i(stream, prompt, 16, delim, NULL); } +GEN fread_string(FILE *stream, const char *prompt, int delim) { + if (prompt) { + printf("%s ", prompt); + } + char *line = NULL; + size_t n = 0; + + ssize_t len = getdelim(&line, &n, delim, stream); + if (len == 1) { + free(line); + return strtoGENstr(""); + } + + line[len - 1] = 0; + GEN result = strtoGENstr(line); + free(line); + return result; +} + GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, int delim) { switch (param) { @@ -127,6 +87,8 @@ GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, return fread_int(stream, prompt, bits, delim); case PARAM_SHORT: return fread_short(stream, prompt, delim); + case PARAM_STRING: + return fread_string(stream, prompt, delim); } return gen_m1; } diff --git a/src/input.h b/src/input.h index ead8baa..21b8393 100644 --- a/src/input.h +++ b/src/input.h @@ -7,7 +7,12 @@ #include "random.h" -typedef enum PARAM { PARAM_PRIME, PARAM_INT, PARAM_SHORT } param_t; +typedef enum PARAM { + PARAM_PRIME, + PARAM_INT, + PARAM_SHORT, + PARAM_STRING +} param_t; /** * @@ -38,11 +43,15 @@ GEN fread_int(FILE *stream, const char *prompt, long bits, int delim); */ GEN fread_short(FILE *stream, const char *prompt, int delim); +GEN fread_string(FILE *stream, const char *prompt, int delim); + GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, int delim); GEN read_param(param_t param, const char *prompt, long bits, int delim); +extern FILE *in; + FILE *input_open(const char *input); void input_close(FILE *in); diff --git a/src/output.c b/src/output.c index adeda58..e6dc120 100644 --- a/src/output.c +++ b/src/output.c @@ -5,6 +5,8 @@ #include "output.h" +FILE *out; + char *output_scsv(const char *format, char delim, GEN vector) { long len = lg(vector) - 1; char *params[len]; @@ -44,8 +46,7 @@ void output_csv(FILE *out, const char *format, char delim, GEN vector) { free(string); } -char *output_sjson(GEN vector) { -} +char *output_sjson(GEN vector) {} void output_json(FILE *out, GEN vector) {} diff --git a/src/output.h b/src/output.h index f45aa50..121a74f 100644 --- a/src/output.h +++ b/src/output.h @@ -5,9 +5,9 @@ #ifndef ECGEN_OUTPUT_H #define ECGEN_OUTPUT_H -#include <stdbool.h> -#include <parson/parson.h> #include <pari/pari.h> +#include <parson/parson.h> +#include <stdbool.h> /** * @@ -41,6 +41,8 @@ char *output_sjson(GEN vector); */ void output_json(FILE *out, GEN vector); +extern FILE *out; + FILE *output_open(const char *output, bool append); void output_close(FILE *out); diff --git a/src/point.c b/src/point.c index 8fa1007..a5a1c69 100644 --- a/src/point.c +++ b/src/point.c @@ -4,7 +4,6 @@ */ #include "point.h" - point_t *gerepile_point(pari_sp ltop, point_t *point) { if (point) { gerepileall(ltop, 2, &point->point, &point->order); diff --git a/src/point.h b/src/point.h index 710c3ce..3b69144 100644 --- a/src/point.h +++ b/src/point.h @@ -6,12 +6,8 @@ #define ECGEN_POINT_H #include <pari/pari.h> - -typedef struct point_t { - GEN point; - GEN order; -} point_t; +#include "types.h" point_t *gerepile_point(pari_sp ltop, point_t *point); -#endif //ECGEN_POINT_H +#endif // ECGEN_POINT_H @@ -3,9 +3,8 @@ * Copyright (C) 2017 J08nY */ #include "poly.h" -#include <stdlib.h> -polynomial_t ansi_trinomials[] = { +static polynomial_t ansi_trinomials[] = { {161, 18}, {162, 27}, {166, 37}, {167, 6}, {169, 34}, {170, 11}, {172, 1}, {174, 13}, {175, 6}, {177, 8}, {178, 31}, {180, 3}, {182, 81}, {183, 56}, {185, 24}, @@ -199,7 +198,7 @@ polynomial_t ansi_trinomials[] = { {1988, 555}, {1990, 133}, {1991, 546}, {1993, 103}, {1994, 15}, {1996, 307}, {1999, 367}}; -polynomial_t ansi_pentanomials[] = { +static polynomial_t ansi_pentanomials[] = { {160, 1, 2, 117}, {163, 1, 2, 8}, {164, 1, 2, 49}, {165, 1, 2, 25}, {168, 1, 2, 65}, {171, 1, 3, 42}, {173, 1, 2, 10}, {176, 1, 2, 43}, {179, 1, 2, 4}, @@ -5,8 +5,8 @@ #ifndef ECGEN_POLY_H #define ECGEN_POLY_H -#include <stdbool.h> #include <pari/pari.h> +#include <stdbool.h> typedef struct polynomial { int m; @@ -15,9 +15,6 @@ typedef struct polynomial { int e3; } polynomial_t; -extern polynomial_t ansi_trinomials[]; -extern polynomial_t ansi_pentanomials[]; - /** * * @param m diff --git a/src/random.c b/src/random.c index eaa1a7c..319ed3c 100644 --- a/src/random.c +++ b/src/random.c @@ -3,6 +3,32 @@ * Copyright (C) 2017 J08nY */ #include "random.h" +#include <time.h> + +bool random_init() { + pari_ulong seed = 0; + // Try urandom first + FILE *rand = fopen("/dev/urandom", "rb"); + if (rand) { + fread(&seed, sizeof(char), sizeof(pari_ulong), rand); + fclose(rand); + } + // Try worse methods later + if (seed == 0) { + struct timespec t; + if (!clock_gettime(CLOCK_REALTIME, &t)) { + seed = (pari_ulong)t.tv_nsec; + } else { + seed = (pari_ulong)time(NULL); + } + } + + pari_sp ltop = avma; + setrand(utoi(seed)); + avma = ltop; + + return true; +} GEN random_prime(long bits) { pari_sp ltop = avma; diff --git a/src/random.h b/src/random.h index 9faa946..5d3d17f 100644 --- a/src/random.h +++ b/src/random.h @@ -6,6 +6,9 @@ #define ECGEN_RANDOM_H #include <pari/pari.h> +#include <stdbool.h> + +bool random_init(); GEN random_prime(long bits); diff --git a/src/seed.c b/src/seed.c new file mode 100644 index 0000000..411195f --- /dev/null +++ b/src/seed.c @@ -0,0 +1,86 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "seed.h" +#include "input.h" + +seed_t *seed_new() { + seed_t *seed = pari_malloc(sizeof(seed_t)); + if (!seed) { + perror("Couldn't malloc."); + exit(1); + } + memset(seed, 0, sizeof(seed_t)); + return seed; +} + +void seed_free(seed_t **seed) { + if (*seed) { + pari_free(*seed); + *seed = NULL; + } +} + +GEN seed_stoi(const char *cstr) { + pari_sp ltop = avma; + GEN seed = gen_0; + + size_t len = strlen(cstr); + for (size_t i = 0; i < len; ++i) { + pari_sp btop = avma; + GEN s = stoi(cstr[i]); + s = shifti(s, (len - i - 1) * 8); + seed = addii(seed, s); + if (gc_needed(btop, 1)) gerepileall(btop, 1, seed); + } + + return gerepilecopy(ltop, seed); +} + +int seed_random(curve_t *curve, config_t *config) { + curve->seed = seed_new(); + curve->seed->seed = random_int(160); + return 1; +} + +int seed_argument(curve_t *curve, config_t *config) { + curve->seed = seed_new(); + curve->seed->seed = seed_stoi(config->seed); + return 1; +} + +int seed_input(curve_t *curve, config_t *config) { + pari_sp ltop = avma; + + GEN str = fread_string(in, "seed:", '\n'); + const char *cstr = GSTR(str); + if (strlen(cstr) < 20) { + fprintf(stderr, "SEED must be at least 160 bits(20 characters).\n"); + avma = ltop; + return 0; + } + + GEN seed = seed_stoi(cstr); + gerepileall(ltop, 1, &seed); + + curve->seed = seed_new(); + curve->seed->seed = seed; + return 1; +} + +int seed_g(curve_t *curve, config_t *config) { + if (config->from_seed) { + if (config->seed) { + return seed_argument(curve, config); + } else { + if (config->random) { + return seed_random(curve, config); + } else { + return seed_input(curve, config); + } + } + } else { + return 1; // seed none.. skip + } +}
\ No newline at end of file diff --git a/src/seed.h b/src/seed.h new file mode 100644 index 0000000..bb2b834 --- /dev/null +++ b/src/seed.h @@ -0,0 +1,21 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_SEED_H +#define ECGEN_SEED_H + +#include "cli.h" +#include "types.h" + +void seed_free(seed_t **seed); + +int seed_random(curve_t *curve, config_t *config); + +int seed_argument(curve_t *curve, config_t *config); + +int seed_input(curve_t *curve, config_t *config); + +int seed_g(curve_t *curve, config_t *config); + +#endif // ECGEN_SEED_H diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..883dc50 --- /dev/null +++ b/src/types.h @@ -0,0 +1,31 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_TYPES_H +#define ECGEN_TYPES_H + +#include <pari/pari.h> +#include "cli.h" + +typedef struct seed { GEN seed; } seed_t; + +typedef struct point_t { + GEN point; + GEN order; +} point_t; + +typedef struct curve { + seed_t *seed; + GEN field; + GEN a; + GEN b; + GEN curve; + GEN order; + point_t **points; + size_t npoints; +} curve_t; + +typedef int (*gen_t)(curve_t *, config_t *); + +#endif // ECGEN_TYPES_H |
