summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-02-15 20:22:36 +0100
committerJ08nY2017-02-15 20:22:36 +0100
commit69bfdc6a4584a22dac7525f38c8ac013f05417b6 (patch)
tree0c2054bdf9846419aa0f301dd3a7b60b3c0bf142
parent8863bda8116a540134eb6715fc91294c5938d400 (diff)
downloadecgen-69bfdc6a4584a22dac7525f38c8ac013f05417b6.tar.gz
ecgen-69bfdc6a4584a22dac7525f38c8ac013f05417b6.tar.zst
ecgen-69bfdc6a4584a22dac7525f38c8ac013f05417b6.zip
-rw-r--r--README.md7
-rw-r--r--src/exhaustive/exhaustive.c14
-rw-r--r--src/invalid/invalid.c4
-rw-r--r--src/io/cli.c65
-rw-r--r--src/io/cli.h2
-rw-r--r--src/io/output.c135
-rw-r--r--src/io/output.h75
7 files changed, 241 insertions, 61 deletions
diff --git a/README.md b/README.md
index b7ea2f1..a448e7e 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,10 @@ Tool for generating Elliptic curve domain parameters.
- `-n/--order=ORDER` requests the curve to have a (prime) order `ORDER`.
- `-i/--invalid` requests that invalid curves of small prime orders be generated.
<br/><br/>
- - `-o/--output=FILE` writes output to `FILE`.
+ - `-v/--verbose=[FILE]` turns on verbose output (to file).
+ - `-t/--format=[FORMAT]` sets format to output in. One of \[csv,json\], default is json.
- `-f/--input=FILE` reads input from `FILE`.
+ - `-o/--output=FILE` writes output to `FILE`.
- `-a/--append` appends to output file (doesn't overwrite it).
<br/><br/>
- `-d/--datadir=DIR` specifies the PARI/GP datadir containing the `seadata` package.
@@ -29,6 +31,9 @@ Three different EC curve parameters generation methods are implemented.
- randomly
- using ANSI X9.62 verifiably random method(from seed), until a curve with requested properties appears.
- given input
+ - Can generate curves repeatedly until one satisfies requested properties:
+ - `-p/--prime` generates curves until a prime order curve is found.
+ - `-k/--koblitz` generates a curve with fixed *A = 0* parameter.
##### Invalid curve generation
- Generates *invalid* curves for a given curve.
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 00905c5..4d6e7a9 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -69,18 +69,18 @@ int exhaustive_gen(curve_t *curve, config_t *config, gen_t generators[],
}
if (config->verbose) {
if (diff > 0) {
- fprintf(out, "+");
+ fprintf(debug, "+");
} else if (diff < 0) {
- fprintf(out, "-");
+ fprintf(debug, "-");
} else {
- fprintf(out, ".");
+ fprintf(debug, ".");
}
- fflush(out);
+ fflush(debug);
}
state += diff;
}
- if (config->verbose) fprintf(out, "\n");
+ if (config->verbose) fprintf(debug, "\n");
return 1;
}
@@ -90,11 +90,11 @@ int exhaustive_do(config_t *cfg) {
exhaustive_init(generators, cfg);
curve_t *curve = curve_new();
- if (!exhaustive_gen(curve, cfg, generators, OFFSET_FIELD, OFFSET_END)) {
+ if (!exhaustive_gen(curve, cfg, generators, OFFSET_SEED, OFFSET_END)) {
curve_free(&curve);
return 1;
}
- output_csv(out, "%P#x", ',', curve_params(curve));
+ output_o(curve, cfg);
curve_free(&curve);
return 0;
} \ No newline at end of file
diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c
index 1c21f89..72a9877 100644
--- a/src/invalid/invalid.c
+++ b/src/invalid/invalid.c
@@ -108,7 +108,7 @@ size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
(*curves)[i] = curve_new();
(*curves)[i] = curve_copy(invalid, (*curves)[i]);
}
- output_csv(out, "%P#x", ',', curve_params((*curves)[i]));
+ output_o((*curves)[i], cfg);
ncurves++;
count++;
}
@@ -136,7 +136,7 @@ int invalid_do(config_t *cfg) {
curve_free(&curve);
return 1;
}
- output_csv(out, "%P#x", ',', curve_params(curve));
+ output_o(curve, cfg);
// now, generate primes upto order^2
pari_ulong *primes;
diff --git a/src/io/cli.c b/src/io/cli.c
index 6aaadc8..f9097d9 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -6,8 +6,8 @@
#include <string.h>
char doc[] =
- "ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 "
- "Eastern Seaboard Phishing Authority";
+ "ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 "
+ "Eastern Seaboard Phishing Authority";
char args_doc[] = "bits";
enum opt_keys {
@@ -18,6 +18,7 @@ enum opt_keys {
OPT_INVALID = 'i',
OPT_ORDER = 'n',
OPT_KOBLITZ = 'k',
+ OPT_FORMAT = 't',
OPT_OUTPUT = 'o',
OPT_INPUT = 'f',
OPT_APPEND = 'a',
@@ -29,21 +30,22 @@ enum opt_keys {
// 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)."},
- {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves (for a given curve)."},
- {"order", OPT_ORDER, "ORDER", 0, "Generate a curve with given order (using Complex Multiplication)."},
- {"koblitz", OPT_KOBLITZ, 0, 0, "Generate a Koblitz curve."},
+ {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves (for a given curve)."},
+ {"order", OPT_ORDER, "ORDER", 0, "Generate a curve with given order (using Complex Multiplication)."},
+ {"koblitz", OPT_KOBLITZ, 0, 0, "Generate a Koblitz curve."},
// Other
- {"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)."},
- {"verbose", OPT_VERBOSE, "FILE", OPTION_ARG_OPTIONAL, "Verbose logging to stdout"},
+ {"data-dir", OPT_DATADIR, "DIR", 0, "PARI/GP data directory (containing seadata package)."},
+ {"format", OPT_FORMAT, "FORMAT", 0, "Format to output in. One of [csv,json], default is json."},
+ {"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)."},
+ {"verbose", OPT_VERBOSE, "FILE", OPTION_ARG_OPTIONAL, "Verbose logging (to stdout or file)."},
{0}};
// clang-format on
@@ -54,6 +56,21 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
case OPT_DATADIR:
cfg->datadir = arg;
break;
+ case OPT_FORMAT:
+ if (arg) {
+ if (!strcmp(arg, "csv")) {
+ cfg->format = FORMAT_CSV;
+ } else if (!strcmp(arg, "json")) {
+ cfg->format = FORMAT_JSON;
+ } else {
+ argp_failure(state, 1, 0,
+ "Invalid format specified. One of [csv, json] is valid.");
+ }
+ } else {
+ argp_failure(state, 1, 0,
+ "You have to specify a format with the format option.");
+ }
+ break;
case OPT_INPUT:
cfg->input = arg;
break;
@@ -93,8 +110,8 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
// 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).");
+ state, 1, 0,
+ "SEED must be at least 160 bits (20 characters).");
}
cfg->seed = arg;
}
@@ -119,22 +136,22 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) {
// Only one field
if (!cfg->prime_field && !cfg->binary_field) {
argp_failure(state, 1, 0,
- "Specify field type, prime or binary, with --fp / "
- "--f2m (but not both).");
+ "Specify field type, prime or binary, with --fp / "
+ "--f2m (but not both).");
}
// Invalid is not prime or seed by definition.
if (cfg->invalid && (cfg->prime || cfg->from_seed)) {
// not seed, not prime
argp_failure(state, 1, 0,
- "Invalid curve generation can not generate curves "
- "from seed, exhaustive or prime order.");
+ "Invalid curve generation can not generate curves "
+ "from seed, exhaustive or prime order.");
}
if (cfg->cm && (cfg->prime || cfg->from_seed || cfg->invalid)) {
argp_failure(state, 1, 0,
- "Fixed order curve generation can not generate "
- "curves from seed, or invalid curves. Prime order "
- "also doesn't make sense if the given one isn't "
- "prime.");
+ "Fixed order curve generation can not generate "
+ "curves from seed, or invalid curves. Prime order "
+ "also doesn't make sense if the given one isn't "
+ "prime.");
}
break;
case ARGP_KEY_NO_ARGS:
diff --git a/src/io/cli.h b/src/io/cli.h
index 52b39ec..152a129 100644
--- a/src/io/cli.h
+++ b/src/io/cli.h
@@ -14,6 +14,7 @@ extern char args_doc[];
extern struct argp_option options[];
enum field_e { FIELD_PRIME, FIELD_BINARY };
+enum format_e { FORMAT_JSON, FORMAT_CSV };
typedef struct config_t {
enum field_e field;
@@ -28,6 +29,7 @@ typedef struct config_t {
bool from_seed;
char *seed;
char *datadir;
+ enum format_e format;
char *output;
char *input;
bool append;
diff --git a/src/io/output.c b/src/io/output.c
index 1b4b16b..7b3e8a1 100644
--- a/src/io/output.c
+++ b/src/io/output.c
@@ -5,17 +5,23 @@
#include "output.h"
#include <parson/parson.h>
+#include "math/field.h"
+#include "math/curve.h"
+
FILE *out;
FILE *debug;
-char *output_scsv(const char *format, char delim, GEN vector) {
- long len = lg(vector) - 1;
+char *output_scsv(curve_t *curve, config_t *config) {
+ pari_sp ltop = avma;
+ GEN vector = curve_params(curve);
+
+ long len = glength(vector);
char *params[len];
size_t lengths[len];
size_t total = 0;
for (long i = 0; i < len; ++i) {
- params[i] = pari_sprintf(format, gel(vector, i + 1));
+ params[i] = pari_sprintf("%P#x", gel(vector, i + 1));
lengths[i] = strlen(params[i]);
total += lengths[i];
}
@@ -33,34 +39,111 @@ char *output_scsv(const char *format, char delim, GEN vector) {
offset += lengths[i];
if (i != len - 1) {
- result[offset] = delim;
+ result[offset] = ',';
offset++;
}
}
memset(result + offset, 0, 1);
+ avma = ltop;
return result;
}
-void output_csv(FILE *out, const char *format, char delim, GEN vector) {
- char *string = output_scsv(format, delim, vector);
+void output_fcsv(FILE *out, curve_t *curve, config_t *config) {
+ char *string = output_scsv(curve, config);
fprintf(out, "%s\n", string);
free(string);
}
+void output_csv(curve_t *curve, config_t *config) {
+ output_fcsv(out, curve, config);
+}
-char *output_sjson(curve_t *curve) {
- /*
+JSON_Value *output_jjson(curve_t *curve, config_t *config) {
+ pari_sp ltop = avma;
+ // root object/value is curve
JSON_Value *root_value = json_value_init_object();
JSON_Object *root_object = json_value_get_object(root_value);
- char *result = NULL;
- */
- //TODO implement
- return NULL;
+
+ switch (config->field) {
+ case FIELD_PRIME: {
+ char *prime = pari_sprintf("%P#x", curve->field);
+ json_object_dotset_string(root_object, "field.p", prime);
+ pari_free(prime);
+ break;
+ }
+ case FIELD_BINARY: {
+ GEN field = field_params(curve->field);
+ char *e1 = pari_sprintf("%P#x", gel(field, 1));
+ char *e2 = pari_sprintf("%P#x", gel(field, 2));
+ char *e3 = pari_sprintf("%P#x", gel(field, 3));
+ char *m = pari_sprintf("%#lx", config->bits); // maybe not?
+ json_object_dotset_string(root_object, "field.m", m);
+ json_object_dotset_string(root_object, "field.e1", e1);
+ json_object_dotset_string(root_object, "field.e2", e2);
+ json_object_dotset_string(root_object, "field.e3", e3);
+ pari_free(m);
+ pari_free(e1);
+ pari_free(e2);
+ pari_free(e3);
+ break;
+ }
+ default:
+ fprintf(stderr, "Error, field has unknown amount of elements.\n");
+ exit(1);
+ }
+
+ char *a = pari_sprintf("%P#x", field_elementi(curve->a));
+ json_object_set_string(root_object, "a", a);
+ pari_free(a);
+ char *b = pari_sprintf("%P#x", field_elementi(curve->b));
+ json_object_set_string(root_object, "b", b);
+ pari_free(b);
+ char *order = pari_sprintf("%P#x", curve->order);
+ json_object_set_string(root_object, "order", order);
+ pari_free(order);
+ if (curve->npoints) {
+ JSON_Value *points_value = json_value_init_array();
+ JSON_Array *points_array = json_value_get_array(points_value);
+
+ for (size_t i = 0; i < curve->npoints; ++i) {
+ JSON_Value *point_value = json_value_init_object();
+ JSON_Object *point_object = json_value_get_object(point_value);
+
+ char *x = pari_sprintf("%P#x", field_elementi(gel(curve->points[i]->point, 1)));
+ json_object_set_string(point_object, "x", x);
+ pari_free(x);
+ char *y = pari_sprintf("%P#x", field_elementi(gel(curve->points[i]->point, 2)));
+ json_object_set_string(point_object, "y", y);
+ pari_free(y);
+ char *p_order = pari_sprintf("%P#x", curve->points[i]->order);
+ json_object_set_string(point_object, "order", p_order);
+ pari_free(p_order);
+ json_array_append_value(points_array, point_value);
+ }
+
+ json_object_set_value(root_object, "points", points_value);
+ }
+ avma = ltop;
+ return root_value;
}
-void output_json(FILE *out, GEN vector) {
- //TODO implement
+char *output_sjson(curve_t *curve, config_t *config) {
+ JSON_Value *root_value = output_jjson(curve, config);
+ char *result = json_serialize_to_string_pretty(root_value);
+ json_value_free(root_value);
+
+ return result;
+}
+
+void output_fjson(FILE *out, curve_t *curve, config_t *config) {
+ char *s = output_sjson(curve, config);
+ fprintf(out, "%s", s);
+ json_free_serialized_string(s);
+}
+
+void output_json(curve_t *curve, config_t *config) {
+ output_fjson(out, curve, config);
}
void output_init(config_t *cfg) {
@@ -76,10 +159,32 @@ void output_init(config_t *cfg) {
} else {
out = stdout;
}
+ if (cfg->debug) {
+ debug = fopen(cfg->debug, "w");
+ if (!debug) {
+ debug = stdout;
+ perror("Failed to open verbose output file.");
+ }
+ } else {
+ debug = stdout;
+ }
+
+ switch (cfg->format) {
+ case FORMAT_JSON:
+ output_s = &output_sjson;
+ output_f = &output_fjson;
+ output_o = &output_json;
+ break;
+ case FORMAT_CSV:
+ output_s = &output_scsv;
+ output_f = &output_fcsv;
+ output_o = &output_csv;
+ break;
+ }
}
void output_quit(void) {
if (out != NULL && out != stdout) {
fclose(out);
}
-} \ No newline at end of file
+}
diff --git a/src/io/output.h b/src/io/output.h
index b2b32ac..5aca4bd 100644
--- a/src/io/output.h
+++ b/src/io/output.h
@@ -11,41 +11,92 @@
/**
*
- * @param delim
- * @param format
- * @param vector
+ * @param curve
+ * @param config
* @return
*/
-char *output_scsv(const char *format, char delim, GEN vector);
+char *output_scsv(curve_t *curve, config_t *config);
/**
*
* @param out
- * @param delim
- * @param format
- * @param vector
+ * @param curve
+ * @param config
*/
-void output_csv(FILE *out, const char *format, char delim, GEN vector);
+void output_fcsv(FILE *out, curve_t *curve, config_t *config);
/**
*
- * @param vector
+ * @param curve
+ * @param config
+ */
+void output_csv(curve_t *curve, config_t *config);
+
+/**
+ *
+ * @param curve
+ * @param config
+ * @return
+ */
+char *output_sjson(curve_t *curve, config_t *config);
+
+/**
+ *
+ * @param out
+ * @param curve
+ * @param config
+ */
+void output_fjson(FILE *out, curve_t *curve, config_t *config);
+
+/**
+ *
+ * @param curve
+ * @param config
+ */
+void output_json(curve_t *curve, config_t *config);
+
+/**
+ *
+ * @param curve
+ * @param config
* @return
*/
-char *output_sjson(curve_t *curve);
+char *(*output_s)(curve_t *curve, config_t *config);
/**
*
* @param out
- * @param vector
+ * @param curve
+ * @param config
*/
-void output_json(FILE *out, GEN vector);
+void (*output_f)(FILE *out, curve_t *curve, config_t *config);
+/**
+ *
+ * @param curve
+ * @param config
+ */
+void (*output_o)(curve_t *curve, config_t *config);
+
+/**
+ *
+ */
extern FILE *out;
+
+/**
+ *
+ */
extern FILE *debug;
+/**
+ *
+ * @param cfg
+ */
void output_init(config_t *cfg);
+/**
+ *
+ */
void output_quit(void);
#endif // ECGEN_OUTPUT_H