aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--src/exhaustive/exhaustive.c11
-rw-r--r--src/gen/order.c23
-rw-r--r--src/gen/order.h10
-rw-r--r--src/io/cli.c12
-rw-r--r--src/misc/config.h3
-rwxr-xr-xtest/ecgen.sh2
7 files changed, 61 insertions, 1 deletions
diff --git a/README.md b/README.md
index ee248d3..6b2b48c 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ Tool for generating Elliptic curve domain parameters.
- `-c / --count=COUNT` Generate multiple curves.
- `-k / --cofactor=VALUE` Generate a curve with cofactor of `VALUE`.
+ - `-B / --smooth=BOUND` Generate a smooth order curve with bit-lengths of factors bounded by `BOUND`.
- `-K / --koblitz[=A]` Generate a Koblitz curve (a in {0, 1}, b = 1).
- `-p / --prime` Generate a curve with prime order.
- `--points=TYPE` Generate points of given `TYPE` (random/prime/all/nonprime/none).
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 57b72ce..a8d0f22 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -47,6 +47,8 @@ static void exhaustive_ginit(gen_f *generators) {
generators[OFFSET_ORDER] = &order_gen_prime;
} else if (cfg->cofactor) {
generators[OFFSET_ORDER] = &order_gen_cofactor;
+ } else if (cfg->smooth) {
+ generators[OFFSET_ORDER] = &order_gen_smooth;
} else {
generators[OFFSET_ORDER] = &order_gen_any;
}
@@ -157,6 +159,8 @@ static void exhaustive_ginit(gen_f *generators) {
generators[OFFSET_ORDER] = &order_gen_prime;
} else if (cfg->cofactor) {
generators[OFFSET_ORDER] = &order_gen_cofactor;
+ } else if (cfg->smooth) {
+ generators[OFFSET_ORDER] = &order_gen_smooth;
} else if (cfg->koblitz) {
generators[OFFSET_ORDER] = &order_gen_koblitz;
} else {
@@ -256,6 +260,13 @@ static void exhaustive_ainit(arg_t **gen_argss, arg_t **check_argss) {
gen_argss[OFFSET_GENERATORS] = gens_arg;
}
+ if (cfg->smooth) {
+ arg_t *order_arg = arg_new();
+ order_arg->args = &cfg->smooth_value;
+ order_arg->nargs = 1;
+ gen_argss[OFFSET_ORDER] = order_arg;
+ }
+
if (cfg->hex_check) {
arg_t *point_arg = arg_new();
point_arg->args = cfg->hex_check;
diff --git a/src/gen/order.c b/src/gen/order.c
index 0bbac77..a9d22b2 100644
--- a/src/gen/order.c
+++ b/src/gen/order.c
@@ -66,6 +66,29 @@ GENERATOR(order_gen_cofactor) {
return 1;
}
+GENERATOR(order_gen_smooth) {
+ HAS_ARG(args);
+ pari_ulong smooth_bound = *(pari_ulong *)args->args;
+ pari_sp ltop = avma;
+ GEN order = ellff_get_card(curve->curve);
+
+ GEN factors = factor(order);
+ GEN primes = gel(factors, 1);
+ long uniqs = glength(primes);
+
+ for (long i = 1; i <= uniqs; ++i) {
+ long blen = glength(binary_zv(gel(primes, i)));
+ if (blen > smooth_bound) {
+ avma = ltop;
+ return -4;
+ }
+ }
+
+ curve->order = gerepilecopy(ltop, order);
+ obj_insert_shallow(curve->curve, 1, order);
+ return 1;
+}
+
GENERATOR(order_gen_prime) {
pari_sp ltop = avma;
GEN order = ellsea(curve->curve, 1);
diff --git a/src/gen/order.h b/src/gen/order.h
index 45b5e3e..9dc1553 100644
--- a/src/gen/order.h
+++ b/src/gen/order.h
@@ -56,6 +56,16 @@ GENERATOR(order_gen_cofactor);
/**
* GENERATOR(gen_f)
+ *
+ * @param curve A curve_t being generated
+ * @param args pari_ulong the desired cofactor
+ * @param state
+ * @return state diff
+ */
+GENERATOR(order_gen_smooth);
+
+/**
+ * GENERATOR(gen_f)
* Calculates the curve order, always using the SEA algorithm,
* gives up early in case the order is divisible by "something".
* Succeeds if the curve has a prime order.
diff --git a/src/io/cli.c b/src/io/cli.c
index a525a78..ad3df9b 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -10,7 +10,7 @@
char cli_doc[] =
"ecgen, tool for generating Elliptic curve domain parameters.\v(C) "
- "2017-2018,2021 J08nY";
+ "2017-2018,2021,2023 J08nY";
char cli_args_doc[] = "bits";
enum opt_keys {
@@ -18,6 +18,7 @@ enum opt_keys {
OPT_COUNT = 'c',
OPT_PRIME = 'p',
OPT_COFACTOR = 'k',
+ OPT_SMOOTH = 'B',
OPT_RANDOM = 'r',
OPT_ANSI = 's',
OPT_BRAINPOOL = 'b',
@@ -65,6 +66,7 @@ struct argp_option cli_options[] = {
"Optionally, only generate random parameters WHAT (seed,field,a,b,equation).", 3},
{"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 3},
{"cofactor", OPT_COFACTOR, "VALUE", 0, "Generate a curve with cofactor of VALUE.", 3},
+ {"smooth", OPT_SMOOTH, "BOUND", 0, "Generate a smooth order curve with bit-lengths of factors bounded by 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},
{"hex-check", OPT_HEXCHECK, "HEX", 0, "Check a generated curve param hex expansion for the HEX string.", 3},
@@ -152,6 +154,10 @@ static void cli_end(struct argp_state *state) {
"Specify field type, prime or binary, with --fp / "
"--f2m (but not both).");
}
+ // Only one of prime, cofactor, smooth
+ if (cfg->prime + cfg->smooth + cfg->cofactor > 1) {
+ argp_failure(state, 1, 0, "Can only choose one of prime-order, cofactor value or smoothness bound.");
+ }
// Only one gen method
switch (cfg->method) {
case METHOD_DEFAULT:
@@ -307,6 +313,10 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
case OPT_PRIME:
cfg->prime = true;
break;
+ case OPT_SMOOTH:
+ cfg->smooth = true;
+ cfg->smooth_value = strtol(arg, NULL, 10);
+ break;
case OPT_COFACTOR:
cfg->cofactor = true;
cfg->cofactor_value = strtol(arg, NULL, 10);
diff --git a/src/misc/config.h b/src/misc/config.h
index 4135f9e..d73d26f 100644
--- a/src/misc/config.h
+++ b/src/misc/config.h
@@ -83,6 +83,9 @@ 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). */
+ bool smooth;
+ long smooth_value;
/** @brief Whether the curves should have a bound on the cofactor value. */
bool cofactor;
long cofactor_value;
diff --git a/test/ecgen.sh b/test/ecgen.sh
index 0adf90d..2d5279c 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -45,6 +45,8 @@ function exhaustive() {
assert_raises "${ecgen} --f2m -r -u 10"
assert_raises "${ecgen} --fp -r -i -u 10"
assert_raises "${ecgen} --f2m -r -i -u 10"
+ assert_raises "${ecgen} --fp -r -p -u 10"
+ assert_raises "${ecgen} --fp -r -B 5 -u 10":
assert_raises "${ecgen} --fp -r -k 10 10"
assert_raises "${ecgen} --f2m -r -k 10 10"
assert_raises "${ecgen} --fp -r -K 10"