diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 19 | ||||
| -rw-r--r-- | src/cli.c | 76 | ||||
| -rw-r--r-- | src/cli.h | 13 | ||||
| -rw-r--r-- | src/curve.c | 219 | ||||
| -rw-r--r-- | src/curve.h | 109 | ||||
| -rw-r--r-- | src/ecgen.c | 93 | ||||
| -rw-r--r-- | src/field.c | 29 | ||||
| -rw-r--r-- | src/field.h | 21 | ||||
| -rw-r--r-- | src/gp.c | 199 | ||||
| -rw-r--r-- | src/gp.h | 14 | ||||
| -rw-r--r-- | src/gp/gp.gp | 4 | ||||
| -rw-r--r-- | src/gp/utils.gp | 33 | ||||
| -rw-r--r-- | src/input.c | 129 | ||||
| -rw-r--r-- | src/input.h | 17 | ||||
| -rw-r--r-- | src/output.c | 44 | ||||
| -rw-r--r-- | src/output.h | 42 | ||||
| -rw-r--r-- | src/point.c | 13 | ||||
| -rw-r--r-- | src/point.h | 17 | ||||
| -rw-r--r-- | src/poly.h | 4 | ||||
| -rw-r--r-- | src/random.c | 34 | ||||
| -rw-r--r-- | src/random.h | 14 |
21 files changed, 672 insertions, 471 deletions
diff --git a/src/Makefile b/src/Makefile index 6e4726a..3a4b559 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,22 +9,22 @@ CC=gcc GP2C=gp2c CFLAGS=-O3 -Wall -LDFLAGS= +LDFLAGS=-L../lib GP_CFLAGS=-O3 -Wall -fomit-frame-pointer -fno-strict-aliasing -fPIC GPFLAGS=-g -i4 -INCLUDES=-I. -LIBS=-lpari +INCLUDES=-I. -I../lib +LIBS=-lpari -lparson #### -GP = gp +GP = GPC = $(addsuffix .c, $(GP)) GPO = $(addsuffix .o, $(GP)) GPH = $(addsuffix .h, $(GP)) -SRC = cli input +SRC = cli input output poly field curve random OBJ = $(addsuffix .o, $(SRC)) HDR = $(addsuffix .h, $(SRC)) @@ -48,8 +48,6 @@ $(GPO): $(GPC) $(GPH) #### -.PHONY: all gp2c clean-all clean clean-gp help - clean-all: clean clean-gp clean: @@ -70,3 +68,10 @@ help: @echo " - clean : cleans up after a build" @echo " - clean-gp : cleans up after gp2c generation" @echo " - clean-all : cleans all" + @echo " - format : run clang-format on source files" + +format: + clang-format -i *.c + clang-format -i *.h + +.PHONY: all gp2c clean-all clean clean-gp help format
\ No newline at end of file @@ -4,87 +4,97 @@ */ #include "cli.h" -char doc[] = "ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 Eastern Seaboard Phishing Authority"; +char doc[] = + "ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 " + "Eastern Seaboard Phishing Authority"; char args_doc[] = "bits"; enum opt_keys { OPT_DATADIR = 'd', - OPT_APPEND = 'a', OPT_PRIME = 'p', + OPT_RANDOM = 'r', + OPT_SEED = 's', OPT_OUTPUT = 'o', OPT_INPUT = 'i', - OPT_RANDOM = 'r', + OPT_APPEND = 'a', OPT_FP = 1, OPT_F2M = 2, }; +// clang-format off struct argp_option options[] = { // Field specification - {"fp", OPT_FP, 0, 0, "Prime field."}, - {"f2m", OPT_F2M, 0, 0, "Binary field."}, + {"fp", OPT_FP, 0, 0, "Prime field."}, + {"f2m", OPT_F2M, 0, 0, "Binary field."}, // Curve specification - {"random", OPT_RANDOM, 0, 0, "Generate a random curve."}, - {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order."}, + {"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)."}, // Other - {"data-dir", OPT_DATADIR, "DIR", 0, - "PARI/GP data directory (containing seadata and elldata)."}, - {"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)."}, + {"data-dir", OPT_DATADIR, "DIR", 0, "PARI/GP data directory (containing seadata and elldata)."}, + {"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)."}, {0}}; +// clang-format on error_t parse_opt(int key, char *arg, struct argp_state *state) { - struct arguments *args = state->input; + struct config_t *cfg = state->input; switch (key) { case OPT_DATADIR: - args->datadir = arg; + cfg->datadir = arg; break; case OPT_INPUT: - args->input = arg; + cfg->input = arg; break; case OPT_OUTPUT: - args->output = arg; + cfg->output = arg; break; case OPT_APPEND: - args->append = true; + cfg->append = true; break; case OPT_RANDOM: - args->random = true; + cfg->random = true; break; case OPT_PRIME: - args->prime = true; + cfg->prime = true; + break; + case OPT_SEED: + cfg->from_seed = true; + cfg->seed = arg; break; case OPT_FP: - if (args->binary_field) { + if (cfg->binary_field) { argp_failure( - state, 1, 0, - "Either specify prime field or binary field, not both."); + state, 1, 0, + "Either specify prime field or binary field, not both."); } - args->field = FIELD_PRIME; - args->prime_field = true; + cfg->field = FIELD_PRIME; + cfg->prime_field = true; break; case OPT_F2M: - if (args->prime_field) { + if (cfg->prime_field) { argp_failure( - state, 1, 0, - "Either specify binary field or prime field, not both."); + state, 1, 0, + "Either specify binary field or prime field, not both."); } - args->field = FIELD_BINARY; - args->binary_field = true; + cfg->field = FIELD_BINARY; + cfg->binary_field = true; break; case ARGP_KEY_ARG: if (state->arg_num >= 1) { argp_usage(state); } - args->bits = strtol(arg, NULL, 10); + cfg->bits = strtol(arg, NULL, 10); break; case ARGP_KEY_END: - if (!args->prime_field && !args->binary_field) { + // validate all option states here. + if (!cfg->prime_field && !cfg->binary_field) { argp_failure( - state, 1, 0, - "Specify field type, prime or binary, with --fp / --f2m."); + state, 1, 0, + "Specify field type, prime or binary, with --fp / --f2m."); } break; case ARGP_KEY_NO_ARGS: @@ -13,23 +13,22 @@ extern char doc[]; extern char args_doc[]; extern struct argp_option options[]; -typedef enum { - FIELD_PRIME, - FIELD_BINARY -} field_t; +enum field_e { FIELD_PRIME, FIELD_BINARY } ; -struct arguments { - field_t field; +typedef struct config_t { + enum field_e field; bool binary_field; bool prime_field; bool random; bool prime; + bool from_seed; + char *seed; char *datadir; char *output; char *input; bool append; long bits; -}; +} config_t; error_t parse_opt(int key, char *arg, struct argp_state *state); diff --git a/src/curve.c b/src/curve.c index 0d15ccf..7c3ae9d 100644 --- a/src/curve.c +++ b/src/curve.c @@ -4,32 +4,207 @@ */ #include "curve.h" -GEN curve_random(GEN field) { +curve_t *new_curve() { + curve_t *curve = malloc(sizeof(curve_t)); + if (!curve) { + perror("Couldn't malloc."); + exit(1); + } + memset(curve, 0, sizeof(curve_t)); + return curve; +} + +void free_curve(curve_t **curve) { + if (*curve) { + free((*curve)->points); + free(*curve); + *curve = NULL; + } +} + +curve_t *curve_random(GEN field) { + curve_t *result = new_curve(); + pari_sp ltop = avma; + + GEN curve, a, b; + a = genrand(field); + b = genrand(field); + + GEN v = gen_0; + switch (typ(field)) { + case t_INT: + v = gtovec0(gen_0, 2); + gel(v, 1) = a; + gel(v, 2) = b; + break; + case t_FFELT: + v = gtovec0(gen_0, 5); + gel(v, 1) = gen_1; + gel(v, 4) = a; + gel(v, 5) = b; + break; + default: + pari_err_TYPE("curve_random", 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_t *curve_nonzero(GEN field) { + 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_t *curve_primef(enum field_e t, long bits) { pari_sp ltop = avma; - GEN curve; + curve_t *result = NULL; do { - GEN a = genrand(field); - GEN b = genrand(field); + if (result) { + avma = ltop; + free_curve(&result); + } + result = curve_nonzerof(t, bits); + result->order = ellsea(result->curve, 1); + } while (gequal0(result->order) || !isprime(result->order)); + + return result; +} + +GEN curve_invalid(GEN field, GEN a, GEN b) { + return gen_m1; +} + +curve_t *curve_seed_Fp(GEN field, GEN seed) { + return NULL; +} + +curve_t *curve_seed_F2m(GEN field, GEN seed) { + return NULL; +} - GEN v = gen_0; - switch (typ(field)) { - case t_INT: - v = gtovec0(gen_0, 2); - gel(v, 1) = a; - gel(v, 2) = b; - break; - case t_FFELT: - v = gtovec0(gen_0, 5); - gel(v, 1) = gen_1; - gel(v, 4) = a; - gel(v, 5) = b; - break; - default: - pari_err_TYPE("curve_random", field); +curve_t *curve_seed(GEN field, GEN seed) { + switch (typ(field)) { + case t_INT: + return curve_seed_Fp(field, seed); + case t_FFELT: + return curve_seed_F2m(field, seed); + default: + pari_err_TYPE("curve_seed", field); + return NULL; /* NOT REACHED */ + } +} + +curve_t *curve_seedr(GEN field) { + pari_sp ltop = avma; + + GEN seed; + curve_t *result = NULL; + do { + if (result) { + avma = ltop; + free_curve(&result); } - curve = ellinit(v, field, -1); - } while (gequal0(ell_get_disc(curve))); + 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; +} + +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)); - return gerepilecopy(ltop, curve); + return gerepilecopy(ltop, gconcat(gconcat(field, a), b)); } diff --git a/src/curve.h b/src/curve.h index 106bf5e..5002f45 100644 --- a/src/curve.h +++ b/src/curve.h @@ -5,8 +5,111 @@ #ifndef ECGEN_CURVE_H #define ECGEN_CURVE_H -#include "gp.h" +#include <pari/pari.h> +#include "field.h" +#include "point.h" -GEN curve_random(GEN field); +typedef struct curve_t { + GEN seed; + GEN field; + GEN a; + GEN b; + GEN curve; + GEN order; + point_t **points; + size_t npoints; +} curve_t; -#endif //ECGEN_CURVE_H +/** + * + * @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); + +/** + * + * @param t + * @param bits + * @return + */ +curve_t *curve_nonzerof(enum field_e t, long bits); + +/** + * + * @param field + * @return + */ +curve_t *curve_prime(GEN field); + +/** + * + * @param t + * @param bits + * @return + */ +curve_t *curve_primef(enum field_e t, long bits); + +/** + * ANSI X9.62 Verifiable random curve over field with seed. + * + * @param field + * @param seed + * @return + */ +curve_t *curve_seed(GEN field, GEN seed); + +/** + * + * @param field + * @return + */ +curve_t *curve_seedr(GEN field); + +/** + * + * @param seed + * @param t + * @param bits + * @return + */ +curve_t *curve_seedf(GEN seed, enum field_e t, long bits); + +/** + * + * @param t + * @param bits + * @return + */ +curve_t *curve_seedrf(enum field_e t, long bits); + +/** + * + * @param curve + * @return + */ +GEN curve_params(curve_t *curve); + +/** + * + * @param curve + */ +void free_curve(curve_t **curve); + + +#endif // ECGEN_CURVE_H diff --git a/src/ecgen.c b/src/ecgen.c index 4459805..320cd0b 100644 --- a/src/ecgen.c +++ b/src/ecgen.c @@ -14,7 +14,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /** * @author J08nY <johny@neuromancer.sk> @@ -24,27 +25,27 @@ #include <time.h> #include "cli.h" -#include "field.h" #include "curve.h" #include "output.h" +#include "input.h" -const char *argp_program_version = "ecgen 0.2\n" - "Copyright (C) 2017 J08nY\n" - "License GPLv2: GNU GPL version 2 (or later) <http://gnu.org/licenses/gpl.html>\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law."; +const char *argp_program_version = + "ecgen 0.2\n" + "Copyright (C) 2017 J08nY\n" + "License GPLv2: GNU GPL version 2 (or later) " + "<http://gnu.org/licenses/gpl.html>\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law."; const char *argp_program_bug_address = "<johny@neuromancer.sk>"; static struct argp argp = {options, parse_opt, args_doc, doc}; -static struct arguments args; +static struct config_t cfg; static FILE *in; static FILE *out; bool init() { // Init PARI, 1GB stack, 1M primes pari_init(1000000000, 1000000); - init_gp(); - // Init PARI PRNG pari_ulong seed = 0; @@ -58,9 +59,9 @@ bool init() { if (seed == 0) { struct timespec t; if (!clock_gettime(CLOCK_REALTIME, &t)) { - seed = (pari_ulong) t.tv_nsec; + seed = (pari_ulong)t.tv_nsec; } else { - seed = (pari_ulong) time(NULL); + seed = (pari_ulong)time(NULL); } } @@ -68,32 +69,16 @@ bool init() { setrand(utoi(seed)); avma = ltop; - //set datadir if specified - if (args.datadir) { - default0("datadir", args.datadir); + // set datadir if specified + if (cfg.datadir) { + default0("datadir", cfg.datadir); } - //open outfile - out = stdout; - if (args.output) { - out = fopen(args.output, args.append ? "a" : "w"); - if (!out) { - //fallback to stdout and output err - out = stdout; - perror("Failed to open output file."); - } - } + // open outfile + out = output_open(cfg.output, cfg.append); - //open infile - in = stdin; - if (args.input) { - in = fopen(args.input, "r"); - if (!in) { - //fallback to stdin or quit? - in = stdin; - perror("Failed to open input file."); - } - } + // open infile + in = input_open(cfg.input); return true; } @@ -101,47 +86,33 @@ bool init() { int quit(int status) { pari_close(); - if (out != NULL && out != stdout) { - fclose(out); - } - - if (in != NULL && in != stdout) { - fclose(in); - } + output_close(out); + input_close(in); return status; } int main(int argc, char *argv[]) { // Parse cli args - memset(&args, 0, sizeof(args)); - argp_parse(&argp, argc, argv, 0, 0, &args); - + memset(&cfg, 0, sizeof(cfg)); + argp_parse(&argp, argc, argv, 0, 0, &cfg); if (!init()) { return quit(1); } - if (args.random) { - GEN field = gen_0; - switch (args.field) { - case FIELD_PRIME: - field = field_primer(args.bits); - break; - case FIELD_BINARY: - field = field_binaryr(args.bits); - break; + if (cfg.random) { + curve_t *curve; + if (cfg.prime) { + curve = curve_primef(cfg.field, cfg.bits); + } else { + curve = curve_nonzerof(cfg.field, cfg.bits); } - GEN curve = curve_random(field); - GEN ord = ellcard(curve, NULL); - GEN f = field_params(field); - GEN a = gtovec(field_elementi(ell_get_a4(curve))); - GEN b = gtovec(field_elementi(ell_get_a6(curve))); + output_csv(out, "%Px", ',', curve_params(curve)); - GEN o = gconcat(gconcat(gconcat(f, a), b), gtovec(ord)); + free_curve(&curve); - output_csv(out, ',', 'x', o); } else { fprintf(stderr, "Currently unsupported."); } diff --git a/src/field.c b/src/field.c index 016f095..c2cfdf8 100644 --- a/src/field.c +++ b/src/field.c @@ -4,36 +4,42 @@ */ #include "field.h" - -GEN field_primer(long bits) { - return random_prime(bits); -} - +GEN field_primer(long bits) { return random_prime(bits); } GEN field_binaryr(long bits) { if (poly_exists(bits)) { return poly_find_gen(bits); } else { - fprintf(stderr, "Unable to find a suitable binary field. Use an explicit one."); + fprintf(stderr, + "Unable to find a suitable binary field. Use an explicit one."); exit(1); } } +GEN field_random(enum field_e t, long bits) { + switch(t) { + case FIELD_PRIME: + return field_primer(bits); + case FIELD_BINARY: + return field_binaryr(bits); + default: + return gen_0; /* NOT REACHABLE */ + } +} + GEN field_params(GEN field) { pari_sp ltop = avma; - long l2; if (typ(field) == t_INT) { GEN p3 = cgetg(2, t_VEC); gel(p3, 1) = gcopy(field); - p3 = gerepilecopy(ltop, p3); - return p3; + return gerepilecopy(ltop, p3); } GEN out = gtovec0(gen_0, 3); long j = 1; - l2 = glength(member_mod(field)) - 2; + long l2 = glength(member_mod(field)) - 2; { pari_sp btop = avma; for (GEN i = gen_1; gcmpgs(i, l2) <= 0; i = gaddgs(i, 1)) { @@ -45,8 +51,7 @@ GEN field_params(GEN field) { if (gc_needed(btop, 1)) gerepileall(btop, 4, &out, &c, &i); } } - out = gerepilecopy(ltop, out); - return out; + return gerepilecopy(ltop, out); } GEN field_elementi(GEN element) { diff --git a/src/field.h b/src/field.h index 55d6bf9..e09ea62 100644 --- a/src/field.h +++ b/src/field.h @@ -6,7 +6,8 @@ #define ECGEN_FIELD_H #include "poly.h" -#include "gp.h" +#include "random.h" +#include "cli.h" /** * @@ -23,9 +24,18 @@ GEN field_primer(long bits); GEN field_binaryr(long bits); /** + * + * @param t + * @param bits + * @return + */ +GEN field_random(enum field_e t, long bits); + +/** * Extract a field representation from a field. * - char(field) == 2: - * returns the vector of powers of middle coefficients of the reduction polynomial. + * returns the vector of powers of middle coefficients of the reduction + * polynomial. * - char(field) != 2: * returns the field characteristic(p).- * @@ -34,6 +44,11 @@ GEN field_binaryr(long bits); */ GEN field_params(GEN field); +/** + * + * @param element + * @return + */ GEN field_elementi(GEN element); -#endif //ECGEN_FIELD_H +#endif // ECGEN_FIELD_H @@ -6,202 +6,3 @@ void init_gp(void) /* void */ avma = ltop; return; } - -/* -* ecgen, tool for generating Elliptic curve domain parameters -* Copyright (C) 2017 J08nY -*/ - -/* -* ecgen, tool for generating Elliptic curve domain parameters -* Copyright (C) 2017 J08nY -*/ - -GEN random_primer(GEN range) /* int */ -{ - pari_sp ltop = avma; - GEN p = gen_0; /* int */ - if (!is_matvec_t(typ(range))) pari_err_TYPE("random_primer", range); - { - pari_sp btop = avma; - do { - p = randomprime(range); - if (gc_needed(btop, 1)) p = gerepilecopy(btop, p); - } while (!isprime(p)); - } - p = gerepilecopy(ltop, p); - return p; -} - -/** -* Calculates a random prime of bit size bits. -* -* @param bits bit size of the requested prime -* @return random prime between 2^(bits - 1) and 2^bits -*/ -GEN random_prime(long bits) /* int */ -{ - pari_sp ltop = avma; - GEN p1 = gen_0; /* vec */ - GEN p2 = gen_0; /* int */ - p1 = cgetg(3, t_VEC); - gel(p1, 1) = powis(gen_2, bits - 1); - gel(p1, 2) = powis(gen_2, bits); - p2 = random_primer(p1); - p2 = gerepilecopy(ltop, p2); - return p2; -} - -GEN random_intr(GEN range) { - pari_sp ltop = avma; - GEN p1 = gen_0; - if (!is_matvec_t(typ(range))) pari_err_TYPE("random_intr", range); - p1 = genrand(range); - p1 = gerepilecopy(ltop, p1); - return p1; -} - -/** -* Generates a random integer with bit size bits. -* -* @param bits bit size of the requested integer -* @return random int between 2^(bits - 1) and 2^bits -*/ -GEN random_int(long bits) { - pari_sp ltop = avma; - GEN p1 = gen_0; /* vec */ - GEN p2 = gen_0; - p1 = cgetg(3, t_VEC); - gel(p1, 1) = powis(gen_2, bits - 1); - gel(p1, 2) = powis(gen_2, bits); - p2 = random_intr(p1); - p2 = gerepilecopy(ltop, p2); - return p2; -} - -/** -* Converts a list to a vector. -* -* @param l list to convert -* @return a vector of the lists values -*/ -GEN list_to_vec(GEN l) /* vec */ -{ - pari_sp ltop = avma; - GEN v = gen_0; /* vec */ - GEN n = gen_0; /* int */ - GEN p1 = gen_0; /* vec */ - n = stoi(glength(l)); - { - long l2; - p1 = cgetg(itos(n) + 1, t_VEC); - for (l2 = 1; cmpsi(l2, n) <= 0; ++l2) gel(p1, l2) = gen_0; - } - v = p1; - { - pari_sp btop = avma; - GEN i = gen_0; - for (i = gen_1; gcmp(i, n) <= 0; i = gaddgs(i, 1)) { - gel(v, gtos(i)) = gcopy(gel(list_data(l), gtos(i))); - if (gc_needed(btop, 1)) gerepileall(btop, 2, &v, &i); - } - } - v = gerepilecopy(ltop, v); - return v; -} - -/* -* ecgen, tool for generating Elliptic curve domain parameters -* Copyright (C) 2017 J08nY -*/ - -/** -* Computes primes upto some upper bound. -* -* @param bound an upper bound on primes -* @return a vector of primes up to bound^2 -*/ -GEN prime_upto(GEN bound) /* vec */ -{ - pari_sp ltop = avma; - GEN p = gen_0; /* list */ - GEN product = gen_0, last = gen_0; /* int */ - GEN result = gen_0; /* vec */ - if (typ(bound) != t_INT) pari_err_TYPE("prime_upto", bound); - p = mklist(); - bound = sqri(bound); - listput0(p, gen_2, 0); - product = gen_2; - last = gen_2; - { - pari_sp btop = avma; - while (cmpii(product, bound) < 0) { - last = nextprime(addis(last, 1)); - listput0(p, last, 0); - product = mulii(product, last); - if (gc_needed(btop, 1)) gerepileall(btop, 3, &p, &product, &last); - } - } - result = list_to_vec(p); - listkill(p); - result = gerepilecopy(ltop, result); - return result; -} - -/** -* -*/ -GEN invalid(GEN coeffs, GEN field, GEN primes, GEN bits, long prec) /* vec */ -{ - pari_sp ltop = avma; - GEN bs = gen_0, cs = gen_0, eq = gen_0; /* vec */ - GEN e = gen_0; /* ell */ - GEN b = gen_0, n = gen_0, c = gen_0, o = gen_0; /* int */ - GEN p1 = gen_0; /* vec */ - if (!is_matvec_t(typ(coeffs))) pari_err_TYPE("invalid", coeffs); - if (typ(field) != t_POL) pari_err_TYPE("invalid", field); - if (!is_matvec_t(typ(primes))) pari_err_TYPE("invalid", primes); - if (typ(bits) != t_INT) pari_err_TYPE("invalid", bits); - n = stoi(lg(primes) - 1); - { - long l2; - p1 = cgetg(itos(n) + 1, t_VEC); - for (l2 = 1; cmpsi(l2, n) <= 0; ++l2) gel(p1, l2) = gen_0; - } - bs = p1; - eq = gcopy(coeffs); - c = gen_0; - { - pari_sp btop = avma; - while (cmpii(c, n) < 0) { - b = random_int(itos(bits)); - gel(eq, 4) = icopy(b); - /* Times field? */ - - pari_CATCH(CATCH_ALL) { - GEN E = pari_err_last(); /* error */ - continue; - } - pari_TRY { e = ellinit(eq, field, prec); } - pari_ENDCATCH o = ellsea(e, 0); - { - pari_sp btop = avma; - GEN i = gen_0; - for (i = gen_1; gcmp(i, n) <= 0; i = gaddgs(i, 1)) { - if (gequal0(gmod(o, gel(primes, gtos(i)))) && - gequal0(gel(bs, gtos(i)))) { - gel(bs, gtos(i)) = icopy(b); - gel(cs, gtos(i)) = gcopy(e); - c = addis(c, 1); - } - if (gc_needed(btop, 1)) - gerepileall(btop, 4, &bs, &cs, &c, &i); - } - } - if (gc_needed(btop, 1)) - gerepileall(btop, 7, &bs, &cs, &eq, &e, &b, &c, &o); - } - } - cs = gerepilecopy(ltop, cs); - return cs; -} @@ -8,21 +8,7 @@ #include <pari/pari.h> /* GP;install("init_gp","v","init_gp","./gp/gp.gp.so"); -GP;install("random_primer","G","random_primer","./gp/gp.gp.so"); -GP;install("random_prime","L","random_prime","./gp/gp.gp.so"); -GP;install("random_intr","G","random_intr","./gp/gp.gp.so"); -GP;install("random_int","L","random_int","./gp/gp.gp.so"); -GP;install("list_to_vec","G","list_to_vec","./gp/gp.gp.so"); -GP;install("prime_upto","G","prime_upto","./gp/gp.gp.so"); -GP;install("invalid","GGGGp","invalid","./gp/gp.gp.so"); */ void init_gp(void); -GEN random_primer(GEN range); -GEN random_prime(long bits); -GEN random_intr(GEN range); -GEN random_int(long bits); -GEN list_to_vec(GEN l); -GEN prime_upto(GEN bound); -GEN invalid(GEN coeffs, GEN field, GEN primes, GEN bits, long prec); /*End of prototype*/ #endif //GP_H diff --git a/src/gp/gp.gp b/src/gp/gp.gp index 0124958..9bae867 100644 --- a/src/gp/gp.gp +++ b/src/gp/gp.gp @@ -3,5 +3,7 @@ * Copyright (C) 2017 J08nY */ +/* \r gp/utils -\r gp/invalid
\ No newline at end of file +\r gp/invalid +*/
\ No newline at end of file diff --git a/src/gp/utils.gp b/src/gp/utils.gp index 932a44a..0f29394 100644 --- a/src/gp/utils.gp +++ b/src/gp/utils.gp @@ -2,39 +2,6 @@ * ecgen, tool for generating Elliptic curve domain parameters * Copyright (C) 2017 J08nY */ - - random_primer(range:vec) = { - local(p:int); - until(isprime(p), - p = randomprime(range):int; - ); - return(p); - } - -/** - * Calculates a random prime of bit size bits. - * - * @param bits bit size of the requested prime - * @return random prime between 2^(bits - 1) and 2^bits - */ -random_prime(bits:small) = { - return(random_primer([2^(bits-1), 2^bits])); -} - -random_intr(range:vec) = { - return(random(range)); -} - -/** - * Generates a random integer with bit size bits. - * - * @param bits bit size of the requested integer - * @return random int between 2^(bits - 1) and 2^bits - */ -random_int(bits:small) = { - return(random_intr([2^(bits-1), 2^bits])); -} - /** * Converts a list to a vector. * diff --git a/src/input.c b/src/input.c index 441fd47..e49eae6 100644 --- a/src/input.c +++ b/src/input.c @@ -7,67 +7,68 @@ /* * *char *prime_prompts[] = {"p:", "a:", "b:"}; - param_t prime_params[] = {PARAM_PRIME, PARAM_INT, PARAM_INT}; + 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 *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 (args.prime_field) { - prompts = prime_prompts; - params = prime_params; - length = 3; - } else { - prompts = binary_prompts; - params = binary_params; - length = 5; - } - GEN field; - GEN domain[length]; + 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 (args.random) { - //random domain, might not define a curve... check disc - if (args.prime_field) { - field = ifield_prime(args.bits); - } else { - field = ifield_binary(args.bits); - } - } else { - for (size_t i = 0; i < length; ++i) { - domain[i] = fread_param(params[i], in, prompts[i], args.bits, in == stdin ? '\n' : ','); - if (equalii(domain[i], gen_m1)) { - fprintf(stderr, "Whoops?"); - return quit(1); - } - } - if (args.prime_field) { - field = field_prime(domain[0]); - } else { - field = field_binary(args.bits, domain[0], domain[1], domain[2]); - } - } - pari_fprintf(out, "%Ps", field_params(field)); + 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 (args.prime_field) { - GEN field = prime_field(p); - GEN curve = prime_weierstrass(a, b, field, 0); - } else if (args.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:", args.bits, '\n'); + 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(args.bits, e[0], e[1], e[2]); - } + GEN field = binary_field(cfg.bits, e[0], e[1], e[2]); + } */ - GEN fread_i(FILE *stream, const char *prompt, long bits, int delim, - GEN (*rand_func)(long)) { + GEN (*rand_func)(long)) { printf("%s ", prompt); char *line = NULL; size_t n = 0; @@ -117,7 +118,8 @@ GEN fread_short(FILE *stream, const char *prompt, int delim) { return fread_i(stream, prompt, 16, delim, NULL); } -GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, int delim) { +GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, + int delim) { switch (param) { case PARAM_PRIME: return fread_prime(stream, prompt, bits, delim); @@ -133,3 +135,22 @@ GEN read_param(param_t param, const char *prompt, long bits, int delim) { return fread_param(param, stdin, prompt, bits, delim); } +FILE *input_open(const char *input) { + if (input) { + FILE *in = fopen(input, "r"); + if (!in) { + // fallback to stdin or quit? + in = stdin; + perror("Failed to open input file."); + } + return in; + } else { + return stdin; + } +} + +void input_close(FILE *in) { + if (in != NULL && in != stdout) { + fclose(in); + } +} diff --git a/src/input.h b/src/input.h index b0ab421..ead8baa 100644 --- a/src/input.h +++ b/src/input.h @@ -5,13 +5,9 @@ #ifndef ECGEN_INPUT_H #define ECGEN_INPUT_H -#include "gp.h" +#include "random.h" -typedef enum PARAM { - PARAM_PRIME, - PARAM_INT, - PARAM_SHORT -} param_t; +typedef enum PARAM { PARAM_PRIME, PARAM_INT, PARAM_SHORT } param_t; /** * @@ -42,10 +38,13 @@ GEN fread_int(FILE *stream, const char *prompt, long bits, int delim); */ GEN fread_short(FILE *stream, const char *prompt, int delim); - -GEN fread_param(param_t param, FILE *stream, const char *prompt, long bits, 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); +FILE *input_open(const char *input); + +void input_close(FILE *in); -#endif //ECGEN_INPUT_H +#endif // ECGEN_INPUT_H diff --git a/src/output.c b/src/output.c index 26f4f89..adeda58 100644 --- a/src/output.c +++ b/src/output.c @@ -2,22 +2,21 @@ * ecgen, tool for generating Elliptic curve domain parameters * Copyright (C) 2017 J08nY */ -#include "output.h" -void output_csv(FILE *out, char delim, char format, GEN vector) { - char fmt[] = {'%', 'P', format, 0}; +#include "output.h" +char *output_scsv(const char *format, char delim, GEN vector) { long len = lg(vector) - 1; char *params[len]; size_t lengths[len]; size_t total = 0; for (long i = 0; i < len; ++i) { - params[i] = pari_sprintf(fmt, gel(vector, i + 1)); + params[i] = pari_sprintf(format, gel(vector, i + 1)); lengths[i] = strlen(params[i]); total += lengths[i]; } - char *result = malloc(total + len); + char *result = (char *)malloc(total + len); if (!result) { perror("Couldn't malloc."); exit(1); @@ -34,9 +33,38 @@ void output_csv(FILE *out, char delim, char format, GEN vector) { offset++; } } - result[offset] = 0; + memset(result + offset, 0, 1); + + return result; +} + +void output_csv(FILE *out, const char *format, char delim, GEN vector) { + char *string = output_scsv(format, delim, vector); + fprintf(out, "%s", string); + free(string); +} - fprintf(out, "%s", result); - free(result); +char *output_sjson(GEN vector) { } +void output_json(FILE *out, GEN vector) {} + +FILE *output_open(const char *output, bool append) { + if (output) { + FILE *out = fopen(output, append ? "a" : "w"); + if (!out) { + // fallback to stdout and output err + out = stdout; + perror("Failed to open output file."); + } + return out; + } else { + return stdout; + } +} + +void output_close(FILE *out) { + if (out != NULL && out != stdout) { + fclose(out); + } +}
\ No newline at end of file diff --git a/src/output.h b/src/output.h index f3632a1..f45aa50 100644 --- a/src/output.h +++ b/src/output.h @@ -5,8 +5,44 @@ #ifndef ECGEN_OUTPUT_H #define ECGEN_OUTPUT_H -#include "gp.h" +#include <stdbool.h> +#include <parson/parson.h> +#include <pari/pari.h> -void output_csv(FILE *out, char delim, char format, GEN vector); +/** + * + * @param delim + * @param format + * @param vector + * @return + */ +char *output_scsv(const char *format, char delim, GEN vector); + +/** + * + * @param out + * @param delim + * @param format + * @param vector + */ +void output_csv(FILE *out, const char *format, char delim, GEN vector); + +/** + * + * @param vector + * @return + */ +char *output_sjson(GEN vector); + +/** + * + * @param out + * @param vector + */ +void output_json(FILE *out, GEN vector); + +FILE *output_open(const char *output, bool append); + +void output_close(FILE *out); -#endif //ECGEN_OUTPUT_H +#endif // ECGEN_OUTPUT_H diff --git a/src/point.c b/src/point.c new file mode 100644 index 0000000..8fa1007 --- /dev/null +++ b/src/point.c @@ -0,0 +1,13 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "point.h" + + +point_t *gerepile_point(pari_sp ltop, point_t *point) { + if (point) { + gerepileall(ltop, 2, &point->point, &point->order); + } + return point; +}
\ No newline at end of file diff --git a/src/point.h b/src/point.h new file mode 100644 index 0000000..710c3ce --- /dev/null +++ b/src/point.h @@ -0,0 +1,17 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_POINT_H +#define ECGEN_POINT_H + +#include <pari/pari.h> + +typedef struct point_t { + GEN point; + GEN order; +} point_t; + +point_t *gerepile_point(pari_sp ltop, point_t *point); + +#endif //ECGEN_POINT_H @@ -6,7 +6,7 @@ #define ECGEN_POLY_H #include <stdbool.h> -#include "gp.h" +#include <pari/pari.h> typedef struct polynomial { int m; @@ -45,4 +45,4 @@ GEN poly_find_gen(long m); */ GEN poly_gen(polynomial_t *polynomial); -#endif //ECGEN_POLY_H +#endif // ECGEN_POLY_H diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..eaa1a7c --- /dev/null +++ b/src/random.c @@ -0,0 +1,34 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#include "random.h" + +GEN random_prime(long bits) { + pari_sp ltop = avma; + + GEN range = gtovec0(gen_0, 2); + gel(range, 1) = powis(gen_2, bits - 1); + gel(range, 2) = powis(gen_2, bits); + + GEN p; + { + pari_sp btop = avma; + do { + p = randomprime(range); + if (gc_needed(btop, 1)) p = gerepilecopy(btop, p); + } while (!isprime(p)); + } + + return gerepilecopy(ltop, p); +} + +GEN random_int(long bits) { + pari_sp ltop = avma; + + GEN range = gtovec0(gen_0, 2); + gel(range, 1) = powis(gen_2, bits - 1); + gel(range, 2) = powis(gen_2, bits); + + return gerepilecopy(ltop, genrand(range)); +}
\ No newline at end of file diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000..9faa946 --- /dev/null +++ b/src/random.h @@ -0,0 +1,14 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +#ifndef ECGEN_RANDOM_H +#define ECGEN_RANDOM_H + +#include <pari/pari.h> + +GEN random_prime(long bits); + +GEN random_int(long bits); + +#endif // ECGEN_RANDOM_H |
