aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-10-01 02:50:57 +0200
committerJ08nY2017-10-01 02:50:57 +0200
commit6fea41693fa19734747103b5cf4d681613090bc1 (patch)
treec58ff06c6b8379844eddb23eccf214edf816e6eb
parent137390f09976235da012a1279e5ba64e54e1c6e1 (diff)
parent75caf69b45fda59267790939cb8f180e4f3c3498 (diff)
downloadecgen-6fea41693fa19734747103b5cf4d681613090bc1.tar.gz
ecgen-6fea41693fa19734747103b5cf4d681613090bc1.tar.zst
ecgen-6fea41693fa19734747103b5cf4d681613090bc1.zip
-rw-r--r--src/exhaustive/ansi.c4
-rw-r--r--src/exhaustive/exhaustive.c5
-rw-r--r--src/gen/equation.c4
-rw-r--r--src/gen/field.c2
-rw-r--r--src/gen/gp.c120
-rw-r--r--src/gen/gp.h19
-rw-r--r--src/misc/types.h6
-rw-r--r--test/src/exhaustive/test_ansi.c18
-rw-r--r--test/src/gen/test_gp.c109
-rw-r--r--test/src/gen/test_point.c12
10 files changed, 275 insertions, 24 deletions
diff --git a/src/exhaustive/ansi.c b/src/exhaustive/ansi.c
index 51d20e5..d18ea02 100644
--- a/src/exhaustive/ansi.c
+++ b/src/exhaustive/ansi.c
@@ -183,9 +183,9 @@ static GENERATOR(ansi_gen_equation_f2m) {
GENERATOR(ansi_gen_equation) {
switch (cfg->field) {
case FIELD_PRIME:
- return ansi_gen_equation_fp(curve, cfg, args);
+ return ansi_gen_equation_fp(curve, cfg, args, state);
case FIELD_BINARY:
- return ansi_gen_equation_f2m(curve, cfg, args);
+ return ansi_gen_equation_f2m(curve, cfg, args, state);
default:
pari_err_BUG("Field not prime or binary?");
return INT_MIN; /* NOT REACHABLE */
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 623396e..30d2c47 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -230,14 +230,15 @@ int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
arg_t *arg = argss ? argss[state] : NULL;
- int diff = generators[state](curve, cfg, arg);
+ int diff = generators[state](curve, cfg, arg, (offset_e)state);
int new_state = state + diff;
if (new_state < start_offset) new_state = start_offset;
if (diff > 0 && validators && validators[state]) {
check_t *validator = validators[state];
for (size_t i = 0; i < validator->nchecks; ++i) {
- int new_diff = validator->checks[i](curve, cfg, arg);
+ int new_diff =
+ validator->checks[i](curve, cfg, arg, (offset_e)state);
if (new_diff <= 0) {
diff = new_diff;
break;
diff --git a/src/gen/equation.c b/src/gen/equation.c
index 76d0498..9d85c13 100644
--- a/src/gen/equation.c
+++ b/src/gen/equation.c
@@ -36,7 +36,7 @@ GENERATOR(a_gen_once) {
return 1;
}
- int inp = a_gen_input(curve, cfg, args);
+ int inp = a_gen_input(curve, cfg, args, state);
if (inp > 0) {
a = gclone(curve->a);
curve_a = curve;
@@ -86,7 +86,7 @@ GENERATOR(b_gen_once) {
return 1;
}
- int inp = b_gen_input(curve, cfg, args);
+ int inp = b_gen_input(curve, cfg, args, state);
if (inp > 0) {
b = gclone(curve->b);
curve_b = curve;
diff --git a/src/gen/field.c b/src/gen/field.c
index 9a908cc..898af9e 100644
--- a/src/gen/field.c
+++ b/src/gen/field.c
@@ -104,7 +104,7 @@ GENERATOR(field_gen_once) {
return 1;
}
- int inp = field_gen_input(curve, cfg, args);
+ int inp = field_gen_input(curve, cfg, args, state);
if (inp > 0) {
field = gclone(curve->field);
curve_field = curve;
diff --git a/src/gen/gp.c b/src/gen/gp.c
new file mode 100644
index 0000000..dff7ca1
--- /dev/null
+++ b/src/gen/gp.c
@@ -0,0 +1,120 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#include "gp.h"
+#include "exhaustive/arg.h"
+#include "io/output.h"
+#include "point.h"
+#include "seed.h"
+#include "util/bits.h"
+
+static point_t **gp_points(const curve_t *curve, GEN point_vec) {
+ long len = glength(point_vec);
+ point_t **result = points_new((size_t)len);
+
+ for (long i = 1; i <= len; ++i) {
+ point_t *point = point_new();
+ point->point = gel(point_vec, i);
+ point->order = ellorder(curve->curve, point->point, NULL);
+ result[i - 1] = point;
+ }
+ return result;
+}
+
+static point_t **gp_gens(const curve_t *curve, GEN gens_vec) {
+ point_t **result = gp_points(curve, gens_vec);
+
+ long len = glength(gens_vec);
+ for (long i = 1; i <= len; ++i) {
+ point_t *gen = result[i - 1];
+ gen->cofactor = divii(curve->order, gen->order);
+ }
+ return result;
+}
+
+GENERATOR(gp_gen) {
+ HAS_ARG(args);
+ pari_sp ltop = avma;
+ GEN closure = compile_str(args->args);
+ GEN params = zerovec(state - OFFSET_SEED);
+
+ if (state > OFFSET_SEED) {
+ if (curve->seed && curve->seed->seed) {
+ gel(params, 1) = bits_to_bitvec(curve->seed->seed);
+ }
+ }
+
+ if (state > OFFSET_FIELD) {
+ gel(params, 2) = curve->field;
+ }
+
+ if (state > OFFSET_A) {
+ gel(params, 3) = curve->a;
+ }
+
+ if (state > OFFSET_B) {
+ gel(params, 4) = curve->b;
+ }
+
+ if (state > OFFSET_CURVE) {
+ gel(params, 5) = curve->curve;
+ }
+
+ if (state > OFFSET_ORDER) {
+ gel(params, 6) = curve->order;
+ }
+
+ if (state > OFFSET_GENERATORS) {
+ GEN gens = zerovec(curve->ngens);
+ for (size_t i = 0; i < curve->ngens; ++i) {
+ gel(gens, i + 1) = curve->generators[i]->point;
+ }
+ gel(params, 7) = gens;
+ }
+
+ if (state > OFFSET_POINTS) {
+ GEN points = zerovec(curve->npoints);
+ for (size_t i = 0; i < curve->npoints; ++i) {
+ gel(points, i + 1) = curve->points[i]->point;
+ }
+ gel(params, 8) = points;
+ }
+
+ GEN res = call0(closure, zerovec(0));
+ res = call0(res, params);
+
+ res = gerepileupto(ltop, res);
+ switch (state) {
+ case OFFSET_SEED:
+ curve->seed = seed_new();
+ curve->seed->seed = bits_from_bitvec(res);
+ break;
+ case OFFSET_FIELD:
+ curve->field = res;
+ break;
+ case OFFSET_A:
+ curve->a = res;
+ break;
+ case OFFSET_B:
+ curve->b = res;
+ break;
+ case OFFSET_CURVE:
+ curve->curve = res;
+ break;
+ case OFFSET_ORDER:
+ curve->order = res;
+ break;
+ case OFFSET_GENERATORS:
+ curve->ngens = (size_t)glength(res);
+ curve->generators = gp_gens(curve, res);
+ break;
+ case OFFSET_POINTS:
+ curve->npoints = (size_t)glength(res);
+ curve->points = gp_points(curve, res);
+ break;
+ case OFFSET_END:
+ break;
+ }
+ return 1;
+} \ No newline at end of file
diff --git a/src/gen/gp.h b/src/gen/gp.h
new file mode 100644
index 0000000..c0ee1af
--- /dev/null
+++ b/src/gen/gp.h
@@ -0,0 +1,19 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#ifndef ECGEN_GP_H
+#define ECGEN_GP_H
+
+#include "misc/types.h"
+
+/**
+ * @brief
+ * @param curve
+ * @param cfg
+ * @param args
+ * @return
+ */
+GENERATOR(gp_gen);
+
+#endif // ECGEN_GP_H
diff --git a/src/misc/types.h b/src/misc/types.h
index 103cf8a..d20ed2b 100644
--- a/src/misc/types.h
+++ b/src/misc/types.h
@@ -116,10 +116,12 @@ typedef struct {
* @param curve A curve_t being generated
* @param cfg An application config
* @param args Current optional generator argument
+ * @param state The current generation state
* @return state diff
*/
-#define GENERATOR(gen_name) \
- int gen_name(curve_t *curve, const config_t *cfg, arg_t *args)
+#define GENERATOR(gen_name) \
+ int gen_name(curve_t *curve, const config_t *cfg, arg_t *args, \
+ offset_e state)
typedef GENERATOR((*gen_f));
diff --git a/test/src/exhaustive/test_ansi.c b/test/src/exhaustive/test_ansi.c
index 09e9e5c..3e3e4e1 100644
--- a/test/src/exhaustive/test_ansi.c
+++ b/test/src/exhaustive/test_ansi.c
@@ -33,7 +33,7 @@ TestSuite(ansi, .init = ansi_suite_setup, .fini = ansi_suite_teardown);
Test(ansi, test_seed_random) {
curve_t curve = {};
config_t cfg = {.bits = 256};
- int ret = ansi_gen_seed_random(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_random(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
cr_assert_not_null(curve.seed, );
@@ -45,7 +45,7 @@ Test(ansi, test_seed_argument) {
curve_t curve = {};
char *seed = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
config_t cfg = {.seed = seed, .bits = 256};
- int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
cr_assert_not_null(curve.seed, );
@@ -60,7 +60,7 @@ Test(ansi, test_seed_argument_hex) {
curve_t curve = {};
char *seed = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd";
config_t cfg = {.seed = seed, .bits = 256};
- int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
cr_assert_not_null(curve.seed, );
@@ -76,7 +76,7 @@ Test(ansi, test_seed_input) {
char *seed = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
config_t cfg = {.bits = 256};
fprintf(write_in, "%s\n", seed);
- int ret = ansi_gen_seed_input(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_input(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
cr_assert_not_null(curve.seed, );
@@ -92,7 +92,7 @@ Test(ansi, test_seed_input_short) {
char *seed = "abcdef";
config_t cfg = {};
fprintf(write_in, "%s\n", seed);
- int ret = ansi_gen_seed_input(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_input(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 0, );
}
@@ -175,10 +175,10 @@ ParameterizedTest(struct prime_params *param, ansi, test_seed_prime_examples) {
bits_t *p = bits_from_hex(param->p);
curve.field = bits_to_i(p);
- int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
- ret = ansi_gen_equation(&curve, &cfg, NULL);
+ ret = ansi_gen_equation(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
GEN expected_r = bits_to_i(bits_from_hex(param->r));
cr_assert(gequal(curve.seed->ansi.r, expected_r), );
@@ -278,10 +278,10 @@ ParameterizedTest(struct binary_params *param, ansi,
GEN expected_b = bits_to_i(bits_from_hex(param->b));
bits_t *b = bits_from_i(expected_b);
- int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
- ret = ansi_gen_equation(&curve, &cfg, NULL);
+ ret = ansi_gen_equation(&curve, &cfg, NULL, OFFSET_SEED);
cr_assert_eq(ret, 1, );
GEN curve_b = field_elementi(curve.b);
cr_assert(gequal(curve_b, expected_b), );
diff --git a/test/src/gen/test_gp.c b/test/src/gen/test_gp.c
new file mode 100644
index 0000000..0d01a3a
--- /dev/null
+++ b/test/src/gen/test_gp.c
@@ -0,0 +1,109 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#include <criterion/criterion.h>
+#include "gen/gp.h"
+#include "test/default.h"
+#include "util/bits.h"
+
+TestSuite(gp, .init = default_setup, .fini = default_teardown);
+
+Test(gp, test_gp_seed) {
+ curve_t curve = {0};
+ config_t cfg = {};
+ arg_t arg = {.args = "() -> { return(Vecsmall([1,0])); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_SEED);
+ cr_assert_eq(ret, 1,);
+ cr_assert_not_null(curve.seed,);
+ cr_assert_not_null(curve.seed->seed,);
+ cr_assert(bits_eq(curve.seed->seed, bits_from_bin("10")),);
+}
+
+Test(gp, test_gp_field) {
+ curve_t curve = {0};
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed) -> { return(19); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_FIELD);
+ cr_assert_eq(ret, 1,);
+ cr_assert(gequal(curve.field, stoi(19)),);
+}
+
+Test(gp, test_gp_a) {
+ curve_t curve = {.field = stoi(19)};
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field) -> { return(Mod(3,field)); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_A);
+ cr_assert_eq(ret, 1,);
+ cr_assert(gequal(curve.a, mkintmodu(3, 19)),);
+}
+
+Test(gp, test_gp_b) {
+ curve_t curve = {.field = stoi(19), .a = mkintmodu(3, 19)};
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field, a) -> { return(a * 2); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_B);
+ cr_assert_eq(ret, 1,);
+ cr_assert(gequal(curve.b, mkintmodu(6, 19)),);
+}
+
+Test(gp, test_gp_curve) {
+ curve_t curve = {.field = stoi(19), .a = mkintmodu(3, 19), .b = mkintmodu(6, 19)};
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field, a, b) -> { return(ellinit([a,b], field)); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_CURVE);
+ cr_assert_eq(ret, 1,);
+ cr_assert(gequal(curve.curve, ellinit(mkvec2(curve.a, curve.b), curve.field, 0)),);
+}
+
+Test(gp, test_gp_order) {
+ curve_t curve = {.field = stoi(19), .a = mkintmodu(3, 19), .b = mkintmodu(6, 19),
+ .curve = ellinit(mkvec2(stoi(3), stoi(6)), stoi(19), 0)};
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field, a, b, curve) -> { return(ellsea(curve)); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_ORDER);
+ cr_assert_eq(ret, 1,);
+ cr_assert(gequal(ellsea(curve.curve, 0), curve.order),);
+}
+
+Test(gp, test_gp_generators) {
+ curve_t curve = {.field = stoi(19), .a = mkintmodu(3, 19), .b = mkintmodu(6, 19),
+ .curve = ellinit(mkvec2(stoi(3), stoi(6)), stoi(19), 0), .order = stoi(16)
+ };
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field, a, b, curve, order) -> { return(ellgenerators(curve)); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_GENERATORS);
+ cr_assert_eq(ret, 1,);
+
+ GEN ellgens = ellgenerators(curve.curve);
+ long len = glength(ellgens);
+ cr_assert_eq(len, curve.ngens,);
+ for (long i = 1; i <= len; ++i) {
+ cr_assert(gequal(gel(ellgens, i), curve.generators[i - 1]->point),);
+ }
+}
+
+Test(gp, test_gp_points) {
+ curve_t curve = {.field = stoi(19), .a = mkintmodu(3, 19), .b = mkintmodu(6, 19),
+ .curve = ellinit(mkvec2(stoi(3), stoi(6)), stoi(19), 0), .order = stoi(16),
+ };
+ point_t gen = {.point = mkvec2(mkintmodu(4,19), mkintmodu(14,19))};
+ point_t *generators[1] = {&gen};
+ curve.generators = generators;
+ curve.ngens = 1;
+
+ config_t cfg = {};
+ arg_t arg = {.args = "(seed, field, a, b, curve, order, gens) -> { return([ellmul(curve,gens[1],2)]); }", .nargs = 1};
+
+ int ret = gp_gen(&curve, &cfg, &arg, OFFSET_POINTS);
+ cr_assert_eq(ret, 1,);
+ cr_assert_eq(curve.npoints, 1,);
+ cr_assert(gequal(curve.points[0]->point, ellmul(curve.curve, gen.point, stoi(2))),);
+} \ No newline at end of file
diff --git a/test/src/gen/test_point.c b/test/src/gen/test_point.c
index d77f83d..d185e9a 100644
--- a/test/src/gen/test_point.c
+++ b/test/src/gen/test_point.c
@@ -14,7 +14,7 @@ Test(point, test_point_random) {
GEN e = ellinit(mkvec2s(1, 3), stoi(23), -1);
curve_t curve = {.order = stoi(27), .curve = e};
config_t cfg = {};
- int ret = point_gen_random(&curve, &cfg, NULL);
+ int ret = point_gen_random(&curve, &cfg, NULL, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Point wasn't generated.");
cr_assert_eq(curve.npoints, 1, "Incorrect number of points.");
@@ -34,7 +34,7 @@ Test(point, test_points_random) {
config_t cfg = {};
size_t npoints = 3;
arg_t arg = {.args = &npoints, .nargs = 1};
- int ret = points_gen_random(&curve, &cfg, &arg);
+ int ret = points_gen_random(&curve, &cfg, &arg, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Points weren't generated.");
cr_assert_eq(curve.npoints, npoints, "Incorrect number of points.");
@@ -62,7 +62,7 @@ Test(point, test_points_trial) {
config_t cfg = {};
pari_ulong prime = 3;
arg_t arg = {.args = &prime, .nargs = 1};
- int ret = points_gen_trial(&curve, &cfg, &arg);
+ int ret = points_gen_trial(&curve, &cfg, &arg, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Points weren't generated.");
cr_assert_eq(curve.npoints, 1, "Incorrect number of points.");
@@ -90,7 +90,7 @@ Test(point, test_points_prime) {
.order = stoi(27), .curve = e, .ngens = 1, .generators = gens};
config_t cfg = {};
pari_ulong prime = 3;
- int ret = points_gen_prime(&curve, &cfg, NULL);
+ int ret = points_gen_prime(&curve, &cfg, NULL, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Points weren't generated.");
cr_assert_eq(curve.npoints, 1, "Incorrect number of points.");
@@ -119,7 +119,7 @@ Test(point, test_points_all) {
config_t cfg = {};
GEN orders = mkvec3s(3, 9, 27);
size_t npoints = 3;
- int ret = points_gen_allgroups(&curve, &cfg, NULL);
+ int ret = points_gen_allgroups(&curve, &cfg, NULL, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Points weren't generated.");
cr_assert_eq(curve.npoints, npoints, "Incorrect number of points.");
@@ -150,7 +150,7 @@ Test(point, test_points_nonprime) {
config_t cfg = {};
GEN orders = mkvec2s(9, 27);
size_t npoints = 2;
- int ret = points_gen_nonprime(&curve, &cfg, NULL);
+ int ret = points_gen_nonprime(&curve, &cfg, NULL, OFFSET_POINTS);
cr_assert_eq(ret, 1, "Points weren't generated.");
cr_assert_eq(curve.npoints, npoints, "Incorrect number of points.");