diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cm/cm.c | 1 | ||||
| -rw-r--r-- | src/exhaustive/exhaustive.c | 3 | ||||
| -rw-r--r-- | src/io/cli.c | 13 | ||||
| -rw-r--r-- | src/io/config.h | 2 | ||||
| -rw-r--r-- | src/math/order.c | 33 | ||||
| -rw-r--r-- | src/math/order.h | 17 | ||||
| -rw-r--r-- | src/math/point.c | 54 | ||||
| -rw-r--r-- | src/math/point.h | 13 | ||||
| -rw-r--r-- | src/math/poly.c | 2 | ||||
| -rw-r--r-- | src/math/poly.h | 8 | ||||
| -rw-r--r-- | src/math/random.c | 13 | ||||
| -rw-r--r-- | src/math/random.h | 19 | ||||
| -rw-r--r-- | src/util/macro.h | 14 | ||||
| -rw-r--r-- | src/util/memory.h | 7 |
14 files changed, 173 insertions, 26 deletions
diff --git a/src/cm/cm.c b/src/cm/cm.c index f91cddf..027f761 100644 --- a/src/cm/cm.c +++ b/src/cm/cm.c @@ -3,7 +3,6 @@ * Copyright (C) 2017 J08nY */ #include "cm.h" -#include "exhaustive/anomalous.h" #include "io/output.h" #include "p1363.h" diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c index b4fbbd9..eb2c69e 100644 --- a/src/exhaustive/exhaustive.c +++ b/src/exhaustive/exhaustive.c @@ -87,6 +87,9 @@ static void exhaustive_ginit(gen_t *generators, const config_t *cfg) { case POINTS_PRIME: generators[OFFSET_POINTS] = &points_gen_prime; break; + case POINTS_ALL: + generators[OFFSET_POINTS] = &points_gen_allgroups; + break; case POINTS_NONE: generators[OFFSET_POINTS] = &gen_skip; break; diff --git a/src/io/cli.c b/src/io/cli.c index dadb65e..d4114c4 100644 --- a/src/io/cli.c +++ b/src/io/cli.c @@ -42,6 +42,7 @@ struct argp_option cli_options[] = { {0, 0, 0, 0, "Field specification:", 1}, {"fp", OPT_FP, 0, 0, "Prime field.", 1}, {"f2m", OPT_F2M, 0, 0, "Binary field.", 1}, + {0, 0, 0, 0, "Generation options:", 2}, {"random", OPT_RANDOM, 0, 0, "Generate a random curve (using Random approach).", 2}, {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 2}, @@ -49,17 +50,19 @@ struct argp_option cli_options[] = { {"koblitz", OPT_KOBLITZ, 0, 0, "Generate a Koblitz curve (a = 0).", 2}, {"unique", OPT_UNIQUE, 0, 0, "Generate a curve with only one generator.", 2}, {"anomalous", OPT_ANOMALOUS, 0, 0, "Generate an anomalous curve (of trace one, with field order equal to curve order).", 2}, - {"points", OPT_POINTS, "TYPE", 0, "Generate points of given type (random/prime/none).", 2}, + {"points", OPT_POINTS, "TYPE", 0, "Generate points of given type (random/prime/all/none).", 2}, {"seed", OPT_SEED, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure). **NOT IMPLEMENTED**", 2}, {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves, for a given curve (using Invalid curve algorithm).", 2}, {"order", OPT_ORDER, "ORDER", 0, "Generate a curve with given order (using Complex Multiplication). **NOT IMPLEMENTED**", 2}, {"count", OPT_COUNT, "COUNT", 0, "Generate multiple curves.", 2}, + {0, 0, 0, 0, "Input/Output options:", 3}, {"format", OPT_FORMAT, "FORMAT", 0, "Format to output in. One of [csv,json], default is json.", 3}, {"input", OPT_INPUT, "FILE", 0, "Input from file.", 3}, {"output", OPT_OUTPUT, "FILE", 0, "Output into file. Overwrites any existing file!", 3}, {"append", OPT_APPEND, 0, 0, "Append to output file (don't overwrite).", 3}, {"verbose", OPT_VERBOSE, "FILE", OPTION_ARG_OPTIONAL, "Verbose logging (to stdout or file).", 3}, + {0, 0, 0, 0, "Other:", 4}, {"data-dir", OPT_DATADIR, "DIR", 0, "Set PARI/GP data directory (containing seadata package).", 4}, {"memory", OPT_MEMORY, "SIZE", 0, "Use PARI stack of SIZE (can have suffix k/m/g).", 4}, @@ -186,16 +189,18 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { break; case OPT_POINTS: if (arg) { + long pts = strtol(arg, NULL, 10); + cfg->points.amount = (size_t)pts; if (strstr(arg, "random")) { - long pts = strtol(arg, NULL, 10); cfg->points.type = POINTS_RANDOM; - cfg->points.amount = (size_t)pts; } else if (strstr(arg, "prime")) { cfg->points.type = POINTS_PRIME; + } else if (strstr(arg, "all")) { + cfg->points.type = POINTS_ALL; } else if (strstr(arg, "none")) { cfg->points.type = POINTS_NONE; } else { - argp_failure(state, 1, 0, "Unknow point type"); + argp_failure(state, 1, 0, "Unknown point type."); } } else { argp_failure(state, 1, 0, diff --git a/src/io/config.h b/src/io/config.h index 42a48be..5186c67 100644 --- a/src/io/config.h +++ b/src/io/config.h @@ -13,7 +13,7 @@ enum field_e { FIELD_PRIME, FIELD_BINARY }; enum format_e { FORMAT_JSON, FORMAT_CSV }; -enum points_e { POINTS_PRIME, POINTS_RANDOM, POINTS_NONE }; +enum points_e { POINTS_PRIME, POINTS_RANDOM, POINTS_ALL, POINTS_NONE }; struct points_s { enum points_e type; size_t amount; diff --git a/src/math/order.c b/src/math/order.c index 4c8c728..347015c 100644 --- a/src/math/order.c +++ b/src/math/order.c @@ -4,6 +4,39 @@ */ #include "order.h" +GEN order_factors(curve_t *curve, const config_t *cfg) { + if (cfg->prime) { + return gtovec(curve->order); + } else { + GEN factors = Z_factor(curve->order); + return gel(factors, 1); + } +} + +GEN order_groups(curve_t *curve, const config_t *cfg, GEN factors) { + long nprimes = glength(factors); + if (cfg->prime) { + return gtovec(curve->order); + } else { + GEN amount = int2n(nprimes); + GEN groups = gtovec0(gen_0, itos(amount) - 1); + + for (size_t count = 1; count < (size_t)(1 << nprimes); ++count) { + GEN result = gen_1; + for (long bit = 0; bit < nprimes; ++bit) { + size_t mask = (size_t)(1 << bit); + if (count & mask) { + result = mulii(result, gel(factors, bit + 1)); + } + } + gel(groups, count) = result; + } + // TODO: sort this, as it is not necessarily sorted, in fact most likely + // not + return groups; + } +} + GENERATOR(order_gen_any) { GEN ord = ellff_get_card(curve->curve); if (isclone(ord)) { diff --git a/src/math/order.h b/src/math/order.h index 8a56b94..ce3cd0b 100644 --- a/src/math/order.h +++ b/src/math/order.h @@ -11,6 +11,23 @@ #include "types.h" /** + * @brief Factors curve order. + * @param curve + * @param cfg + * @return + */ +GEN order_factors(curve_t *curve, const config_t *cfg); + +/** + * @brief Enumerates all subgroup orders of a curve given prime order factors. + * @param curve + * @param cfg + * @param factors + * @return + */ +GEN order_groups(curve_t *curve, const config_t *cfg, GEN factors); + +/** * GENERATOR(gen_t) * Calculates the curve order, using a general algorithm. * Always succeeds. diff --git a/src/math/point.c b/src/math/point.c index f590ca2..4251913 100644 --- a/src/math/point.c +++ b/src/math/point.c @@ -3,6 +3,7 @@ * Copyright (C) 2017 J08nY */ #include "point.h" +#include "order.h" #include "util/memory.h" point_t *point_new(void) { return try_calloc(sizeof(point_t)); } @@ -176,8 +177,7 @@ GENERATOR(points_gen_trial) { GENERATOR(points_gen_prime) { // TODO stack code!!! - GEN factors = Z_factor(curve->order); - GEN primes = gel(factors, 1); + GEN primes = order_factors(curve, cfg); long nprimes = glength(primes); curve->points = points_new((size_t)nprimes); @@ -195,14 +195,13 @@ GENERATOR(points_gen_prime) { // primes[i] divides ord // mul = ord/primes[i] - GEN p = gcopy(gel(primes, i)); - GEN mul = divii(ord, p); + GEN mul = divii(ord, gel(primes, i)); GEN point = ellmul(curve->curve, rand, mul); curve->points[i - 1] = point_new(); - gerepileall(ftop, 2, &point, &p); + gerepileall(ftop, 1, &point); curve->points[i - 1]->point = point; - curve->points[i - 1]->order = p; + curve->points[i - 1]->order = gcopy(gel(primes, i)); npoints++; } } @@ -211,6 +210,49 @@ GENERATOR(points_gen_prime) { return 1; } +GENERATOR(points_gen_allgroups) { + // TODO stack code!!! + + GEN primes = order_factors(curve, cfg); + + GEN groups = order_groups(curve, cfg, primes); + long ngroups = glength(groups); + + curve->points = points_new((size_t)ngroups); + curve->npoints = (size_t)ngroups; + + long npoints = 0; + while (npoints < ngroups) { + GEN rand = genrand(curve->curve); + GEN ord = ellorder(curve->curve, rand, NULL); + + for (long i = 1; i <= ngroups; ++i) { + pari_sp ftop = avma; + GEN num = gel(groups, i); + + if (curve->points[i - 1] == NULL) { + GEN point = NULL; + if (equalii(ord, num)) { + point = gcopy(rand); + } else if (dvdii(ord, num)) { + GEN mul = divii(ord, num); + point = ellmul(curve->curve, rand, mul); + } + + if (point) { + curve->points[i - 1] = point_new(); + gerepileall(ftop, 1, &point); + curve->points[i - 1]->point = point; + curve->points[i - 1]->order = gcopy(num); + ++npoints; + } + } + } + } + + return 1; +} + UNROLL(points_unroll) { if (curve->points) { points_free_deep(&curve->points, curve->npoints); diff --git a/src/math/point.h b/src/math/point.h index 49c37c6..a25ec2c 100644 --- a/src/math/point.h +++ b/src/math/point.h @@ -159,6 +159,19 @@ GENERATOR(points_gen_trial); GENERATOR(points_gen_prime); /** + * GENERATOR(gen_t) + * + * Generates points on all subgroups of the curve. Prime and non-prime order. + * + * @param curve + * @param cfg + * @param args + * @return + */ +GENERATOR(points_gen_allgroups); + +/** + * UNROLL(unroll_t) * * @param curve * @param cfg diff --git a/src/math/poly.c b/src/math/poly.c index 50d0da0..2b655da 100644 --- a/src/math/poly.c +++ b/src/math/poly.c @@ -2729,7 +2729,7 @@ polynomial_t *poly_find(unsigned long m) { len_penta = sizeof(hp_pentanomials) / sizeof(polynomial_t); } - polynomial_t searched = {(int)m}; + polynomial_t searched = {(unsigned int)m}; polynomial_t *tri = (polynomial_t *)bsearch( &searched, search_tri, len_tri, sizeof(polynomial_t), &compare_poly); if (tri) { diff --git a/src/math/poly.h b/src/math/poly.h index 664ca6b..83b909a 100644 --- a/src/math/poly.h +++ b/src/math/poly.h @@ -12,10 +12,10 @@ #include <stdbool.h> typedef struct { - int m; - int e1; - int e2; - int e3; + unsigned int m; + unsigned int e1; + unsigned int e2; + unsigned int e3; } polynomial_t; /** diff --git a/src/math/random.c b/src/math/random.c index da4bc2c..519ce6b 100644 --- a/src/math/random.c +++ b/src/math/random.c @@ -3,6 +3,7 @@ * Copyright (C) 2017 J08nY */ #define _POSIX_C_SOURCE 200809L + #include "random.h" #include <time.h> @@ -43,13 +44,11 @@ GEN random_prime(unsigned long bits) { gel(range, 2) = powis(gen_2, bits); GEN p; - { - pari_sp btop = avma; - do { - p = randomprime(range); - p = gerepileupto(btop, p); - } while (!isprime(p)); - } + pari_sp btop = avma; + do { + p = randomprime(range); + p = gerepileupto(btop, p); + } while (!isprime(p)); return gerepilecopy(ltop, p); } diff --git a/src/math/random.h b/src/math/random.h index de03abb..1152bb5 100644 --- a/src/math/random.h +++ b/src/math/random.h @@ -11,10 +11,29 @@ #include <pari/pari.h> #include <stdbool.h> +/** + * @brief Init the PARI-GP random generator. + * + * Initializes the PARI-GP random generator, tries to do so from + * cryptographically strong sources(/dev/urandom) at first but falls back on + * clock_gettime and {@link time(NULL)}. + * + * @return Whether the initialization was successful. + */ bool random_init(void); +/** + * @brief Generate random <code>bits</code> sized prime. + * @param bits the size of the prime to generate + * @return a random prime in range [2^(bits - 1), 2^bits] + */ GEN random_prime(unsigned long bits); +/** + * @brief Generate random <code>bits</code> sized integer. + * @param bits the size of the integer to generate + * @return a random integer in range [2^(bits - 1), 2^bits] + */ GEN random_int(unsigned long bits); #endif // ECGEN_RANDOM_H diff --git a/src/util/macro.h b/src/util/macro.h new file mode 100644 index 0000000..abe2c5f --- /dev/null +++ b/src/util/macro.h @@ -0,0 +1,14 @@ +/* + * ecgen, tool for generating Elliptic curve domain parameters + * Copyright (C) 2017 J08nY + */ +/** + * @file macro.h + */ +#ifndef ECGEN_MACRO_H +#define ECGEN_MACRO_H + +#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N +#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +#endif // ECGEN_MACRO_H diff --git a/src/util/memory.h b/src/util/memory.h index fef237e..8b85a3d 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -2,11 +2,14 @@ * ecgen, tool for generating Elliptic curve domain parameters * Copyright (C) 2017 J08nY */ -#include <stddef.h> - +/** + * @file memory.h + */ #ifndef ECGEN_MEMORY_H #define ECGEN_MEMORY_H +#include <stddef.h> + /** * @brief * @param size |
