aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md34
-rw-r--r--src/Makefile2
-rw-r--r--src/cli.c48
-rw-r--r--src/cli.h3
-rw-r--r--src/curve.c212
-rw-r--r--src/curve.h87
-rw-r--r--src/ecgen.c52
-rw-r--r--src/equation.c47
-rw-r--r--src/equation.h27
-rw-r--r--src/field.c26
-rw-r--r--src/field.h21
-rw-r--r--src/generators.c39
-rw-r--r--src/generators.h25
-rw-r--r--src/gp.h2
-rw-r--r--src/input.c88
-rw-r--r--src/input.h11
-rw-r--r--src/output.c5
-rw-r--r--src/output.h6
-rw-r--r--src/point.c1
-rw-r--r--src/point.h8
-rw-r--r--src/poly.c5
-rw-r--r--src/poly.h5
-rw-r--r--src/random.c26
-rw-r--r--src/random.h3
-rw-r--r--src/seed.c86
-rw-r--r--src/seed.h21
-rw-r--r--src/types.h31
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})
diff --git a/README.md b/README.md
index e02298f..c4b82ae 100644
--- a/README.md
+++ b/README.md
@@ -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))
diff --git a/src/cli.c b/src/cli.c
index 728bb6e..88521c4 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -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:
diff --git a/src/cli.h b/src/cli.h
index 0f0c625..5bffb3a 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -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
diff --git a/src/gp.h b/src/gp.h
index f066dec..27e4726 100644
--- a/src/gp.h
+++ b/src/gp.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
diff --git a/src/poly.c b/src/poly.c
index 89e2c74..ab24d03 100644
--- a/src/poly.c
+++ b/src/poly.c
@@ -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},
diff --git a/src/poly.h b/src/poly.h
index a0c1904..990c818 100644
--- a/src/poly.h
+++ b/src/poly.h
@@ -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