aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile19
-rw-r--r--src/cli.c76
-rw-r--r--src/cli.h13
-rw-r--r--src/curve.c219
-rw-r--r--src/curve.h109
-rw-r--r--src/ecgen.c93
-rw-r--r--src/field.c29
-rw-r--r--src/field.h21
-rw-r--r--src/gp.c199
-rw-r--r--src/gp.h14
-rw-r--r--src/gp/gp.gp4
-rw-r--r--src/gp/utils.gp33
-rw-r--r--src/input.c129
-rw-r--r--src/input.h17
-rw-r--r--src/output.c44
-rw-r--r--src/output.h42
-rw-r--r--src/point.c13
-rw-r--r--src/point.h17
-rw-r--r--src/poly.h4
-rw-r--r--src/random.c34
-rw-r--r--src/random.h14
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
diff --git a/src/cli.c b/src/cli.c
index cdc2af4..728bb6e 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -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:
diff --git a/src/cli.h b/src/cli.h
index e9b832b..0f0c625 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -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
diff --git a/src/gp.c b/src/gp.c
index d15e117..59cb11a 100644
--- a/src/gp.c
+++ b/src/gp.c
@@ -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;
-}
diff --git a/src/gp.h b/src/gp.h
index c81c4c1..f066dec 100644
--- a/src/gp.h
+++ b/src/gp.h
@@ -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
diff --git a/src/poly.h b/src/poly.h
index 2bb5c96..a0c1904 100644
--- a/src/poly.h
+++ b/src/poly.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