aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--src/Makefile2
-rw-r--r--src/cm/cm_any.c38
-rw-r--r--src/cm/cm_any.h6
-rw-r--r--src/exhaustive/exhaustive.c28
-rw-r--r--src/exhaustive/family.c193
-rw-r--r--src/exhaustive/family.h30
-rw-r--r--src/gen/point.c3
-rw-r--r--src/gen/seed.c2
-rw-r--r--src/io/cli.c39
-rw-r--r--src/io/output.c2
-rw-r--r--src/misc/config.h25
-rw-r--r--src/misc/types.h3
-rw-r--r--src/util/memory.c2
-rwxr-xr-xtest/ecgen.sh8
15 files changed, 374 insertions, 15 deletions
diff --git a/README.md b/README.md
index eeeab77..f4f1e8a 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ Tool for generating Elliptic curve domain parameters.
- `-s / --ansi[=SEED]` Generate a curve from `SEED` (ANSI X9.62 verifiable procedure).
- `-b / --brainpool[=SEED]`Generate a curve using the Brainpool verifiably pseudorandom algorithm from the original paper.
- `--brainpool-rfc[=SEED]` Generate a curve using the Brainpool verifiably pseudorandom algorithm as per RFC 5639.
+ - `-F / --family=FAMILY` Generate a pairing friendly curve from a curve family (e.g. "BN", "BLS12", "BLS24").
- `--nums` Generate a curve using the NUMS procedure (as per draft-black-numscurves-02).
- `--twist` Generate a twist of a given curve.
@@ -203,7 +204,7 @@ for Doxygen.
### Generation methods
-Four different EC curve parameters generation methods are implemented.
+Five different EC curve parameters generation methods are implemented.
[Efficient Algorithms for Generating Elliptic Curves over Finite Fields Suitable for Use in Cryptography - [Baier]](https://www.cdc.informatik.tu-darmstadt.de/reports/reports/harald_baier.diss.pdf)
@@ -258,6 +259,11 @@ Four different EC curve parameters generation methods are implemented.
- [Elliptic curves over F_p suitable for cryptosystems - [Miyaji]](https://dspace.jaist.ac.jp/dspace/bitstream/10119/4464/1/73-61.pdf)
- TODO: Extend with [Generating Anomalous Elliptic Curves - [Leprevost, Monnerat, Varrette, Vaydenay]](https://www.monnerat.info/publications/anomalous.pdf)
+#### Curve families
+
+ - Generates pairing friendly curves.
+ - Used with the `-F / --family` option. Select from BN, BLS12 or BLS24 currently.
+
### Build
ecgen can be built using Make or CMake. ecgen uses git submodules for testing at:
diff --git a/src/Makefile b/src/Makefile
index 6d5140b..54083c3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -14,7 +14,7 @@ FAST ?= 0
STATIC ?= 0
ifeq ($(DEBUG), 1)
- ECGEN_CFLAGS = -DDEBUG -g -Og -Werror -pedantic
+ ECGEN_CFLAGS = -DDEBUG -g -O0 -Werror -pedantic
else ifeq ($(TEST), 1)
ECGEN_CFLAGS = -DNDEBUG --coverage -g -O0
else ifeq ($(FAST), 1)
diff --git a/src/cm/cm_any.c b/src/cm/cm_any.c
index e1dab54..f948ac1 100644
--- a/src/cm/cm_any.c
+++ b/src/cm/cm_any.c
@@ -143,6 +143,7 @@ GEN cm_construct_curve(GEN order, GEN d, GEN p, bool ord_prime) {
GEN r = FpX_roots(H, p);
debug_log("roots = %Ps", r);
if (gequal(r, gtovec(gen_0))) {
+ avma = ltop;
return NULL;
}
@@ -206,6 +207,43 @@ GEN cm_construct_curve(GEN order, GEN d, GEN p, bool ord_prime) {
}
}
}
+ avma = ltop;
+ return NULL;
+}
+
+GEN cm_construct_curve_subgroup(GEN r, GEN d, GEN p) {
+ debug_log("Constructing a curve with r = %Pi, d = %Pi, p = %Pi", r, d,
+ p);
+ pari_sp ltop = avma;
+ GEN H = polclass(d, 0, 0);
+ debug_log("H = %Ps", H);
+
+ GEN roots = FpX_roots(H, p);
+ debug_log("roots = %Ps", roots);
+ if (gequal(roots, gtovec(gen_0))) {
+ avma = ltop;
+ return NULL;
+ }
+
+ long rlen = glength(roots);
+ pari_sp btop = avma;
+ for (long i = 1; i <= rlen; ++i) {
+ GEN root = gel(roots, i);
+ debug_log("trying root = %Pi", root);
+
+ GEN e = ellinit(ellfromj(mkintmod(root, p)), p, 0);
+ pari_CATCH(e_TYPE) { avma = btop; continue; }
+ pari_TRY { checkell(e); };
+ pari_ENDCATCH{};
+
+ GEN ord = ellff_get_card(e);
+ if (dvdii(ord, r)) {
+ debug_log("Got curve.");
+ return gerepilecopy(ltop, e);
+ }
+ avma = btop;
+ }
+ avma = ltop;
return NULL;
}
diff --git a/src/cm/cm_any.h b/src/cm/cm_any.h
index 42fc68e..a49fd7f 100644
--- a/src/cm/cm_any.h
+++ b/src/cm/cm_any.h
@@ -24,6 +24,12 @@ typedef struct {
GEN cm_construct_curve(GEN order, GEN d, GEN p, bool ord_prime);
/**
+ * @brief Construct an elliptic curve given a factor of its order, CM
+ * discriminant and field order.
+ */
+GEN cm_construct_curve_subgroup(GEN r, GEN d, GEN p);
+
+/**
* @brief
* @param curve
* @param args
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 6523170..bf915c0 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -8,6 +8,7 @@
#include "brainpool.h"
#include "brainpool_rfc.h"
#include "nums.h"
+#include "family.h"
#include "check.h"
#include "gen/curve.h"
#include "gen/equation.h"
@@ -137,6 +138,25 @@ static void exhaustive_ginit(gen_f *generators) {
default:
break;
}
+ } else if (cfg->method == METHOD_FAMILY) {
+ // setup family generators
+ if (GET_BOOL(random)) {
+ generators[OFFSET_SEED] = &family_gen_seed_random;
+ } else {
+ generators[OFFSET_SEED] = &family_gen_seed_input;
+
+ }
+ generators[OFFSET_FIELD] = &family_gen_field;
+ generators[OFFSET_A] = &gen_skip;
+ if (cfg->family == FAMILY_KSS16) {
+ generators[OFFSET_B] = &family_gen_equation_cm;
+ } else {
+ generators[OFFSET_B] = &family_gen_equation_iter;
+ }
+
+ //TODO make the prime check optional, based on cfg->prime.
+ generators[OFFSET_ORDER] = &family_gen_order;
+ generators[OFFSET_GENERATORS] = &gens_gen_any;
} else {
// setup normal generators
generators[OFFSET_SEED] = &gen_skip;
@@ -250,8 +270,6 @@ static void exhaustive_cinit(check_t **validators) {
if (cfg->method == METHOD_SEED) {
GET(seed_algo);
switch (cfg->seed_algo) {
- case SEED_ANSI:
- break;
case SEED_BRAINPOOL:
case SEED_BRAINPOOL_RFC: {
// TODO: Missing Brainpool CM disc check.
@@ -267,8 +285,6 @@ static void exhaustive_cinit(check_t **validators) {
check_new(gens_check_anomalous, brainpool_check_gens, NULL);
validators[OFFSET_GENERATORS] = gens_check;
} break;
- case SEED_FIPS:
- break;
default:
break;
}
@@ -310,7 +326,7 @@ static void exhaustive_ainit(arg_t **gen_argss, arg_t **check_argss) {
}
void exhaustive_uinit(unroll_f *unrolls) {
- if (cfg->seed_algo) {
+ if (cfg->seed_algo || cfg->method == METHOD_FAMILY) {
unrolls[OFFSET_SEED] = &seed_unroll;
} else {
unrolls[OFFSET_SEED] = &unroll_skip;
@@ -436,12 +452,14 @@ static void exhaustive_init(exhaustive_t *setup) {
exhaustive_cinit(setup->validators);
exhaustive_ainit(setup->gen_argss, setup->check_argss);
exhaustive_uinit(setup->unrolls);
+ family_init();
}
static void exhaustive_quit(exhaustive_t *setup) {
field_quit();
equation_quit();
nums_quit();
+ family_quit();
exhaustive_clear(setup);
}
diff --git a/src/exhaustive/family.c b/src/exhaustive/family.c
new file mode 100644
index 0000000..9d48026
--- /dev/null
+++ b/src/exhaustive/family.c
@@ -0,0 +1,193 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2024 J08nY
+ */
+
+#include "family.h"
+#include "cm/cm_any.h"
+#include "gen/seed.h"
+#include "misc/config.h"
+#include "util/random.h"
+
+#define FAMILIES (FAMILY_KSS40 + 1)
+
+static GEN nz_store[FAMILIES] = {0};
+static GEN pz_store[FAMILIES] = {0};
+static GEN rz_store[FAMILIES] = {0};
+static GEN tz_store[FAMILIES] = {0};
+static GEN D_store[FAMILIES] = {0};
+
+void family_init() {
+ pari_sp ltop = avma;
+ nz_store[FAMILY_BN] = gclone(closure_evalgen(compile_str("(z) -> z")));
+ pz_store[FAMILY_BN] = gclone(closure_evalgen(
+ compile_str("(z) -> 36*z^4 + 36*z^3 + 24*z^2 + 6*z + 1")));
+ rz_store[FAMILY_BN] = gclone(closure_evalgen(
+ compile_str("(z) -> 36*z^4 + 36*z^3 + 18*z^2 + 6*z + 1")));
+ tz_store[FAMILY_BN] =
+ gclone(closure_evalgen(compile_str("(z) -> 6*z + 1")));
+ D_store[FAMILY_BN] = gclone(stoi(-3));
+
+ nz_store[FAMILY_BLS12] = gclone(closure_evalgen(compile_str("(z) -> z")));
+ pz_store[FAMILY_BLS12] = gclone(closure_evalgen(
+ compile_str("(z) -> (z - 1)^2 * (z^4 - z^2 + 1)/3 + z")));
+ rz_store[FAMILY_BLS12] =
+ gclone(closure_evalgen(compile_str("(z) -> z^4 - z^2 + 1")));
+ tz_store[FAMILY_BLS12] =
+ gclone(closure_evalgen(compile_str("(z) -> z + 1")));
+ D_store[FAMILY_BLS12] = gclone(stoi(-3));
+
+ nz_store[FAMILY_BLS24] = gclone(closure_evalgen(compile_str("(z) -> z")));
+ pz_store[FAMILY_BLS24] = gclone(closure_evalgen(
+ compile_str("(z) -> (z - 1)^2 * (z^8 - z^4 + 1)/3 + z")));
+ rz_store[FAMILY_BLS24] =
+ gclone(closure_evalgen(compile_str("(z) -> z^8 - z^4 + 1")));
+ tz_store[FAMILY_BLS24] =
+ gclone(closure_evalgen(compile_str("(z) -> z + 1")));
+ D_store[FAMILY_BLS24] = gclone(stoi(-3));
+
+ //TODO: This does not work...
+ nz_store[FAMILY_KSS16] =
+ gclone(closure_evalgen(compile_str("(z) -> 70*z + 25")));
+ pz_store[FAMILY_KSS16] = gclone(closure_evalgen(
+ compile_str("(z) -> (z^10 + 2*z^9 + 5*z^8 + 48*z^6 + 152*z^5 + 240*z^4 "
+ "+ 625*z^2 + 2398*z + 3125)/980")));
+ rz_store[FAMILY_KSS16] = gclone(
+ closure_evalgen(compile_str("(z) -> (z^8 + 48*z^4 + 625)/61250")));
+ tz_store[FAMILY_KSS16] =
+ gclone(closure_evalgen(compile_str("(z) -> (2*z^5 + 41*z + 35)/35")));
+ D_store[FAMILY_KSS16] = gclone(stoi(-1));
+
+ avma = ltop;
+}
+
+static seed_t *family_new_seed() {
+ seed_t *result = seed_new();
+ result->type = SEED_FAMILY;
+ return result;
+}
+
+GENERATOR(family_gen_seed_random) {
+ curve->seed = family_new_seed();
+ curve->seed->family.z = random_int(cfg->bits);
+ return 1;
+}
+
+GENERATOR(family_gen_seed_input) {
+ pari_sp ltop = avma;
+ GEN inp = input_int("z:", cfg->bits);
+ if (gequalm1(inp)) {
+ avma = ltop;
+ return 0;
+ } else if (equalii(inp, gen_m2)) {
+ avma = ltop;
+ return INT_MIN;
+ }
+ curve->seed = family_new_seed();
+ curve->seed->family.z = inp;
+ return 1;
+}
+
+GENERATOR(family_gen_field) {
+ pari_sp ltop = avma;
+ GEN n = closure_callgen1(nz_store[cfg->family], curve->seed->family.z);
+ GEN pz = closure_callgen1(pz_store[cfg->family], n);
+ if (typ(pz) != t_INT || !isprime(pz)) {
+ avma = ltop;
+ return -1;
+ }
+ printf("p");
+ GEN rz = closure_callgen1(rz_store[cfg->family], n);
+ if (typ(rz) != t_INT || !isprime(rz)) {
+ avma = ltop;
+ return -1;
+ }
+ printf("r");
+ curve->field = gerepilecopy(ltop, pz);
+ return 1;
+}
+
+static GEN b = NULL;
+static curve_t *b_curve = NULL;
+
+GENERATOR(family_gen_equation_iter) {
+ curve->a = gmodulo(gen_0, curve->field);
+
+ pari_sp ltop = avma;
+ if (!b) {
+ b = gclone(gen_1);
+ curve->b = gmodulo(gen_1, curve->field);
+ b_curve = curve;
+ return 1;
+ } else {
+ if (curve == b_curve) {
+ GEN bn = addii(b, gen_1);
+ gunclone(b);
+ b = gclone(bn);
+ curve->b = gerepilecopy(ltop, gmodulo(bn, curve->field));
+ return 1;
+ } else {
+ // dont use b, regenerate it,
+ gunclone(b);
+ b = gclone(gen_1);
+ curve->b = gerepilecopy(ltop, gmodulo(gen_1, curve->field));
+ b_curve = curve;
+ return 1;
+ }
+ }
+}
+
+GENERATOR(family_gen_equation_cm) {
+ GEN n = closure_callgen1(nz_store[cfg->family], curve->seed->family.z);
+ GEN rz = closure_callgen1(rz_store[cfg->family], n);
+ GEN D = D_store[cfg->family];
+ GEN e = cm_construct_curve_subgroup(rz, D, curve->field);
+ if (e) {
+ curve->a = ell_get_a4(e);
+ curve->b = ell_get_a6(e);
+ return 1;
+ }
+ return -3;
+}
+
+GENERATOR(family_gen_order) {
+ pari_sp ltop = avma;
+ GEN n = closure_callgen1(nz_store[cfg->family], curve->seed->family.z);
+ GEN rz = closure_callgen1(rz_store[cfg->family], n);
+ GEN ord = ellff_get_card(curve->curve);
+ if (dvdii(ord, rz)) {
+ if (isclone(ord)) {
+ curve->order = gerepilecopy(ltop, ord);
+ } else {
+ avma = ltop;
+ curve->order = ord;
+ }
+ return 1;
+ } else {
+ avma = ltop;
+ return -2;
+ }
+}
+
+void family_quit() {
+ for (int i = 0; i < FAMILIES; i++) {
+ if (nz_store[i]) {
+ gunclone(nz_store[i]);
+ }
+ if (pz_store[i]) {
+ gunclone(pz_store[i]);
+ }
+ if (rz_store[i]) {
+ gunclone(rz_store[i]);
+ }
+ if (tz_store[i]) {
+ gunclone(tz_store[i]);
+ }
+ if (D_store[i]) {
+ gunclone(D_store[i]);
+ }
+ }
+ if (b) {
+ gunclone(b);
+ }
+} \ No newline at end of file
diff --git a/src/exhaustive/family.h b/src/exhaustive/family.h
new file mode 100644
index 0000000..9b7deaa
--- /dev/null
+++ b/src/exhaustive/family.h
@@ -0,0 +1,30 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2024 J08nY
+ */
+/*
+ * @file family.h
+ */
+#ifndef ECGEN_EXHAUSTIVE_FAMILY_H
+#define ECGEN_EXHAUSTIVE_FAMILY_H
+
+#include "misc/types.h"
+
+GENERATOR(family_gen_seed_random);
+
+GENERATOR(family_gen_seed_input);
+
+GENERATOR(family_gen_field);
+
+GENERATOR(family_gen_equation_iter);
+
+GENERATOR(family_gen_equation_cm);
+
+GENERATOR(family_gen_order);
+
+void family_init();
+
+void family_quit();
+
+
+#endif //ECGEN_EXHAUSTIVE_FAMILY_H
diff --git a/src/gen/point.c b/src/gen/point.c
index 4f1c624..21d0c26 100644
--- a/src/gen/point.c
+++ b/src/gen/point.c
@@ -41,6 +41,9 @@ GENERATOR(points_gen_random) {
for (size_t i = 0; i < curve->ngens; ++i) {
subgroup_t *subgroup = curve->generators[i];
subgroup->npoints = npoints_per_gen[i];
+ if (npoints_per_gen[i] == 0) {
+ continue;
+ }
subgroup->points = points_new(npoints_per_gen[i]);
for (size_t j = 0; j < npoints_per_gen[i]; ++j) {
diff --git a/src/gen/seed.c b/src/gen/seed.c
index 5dca17a..3e67135 100644
--- a/src/gen/seed.c
+++ b/src/gen/seed.c
@@ -53,6 +53,8 @@ void seed_free(seed_t **seed) {
break;
case SEED_NONE:
break;
+ case SEED_FAMILY:
+ break;
}
try_free(*seed);
*seed = NULL;
diff --git a/src/io/cli.c b/src/io/cli.c
index 5f29047..0da0770 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -31,6 +31,7 @@ enum opt_keys {
OPT_APPEND = 'a',
OPT_VERBOSE = 'v',
OPT_MEMORY = 'm',
+ OPT_FAMILY = 'F',
OPT_FP = 1,
OPT_F2M,
OPT_POINTS,
@@ -59,9 +60,10 @@ struct argp_option cli_options[] = {
{"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},
- {"nums", OPT_NUMS, 0, 0, "Generate a curve using the NUMS procedure.", 2},
+ {"nums", OPT_NUMS, 0, 0, "Generate a curve using the NUMS procedure.", 2},
{"invalid", OPT_INVALID, "RANGE", OPTION_ARG_OPTIONAL, "Generate a set of invalid curves, for a given curve (using Invalid curve algorithm).", 2},
- {"twist", OPT_TWIST, 0, 0, "Generate a twist of a given curve.", 2},
+ {"twist", OPT_TWIST, 0, 0, "Generate a twist of a given curve.", 2},
+ {"family", OPT_FAMILY, "NAME", 0, "Generate a curve from a curve family (e.g. BN, BLS12, BLS24, KSS)."},
{0, 0, 0, 0, "Generation options:", 3},
{"random", OPT_RANDOM, "WHAT", OPTION_ARG_OPTIONAL, "Generate a random curve (using Random approach). "
@@ -171,6 +173,7 @@ static void cli_end(struct argp_state *state) {
case METHOD_INVALID:
case METHOD_TWIST:
case METHOD_SUPERSINGULAR:
+ case METHOD_FAMILY:
break;
default:
argp_failure(state, 1, 0,
@@ -200,6 +203,10 @@ static void cli_end(struct argp_state *state) {
"Can only generate anomalous curves over prime fields "
"currently.");
}
+ if (cfg->method == METHOD_FAMILY && cfg->field == FIELD_BINARY) {
+ argp_failure(state, 1, 0,
+ "Can only generate family curves over prime fields.");
+ }
if (cfg->method == METHOD_SUPERSINGULAR && cfg->field == FIELD_BINARY) {
argp_failure(state, 1, 0,
"Can only generate supersingular curves over prime fields "
@@ -213,7 +220,8 @@ static void cli_end(struct argp_state *state) {
}
if (cfg->method == METHOD_ANOMALOUS && !cfg->random) {
argp_failure(state, 1, 0,
- "Anomalous curves can only be generated randomly (specify the -r option).");
+ "Anomalous curves can only be generated randomly (specify "
+ "the -r option).");
}
// default values
if (!cfg->count) {
@@ -276,6 +284,31 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
cfg->method |= METHOD_SUPERSINGULAR;
SET(method);
break;
+ case OPT_FAMILY:
+ cfg->method |= METHOD_FAMILY;
+ SET(method);
+ if (strcasecmp(arg, "BN") == 0) {
+ cfg->family = FAMILY_BN;
+ } else if (strcasecmp(arg, "BLS12") == 0) {
+ cfg->family = FAMILY_BLS12;
+ } else if (strcasecmp(arg, "BLS24") == 0) {
+ cfg->family = FAMILY_BLS24;
+ } else if (strcasecmp(arg, "KSS16") == 0) {
+ argp_failure(state, 1, 0, "Family not yet supported.");
+ cfg->family = FAMILY_KSS16;
+ } else if (strcasecmp(arg, "KSS18") == 0) {
+ argp_failure(state, 1, 0, "Family not yet supported.");
+ cfg->family = FAMILY_KSS18;
+ } else if (strcasecmp(arg, "KSS36") == 0) {
+ argp_failure(state, 1, 0, "Family not yet supported.");
+ cfg->family = FAMILY_KSS36;
+ } else if (strcasecmp(arg, "KSS40") == 0) {
+ argp_failure(state, 1, 0, "Family not yet supported.");
+ cfg->family = FAMILY_KSS40;
+ } else {
+ argp_failure(state, 1, 0, "Unknown curve family = %s", arg);
+ }
+ break;
case OPT_ANSI:
cfg->method |= METHOD_SEED;
SET(method);
diff --git a/src/io/output.c b/src/io/output.c
index a69b905..32b2de4 100644
--- a/src/io/output.c
+++ b/src/io/output.c
@@ -81,7 +81,7 @@ static JSON_Value *output_jjson(curve_t *curve) {
fprintf(err, "Error, field has unknown amount of elements.\n");
exit(1);
}
- if (curve->seed) {
+ if (curve->seed && curve->seed->seed) {
char *hex_str = bits_to_hex(curve->seed->seed);
char *hex = try_calloc(strlen(hex_str) + 3);
hex[0] = '0';
diff --git a/src/misc/config.h b/src/misc/config.h
index 0c0a5ca..3272190 100644
--- a/src/misc/config.h
+++ b/src/misc/config.h
@@ -48,7 +48,8 @@ typedef enum {
METHOD_SEED = 1 << 2,
METHOD_INVALID = 1 << 3,
METHOD_TWIST = 1 << 4,
- METHOD_SUPERSINGULAR = 1 << 5
+ METHOD_SUPERSINGULAR = 1 << 5,
+ METHOD_FAMILY = 1 << 6
} method_e;
/**
@@ -60,12 +61,26 @@ typedef enum {
SEED_BRAINPOOL,
SEED_BRAINPOOL_RFC,
SEED_FIPS,
- SEED_NUMS
+ SEED_NUMS,
+ SEED_FAMILY
} seed_e;
/**
* @brief
*/
+typedef enum {
+ FAMILY_BN = 0,
+ FAMILY_BLS12,
+ FAMILY_BLS24,
+ FAMILY_KSS16,
+ FAMILY_KSS18,
+ FAMILY_KSS36,
+ FAMILY_KSS40
+} family_e;
+
+/**
+ * @brief
+ */
typedef struct {
/** @brief What field should the curves be generated over. */
enum field_e field;
@@ -84,7 +99,8 @@ typedef struct {
/** @brief Whether the curves should be Koblitz (a \\in {0, 1}, b = 1). */
bool koblitz;
long koblitz_value;
- /** @brief Whether the curves should have a smooth order (bit-length bound). */
+ /** @brief Whether the curves should have a smooth order (bit-length bound).
+ */
bool smooth;
long smooth_value;
/** @brief Whether the curves should have a bound on the cofactor value. */
@@ -97,6 +113,8 @@ typedef struct {
seed_e seed_algo;
/** @brief What seed to use, if any, to generate the curves. */
char *seed;
+ /** @brief What family of curves to generate. */
+ family_e family;
/** @brief Whether the curves should be uniquely generated (one generator).
*/
bool unique;
@@ -156,6 +174,7 @@ typedef struct {
bool invalid_primes;
bool seed_algo;
bool seed;
+ bool family;
bool unique;
bool hex_check;
bool points;
diff --git a/src/misc/types.h b/src/misc/types.h
index 827e8aa..ed9cd18 100644
--- a/src/misc/types.h
+++ b/src/misc/types.h
@@ -51,6 +51,9 @@ typedef struct {
bits_t *seed_b;
GEN mult;
} brainpool;
+ struct {
+ GEN z;
+ } family;
};
} seed_t;
diff --git a/src/util/memory.c b/src/util/memory.c
index d18c01f..f05efae 100644
--- a/src/util/memory.c
+++ b/src/util/memory.c
@@ -46,7 +46,7 @@ void *try_calloc(size_t size) { return alloc(calloc_func, size); }
void *try_realloc(void *ptr, size_t size) {
void *result = realloc_func(ptr, size);
if (!result) {
- perror("Couldn't alloc.");
+ perror("Couldn't realloc.");
exit(EXIT_FAILURE);
}
return result;
diff --git a/test/ecgen.sh b/test/ecgen.sh
index 7aa146b..c067c2e 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -126,6 +126,13 @@ function supersingular() {
assert_raises "${ecgen} --fp --supersingular -r --points=none 20"
}
+function family() {
+ start_test
+ assert_raises "${ecgen} --fp -r --family=BN 32"
+ assert_raises "${ecgen} --fp -r --family=BLS12 32"
+ assert_raises "${ecgen} --fp -r --family=BLS24 32"
+}
+
function invalid() {
start_test
assert_raises "${ecgen} --fp -r -i 10"
@@ -214,6 +221,7 @@ brainpool
nums
anomalous
supersingular
+family
invalid
twist
cli