diff options
| -rw-r--r-- | src/exhaustive/brainpool.c | 25 | ||||
| -rw-r--r-- | src/exhaustive/brainpool.h | 15 | ||||
| -rw-r--r-- | src/exhaustive/brainpool_rfc.c | 77 | ||||
| -rw-r--r-- | src/exhaustive/brainpool_rfc.h | 12 | ||||
| -rw-r--r-- | src/exhaustive/exhaustive.c | 21 | ||||
| -rw-r--r-- | src/io/cli.c | 82 | ||||
| -rw-r--r-- | test/src/exhaustive/test_ansi.c | 3 | ||||
| -rw-r--r-- | test/src/exhaustive/test_brainpool.c | 5 |
8 files changed, 176 insertions, 64 deletions
diff --git a/src/exhaustive/brainpool.c b/src/exhaustive/brainpool.c index a399617..1c8fb31 100644 --- a/src/exhaustive/brainpool.c +++ b/src/exhaustive/brainpool.c @@ -3,7 +3,6 @@ * Copyright (C) 2017 J08nY */ -#include <misc/types.h> #include "brainpool.h" #include "gen/seed.h" #include "io/output.h" @@ -20,12 +19,11 @@ static void seed_wv(seed_t *seed) { pari_sp ltop = avma; GEN L = utoi(cfg->bits); seed->brainpool.v = itou(gfloor(gdivgs(subis(L, 1), 160))); - seed->brainpool.w = - itou(subis(subis(L, 160 * seed->brainpool.v), 1)); + seed->brainpool.w = itou(subis(subis(L, 160 * seed->brainpool.v), 1)); avma = ltop; } -static void brainpool_update_seed(bits_t *s) { +void brainpool_update_seed(bits_t *s) { pari_sp ltop = avma; GEN z = bits_to_i(s); GEN t = Fp_add(z, gen_1, int2n(160)); @@ -35,7 +33,7 @@ static void brainpool_update_seed(bits_t *s) { bits_free(&result); } -static bits_t *brainpool_hash(const bits_t *s, long w, long v) { +bits_t *brainpool_hash(const bits_t *s, long w, long v) { pari_sp ltop = avma; unsigned char h[20]; bits_sha1(s, h); @@ -48,9 +46,9 @@ static bits_t *brainpool_hash(const bits_t *s, long w, long v) { bits_sha1(si, hashout + (20 * (i - 1))); bits_free(&si); } - bits_t *result = bits_from_raw(h, 20*8); - bits_shortenz(result, 20*8 - w); - bits_t *rest = bits_from_raw(hashout, (size_t) (20 * v * 8)); + bits_t *result = bits_from_raw(h, 20 * 8); + bits_shortenz(result, 20 * 8 - w); + bits_t *rest = bits_from_raw(hashout, (size_t)(20 * v * 8)); bits_concatz(result, rest, NULL); bits_free(&rest); avma = ltop; @@ -104,7 +102,8 @@ GENERATOR(brainpool_gen_field) { brainpool_update_seed(seed->seed); seed->brainpool.update_seed = false; } - bits_t *p_bits = brainpool_hash(seed->seed, seed->brainpool.w + 1, seed->brainpool.v); + bits_t *p_bits = brainpool_hash(seed->seed, seed->brainpool.w + 1, + seed->brainpool.v); GEN c = bits_to_i(p_bits); bits_free(&p_bits); GEN p = c; @@ -147,7 +146,7 @@ GENERATOR(brainpool_gen_equation) { GEN z; bits_t *a_bits = - brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); + brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); GEN a = bits_to_i(a_bits); bits_free(&a_bits); z = Fp_sqrtn(a, stoi(4), curve->field, NULL); @@ -161,7 +160,7 @@ GENERATOR(brainpool_gen_equation) { brainpool_update_seed(seed->seed); bits_t *b_bits = - brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); + brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); GEN b = bits_to_i(b_bits); bits_free(&b_bits); if (!Fp_issquare(b, curve->field)) { @@ -176,7 +175,7 @@ GENERATOR(brainpool_gen_equation) { GEN mod_b = gmodulo(b, curve->field); if (gequal0(gmulsg(-16, gadd(gmulsg(4, gpowgs(mod_a, 3)), - gmulsg(27, gsqr(mod_b)))))) { + gmulsg(27, gsqr(mod_b)))))) { brainpool_update_seed(seed->seed); bits_free(&seed->brainpool.seed_a); bits_free(&seed->brainpool.seed_b); @@ -188,7 +187,7 @@ GENERATOR(brainpool_gen_equation) { seed->brainpool.seed_bp = bits_copy(seed->seed); bits_t *mult_bits = - brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); + brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); seed->brainpool.mult = bits_to_i(mult_bits); curve->a = mod_a; diff --git a/src/exhaustive/brainpool.h b/src/exhaustive/brainpool.h index 188780b..741bf2f 100644 --- a/src/exhaustive/brainpool.h +++ b/src/exhaustive/brainpool.h @@ -9,6 +9,21 @@ #include "misc/types.h" /** + * + * @param s + */ +void brainpool_update_seed(bits_t *s); + +/** + * + * @param s + * @param w + * @param v + * @return + */ +bits_t *brainpool_hash(const bits_t *s, long w, long v); + +/** * @brief * @param hex_str * @return diff --git a/src/exhaustive/brainpool_rfc.c b/src/exhaustive/brainpool_rfc.c index 7af6b29..b3c5e5e 100644 --- a/src/exhaustive/brainpool_rfc.c +++ b/src/exhaustive/brainpool_rfc.c @@ -4,19 +4,88 @@ */ #include "brainpool_rfc.h" +#include "brainpool.h" +#include "util/bits.h" -GENERATOR(brainpool_rfc_gen_seed_random) { - -} +#define brainpool_delegate(func) \ + int ret = func(curve, args, state); \ + if (ret != 1) { \ + return ret; \ + } \ + curve->seed->type = SEED_BRAINPOOL_RFC; \ + return 1; GENERATOR(brainpool_rfc_gen_seed_argument) { + brainpool_delegate(brainpool_gen_seed_argument); +} +GENERATOR(brainpool_rfc_gen_seed_random) { + brainpool_delegate(brainpool_gen_seed_random); } GENERATOR(brainpool_rfc_gen_seed_input) { - + brainpool_delegate(brainpool_gen_seed_input); } GENERATOR(brainpool_rfc_gen_equation) { + // field is definitely prime + pari_sp btop = avma; + seed_t *seed = curve->seed; + do { + if (seed->brainpool.update_seed) { + brainpool_update_seed(seed->seed); + seed->brainpool.update_seed = false; + } + + GEN z; + bits_t *a_bits = + brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); + GEN a = bits_to_i(a_bits); + bits_free(&a_bits); + z = Fp_sqrtn(a, stoi(4), curve->field, NULL); + if (z == NULL) { + brainpool_update_seed(seed->seed); + avma = btop; + continue; + } + seed->brainpool.seed_a = bits_copy(seed->seed); + + GEN b; + do { + brainpool_update_seed(seed->seed); + bits_t *b_bits = brainpool_hash(seed->seed, seed->brainpool.w, + seed->brainpool.v); + b = bits_to_i(b_bits); + bits_free(&b_bits); + } while (Fp_issquare(b, curve->field)); + + seed->brainpool.seed_b = bits_copy(seed->seed); + + GEN mod_a = gmodulo(a, curve->field); + GEN mod_b = gmodulo(b, curve->field); + + if (gequal0(gmulsg(-16, gadd(gmulsg(4, gpowgs(mod_a, 3)), + gmulsg(27, gsqr(mod_b)))))) { + brainpool_update_seed(seed->seed); + bits_free(&seed->brainpool.seed_a); + bits_free(&seed->brainpool.seed_b); + avma = btop; + continue; + } + + brainpool_update_seed(seed->seed); + seed->brainpool.seed_bp = bits_copy(seed->seed); + + bits_t *mult_bits = + brainpool_hash(seed->seed, seed->brainpool.w, seed->brainpool.v); + seed->brainpool.mult = bits_to_i(mult_bits); + + curve->a = mod_a; + curve->b = mod_b; + gerepileall(btop, 2, &curve->a, &curve->b); + break; + } while (true); + seed->brainpool.update_seed = true; + return 1; }
\ No newline at end of file diff --git a/src/exhaustive/brainpool_rfc.h b/src/exhaustive/brainpool_rfc.h index ade7068..c838419 100644 --- a/src/exhaustive/brainpool_rfc.h +++ b/src/exhaustive/brainpool_rfc.h @@ -9,25 +9,25 @@ #include "misc/types.h" /** - * @brief + * * @param curve * @param args * @param state * @return */ -GENERATOR(brainpool_rfc_gen_seed_random); +GENERATOR(brainpool_rfc_gen_seed_argument); /** - * @brief + * * @param curve * @param args * @param state * @return */ -GENERATOR(brainpool_rfc_gen_seed_argument); +GENERATOR(brainpool_rfc_gen_seed_random); /** - * @brief + * * @param curve * @param args * @param state @@ -44,4 +44,4 @@ GENERATOR(brainpool_rfc_gen_seed_input); */ GENERATOR(brainpool_rfc_gen_equation); -#endif //ECGEN_BRAINPOOL_RFC_H +#endif // ECGEN_BRAINPOOL_RFC_H diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c index 9c2dfdd..ee475ff 100644 --- a/src/exhaustive/exhaustive.c +++ b/src/exhaustive/exhaustive.c @@ -6,6 +6,7 @@ #include "anomalous.h" #include "ansi.h" #include "brainpool.h" +#include "brainpool_rfc.h" #include "check.h" #include "gen/curve.h" #include "gen/equation.h" @@ -70,11 +71,24 @@ static void exhaustive_ginit(gen_f *generators) { } } generators[OFFSET_FIELD] = &brainpool_gen_field; - generators[OFFSET_A] = &gen_skip; + generators[OFFSET_A] = &gen_skip; generators[OFFSET_B] = &brainpool_gen_equation; } break; - case SEED_BRAINPOOL_RFC: - break; + case SEED_BRAINPOOL_RFC: { + if (cfg->seed) { + generators[OFFSET_SEED] = &brainpool_rfc_gen_seed_argument; + } else { + if (cfg->random) { + generators[OFFSET_SEED] = + &brainpool_rfc_gen_seed_random; + } else { + generators[OFFSET_SEED] = &brainpool_rfc_gen_seed_input; + } + } + generators[OFFSET_FIELD] = &brainpool_gen_field; + generators[OFFSET_A] = &gen_skip; + generators[OFFSET_B] = &brainpool_rfc_gen_equation; + } break; case SEED_FIPS: break; default: @@ -144,7 +158,6 @@ static void exhaustive_ginit(gen_f *generators) { generators[OFFSET_GENERATORS] = &gens_gen_any; } - switch (cfg->points.type) { case POINTS_RANDOM: if (cfg->points.amount) { diff --git a/src/io/cli.c b/src/io/cli.c index 63a69be..702081b 100644 --- a/src/io/cli.c +++ b/src/io/cli.c @@ -40,48 +40,50 @@ enum opt_keys { OPT_ANOMALOUS, OPT_GPGEN, OPT_GPCHECK, - OPT_HEXCHECK + OPT_HEXCHECK, + OPT_BRAINPOOL_RFC }; // clang-format off 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, "Field specification:", 1}, + {"fp", OPT_FP, 0, 0, "Prime field.", 1}, + {"f2m", OPT_F2M, 0, 0, "Binary field.", 1}, - {0, 0, 0, 0, "Generation methods:", 2}, - {"order", OPT_ORDER, "ORDER", 0, "Generate a curve with given order (using Complex Multiplication). **NOT IMPLEMENTED**", 2}, - {"anomalous", OPT_ANOMALOUS, 0, 0, "Generate an anomalous curve (of trace one, with field order equal to curve order).", 2}, - {"ansi", OPT_ANSI, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure).", 2}, - {"brainpool", OPT_BRAINPOOL, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (Brainpool procedure).", 2}, - {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves, for a given curve (using Invalid curve algorithm).", 2}, + {0, 0, 0, 0, "Generation methods:", 2}, + {"order", OPT_ORDER, "ORDER", 0, "Generate a curve with given order (using Complex Multiplication). **NOT IMPLEMENTED**", 2}, + {"anomalous", OPT_ANOMALOUS, 0, 0, "Generate an anomalous curve (of trace one, with field order equal to curve order).", 2}, + {"ansi", OPT_ANSI, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure).", 2}, + {"brainpool", OPT_BRAINPOOL, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (Brainpool procedure).", 2}, + {"brainpool-rfc", OPT_BRAINPOOL_RFC, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (Brainpool procedure, as per RFC 5639).", 2}, + {"invalid", OPT_INVALID, 0, 0, "Generate a set of invalid curves, for a given curve (using Invalid curve algorithm).", 2}, - {0, 0, 0, 0, "Generation options:", 3}, - {"random", OPT_RANDOM, 0, 0, "Generate a random curve (using Random approach).", 3}, - {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 3}, - {"cofactor", OPT_COFACTOR, "BOUND", 0, "Generate a curve with cofactor up to BOUND.", 3}, - {"koblitz", OPT_KOBLITZ, "A", OPTION_ARG_OPTIONAL,"Generate a Koblitz curve (a in {0, 1}, b = 1).", 3}, - {"unique", OPT_UNIQUE, 0, 0, "Generate a curve with only one generator.", 3}, - {"gp-gen", OPT_GPGEN, "FUNC", 0, "Generate a curve param using a GP function. **NOT IMPLEMENTED**", 3}, - {"gp-check", OPT_GPCHECK, "FUNC", 0, "Check a generated curve param using a GP function. **NOT IMPLEMENTED**", 3}, - {"hex-check", OPT_HEXCHECK, "HEX", 0, "Check a generated curve param hex expansion for the HEX string.", 3}, - {"points", OPT_POINTS, "TYPE", 0, "Generate points of given type (random/prime/all/nonprime/none).", 3}, - {"count", OPT_COUNT, "COUNT", 0, "Generate multiple curves.", 3}, + {0, 0, 0, 0, "Generation options:", 3}, + {"random", OPT_RANDOM, 0, 0, "Generate a random curve (using Random approach).", 3}, + {"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 3}, + {"cofactor", OPT_COFACTOR, "BOUND", 0, "Generate a curve with cofactor up to BOUND.", 3}, + {"koblitz", OPT_KOBLITZ, "A", OPTION_ARG_OPTIONAL, "Generate a Koblitz curve (a in {0, 1}, b = 1).", 3}, + {"unique", OPT_UNIQUE, 0, 0, "Generate a curve with only one generator.", 3}, + {"gp-gen", OPT_GPGEN, "FUNC", 0, "Generate a curve param using a GP function. **NOT IMPLEMENTED**", 3}, + {"gp-check", OPT_GPCHECK, "FUNC", 0, "Check a generated curve param using a GP function. **NOT IMPLEMENTED**", 3}, + {"hex-check", OPT_HEXCHECK, "HEX", 0, "Check a generated curve param hex expansion for the HEX string.", 3}, + {"points", OPT_POINTS, "TYPE", 0, "Generate points of given type (random/prime/all/nonprime/none).", 3}, + {"count", OPT_COUNT, "COUNT", 0, "Generate multiple curves.", 3}, - {0, 0, 0, 0, "Input/Output options:", 4}, - {"format", OPT_FORMAT, "FORMAT", 0, "Format to output in. One of {csv, json}, default is json.", 4}, - {"input", OPT_INPUT, "FILE", 0, "Input from file.", 4}, - {"output", OPT_OUTPUT, "FILE", 0, "Output into file. Overwrites any existing file!", 4}, - {"append", OPT_APPEND, 0, 0, "Append to output file (don't overwrite).", 4}, - {"verbose", OPT_VERBOSE, "FILE", OPTION_ARG_OPTIONAL, "Verbose logging (to stdout or file).", 4}, + {0, 0, 0, 0, "Input/Output options:", 4}, + {"format", OPT_FORMAT, "FORMAT", 0, "Format to output in. One of {csv, json}, default is json.", 4}, + {"input", OPT_INPUT, "FILE", 0, "Input from file.", 4}, + {"output", OPT_OUTPUT, "FILE", 0, "Output into file. Overwrites any existing file!", 4}, + {"append", OPT_APPEND, 0, 0, "Append to output file (don't overwrite).", 4}, + {"verbose", OPT_VERBOSE, "FILE", OPTION_ARG_OPTIONAL, "Verbose logging (to stdout or file).", 4}, - {0, 0, 0, 0, "Other:", 5}, - {"data-dir", OPT_DATADIR, "DIR", 0, "Set PARI/GP data directory (containing seadata package).", 5}, - {"memory", OPT_MEMORY, "SIZE", 0, "Use PARI stack of SIZE (can have suffix k/m/g).", 5}, - {"threads", OPT_THREADS, "NUM", 0, "Use NUM threads.", 5}, - {"thread-stack", OPT_TSTACK, "SIZE", 0, "Use PARI stack of SIZE (per thread, can have suffix k/m/g).", 5}, - {"timeout", OPT_TIMEOUT, "TIME", 0, "Timeout computation of a curve parameter after TIME (can have suffix s/m/h/d).", 5}, - {0} + {0, 0, 0, 0, "Other:", 5}, + {"data-dir", OPT_DATADIR, "DIR", 0, "Set PARI/GP data directory (containing seadata package).", 5}, + {"memory", OPT_MEMORY, "SIZE", 0, "Use PARI stack of SIZE (can have suffix k/m/g).", 5}, + {"threads", OPT_THREADS, "NUM", 0, "Use NUM threads.", 5}, + {"thread-stack", OPT_TSTACK, "SIZE", 0, "Use PARI stack of SIZE (per thread, can have suffix k/m/g).", 5}, + {"timeout", OPT_TIMEOUT, "TIME", 0, "Timeout computation of a curve parameter after TIME (can have suffix s/m/h/d).", 5}, + {0} }; // clang-format on @@ -243,6 +245,18 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) { cfg->seed = arg; } break; + case OPT_BRAINPOOL_RFC: + cfg->method |= METHOD_SEED; + cfg->seed_algo = SEED_BRAINPOOL_RFC; + if (arg) { + if (!brainpool_seed_valid(arg)) { + argp_failure( + state, 1, 0, + "SEED must be exactly 160 bits (40 hex characters)."); + } + cfg->seed = arg; + } + break; /* Generation options */ case OPT_COUNT: diff --git a/test/src/exhaustive/test_ansi.c b/test/src/exhaustive/test_ansi.c index bbbe37a..6938bc1 100644 --- a/test/src/exhaustive/test_ansi.c +++ b/test/src/exhaustive/test_ansi.c @@ -153,7 +153,8 @@ ParameterizedTestParameters(ansi, test_ansi_seed_prime_examples) { size_t nb_params = sizeof(params) / sizeof(struct prime_params); return cr_make_param_array(struct prime_params, params, nb_params, NULL); } -ParameterizedTest(struct prime_params *param, ansi, test_ansi_seed_prime_examples) { +ParameterizedTest(struct prime_params *param, ansi, + test_ansi_seed_prime_examples) { cfg->bits = param->bits; cfg->field = FIELD_PRIME; cfg->seed = param->seed; diff --git a/test/src/exhaustive/test_brainpool.c b/test/src/exhaustive/test_brainpool.c index d71bbf7..fe3d90e 100644 --- a/test/src/exhaustive/test_brainpool.c +++ b/test/src/exhaustive/test_brainpool.c @@ -6,8 +6,8 @@ #include <criterion/criterion.h> #include <criterion/parameterized.h> #include "exhaustive/brainpool.h" -#include "test/io.h" #include "gen/seed.h" +#include "test/io.h" #include "util/bits.h" #include "util/memory.h" @@ -88,7 +88,8 @@ Test(brainpool, test_brainpool_equation) { brainpool_gen_seed_argument(&curve, NULL, OFFSET_SEED); - char *prime = "caa002c44829499e8239f049bddcaca373258a175fa337a82e0521744392cff1"; + char *prime = + "caa002c44829499e8239f049bddcaca373258a175fa337a82e0521744392cff1"; bits_t *prime_bits = bits_from_hex(prime); curve.field = bits_to_i(prime_bits); bits_free(&prime_bits); |
