diff options
| author | J08nY | 2017-10-01 02:50:57 +0200 |
|---|---|---|
| committer | J08nY | 2017-10-01 02:50:57 +0200 |
| commit | 6fea41693fa19734747103b5cf4d681613090bc1 (patch) | |
| tree | c58ff06c6b8379844eddb23eccf214edf816e6eb | |
| parent | 137390f09976235da012a1279e5ba64e54e1c6e1 (diff) | |
| parent | 75caf69b45fda59267790939cb8f180e4f3c3498 (diff) | |
| download | ecgen-6fea41693fa19734747103b5cf4d681613090bc1.tar.gz ecgen-6fea41693fa19734747103b5cf4d681613090bc1.tar.zst ecgen-6fea41693fa19734747103b5cf4d681613090bc1.zip | |
| -rw-r--r-- | src/exhaustive/ansi.c | 4 | ||||
| -rw-r--r-- | src/exhaustive/exhaustive.c | 5 | ||||
| -rw-r--r-- | src/gen/equation.c | 4 | ||||
| -rw-r--r-- | src/gen/field.c | 2 | ||||
| -rw-r--r-- | src/gen/gp.c | 120 | ||||
| -rw-r--r-- | src/gen/gp.h | 19 | ||||
| -rw-r--r-- | src/misc/types.h | 6 | ||||
| -rw-r--r-- | test/src/exhaustive/test_ansi.c | 18 | ||||
| -rw-r--r-- | test/src/gen/test_gp.c | 109 | ||||
| -rw-r--r-- | test/src/gen/test_point.c | 12 |
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."); |
