summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/exhaustive/ansi.c27
-rw-r--r--src/exhaustive/brainpool.c151
-rw-r--r--src/exhaustive/brainpool.h35
-rw-r--r--src/gen/seed.c3
-rw-r--r--src/io/cli.c24
-rw-r--r--src/misc/types.h8
-rw-r--r--src/util/bits.c31
-rw-r--r--src/util/bits.h4
-rw-r--r--src/util/str.c16
-rw-r--r--src/util/str.h7
10 files changed, 275 insertions, 31 deletions
diff --git a/src/exhaustive/ansi.c b/src/exhaustive/ansi.c
index 762ffb7..d870d76 100644
--- a/src/exhaustive/ansi.c
+++ b/src/exhaustive/ansi.c
@@ -9,6 +9,7 @@
#include "io/output.h"
#include "util/bits.h"
#include "util/memory.h"
+#include "util/str.h"
static seed_t *ansi_new() {
seed_t *result = seed_new();
@@ -17,26 +18,8 @@ static seed_t *ansi_new() {
}
bool ansi_seed_valid(const char *hex_str) {
- size_t len = strlen(hex_str);
- if (len < 40) {
- return false;
- }
- const char *str_start = hex_str;
- if (hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X')) {
- str_start = hex_str + 2;
- }
- while (*str_start != 0) {
- char c = *str_start++;
- if (!isxdigit(c)) return false;
- }
- return true;
-}
-
-static bits_t *seed_stoi(const char *cstr) {
- const char *seed_str = cstr;
- const char *prefix = strstr(cstr, "0x");
- if (prefix != NULL) seed_str = prefix + 2;
- return bits_from_hex(seed_str);
+ const char *seed = str_is_hex(hex_str);
+ return seed && strlen(seed) >= 40;
}
static void seed_hash(seed_t *seed) {
@@ -64,7 +47,7 @@ GENERATOR(ansi_gen_seed_random) {
GENERATOR(ansi_gen_seed_argument) {
seed_t *seed = ansi_new();
- seed->seed = seed_stoi(cfg->seed);
+ seed->seed = bits_from_hex(str_is_hex(cfg->seed));
seed_hash(seed);
seed_tsh(seed);
curve->seed = seed;
@@ -83,7 +66,7 @@ GENERATOR(ansi_gen_seed_input) {
}
seed_t *seed = ansi_new();
- seed->seed = seed_stoi(cstr);
+ seed->seed = bits_from_hex(str_is_hex(cstr));
seed_hash(seed);
seed_tsh(seed);
curve->seed = seed;
diff --git a/src/exhaustive/brainpool.c b/src/exhaustive/brainpool.c
index f8ddb8e..0e3fa83 100644
--- a/src/exhaustive/brainpool.c
+++ b/src/exhaustive/brainpool.c
@@ -4,11 +4,154 @@
*/
#include "brainpool.h"
+#include <misc/types.h>
+#include "gen/seed.h"
+#include "io/output.h"
+#include "util/bits.h"
+#include "util/str.h"
-GENERATOR(brainpool_gen_seed_random) { return INT_MIN; }
+static seed_t *brainpool_new() {
+ seed_t *result = seed_new();
+ result->type = SEED_BRAINPOOL;
+ result->brainpool.first = true;
+ return result;
+}
-GENERATOR(brainpool_gen_seed_argument) { return INT_MIN; }
+static void seed_wv(seed_t *seed) {
+ pari_sp ltop = avma;
+ GEN L = utoi(cfg->bits);
+ seed->brainpool.v = itou(floorr(divis(subis(L, 1), 160)));
+ seed->brainpool.w =
+ itou(floorr(subis(subis(L, 160 * seed->brainpool.v), 1)));
+ avma = ltop;
+}
-GENERATOR(brainpool_gen_seed_input) { return INT_MIN; }
+static 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));
+ bits_t *result = bits_from_i_len(t, 160);
+ avma = ltop;
+ bits_cpy(s, result);
+ bits_free(&result);
+}
-GENERATOR(brainpool_gen_equation) { return INT_MIN; } \ No newline at end of file
+static bits_t *brainpool_hash(const bits_t *s, long w, long v) {
+ pari_sp ltop = avma;
+ unsigned char h0[20];
+ bits_sha1(s, h0);
+ unsigned char hashout[w + 20 * v];
+ memcpy(hashout, h0, (size_t)w);
+
+ GEN z = bits_to_i(s);
+ GEN m = int2n(160);
+ for (long i = 1; i < v; ++i) {
+ bits_t *si = bits_from_i(Fp_add(z, stoi(i), m));
+ bits_sha1(si, hashout + w + 20 * i);
+ bits_free(&si);
+ }
+ bits_t *result = bits_from_raw(hashout, (size_t)(w + (20 * v)));
+ avma = ltop;
+ return result;
+}
+
+bool brainpool_seed_valid(const char *hex_str) {
+ const char *seed = str_is_hex(hex_str);
+ return seed && strlen(seed) == 40;
+}
+
+GENERATOR(brainpool_gen_seed_random) {
+ seed_t *seed = brainpool_new();
+ seed->seed = bits_new_rand(160);
+ seed_wv(seed);
+ curve->seed = seed;
+ return 1;
+}
+
+GENERATOR(brainpool_gen_seed_argument) {
+ seed_t *seed = brainpool_new();
+ seed->seed = bits_from_hex(str_is_hex(cfg->seed));
+ seed_wv(seed);
+ curve->seed = seed;
+ return 1;
+}
+
+GENERATOR(brainpool_gen_seed_input) {
+ pari_sp ltop = avma;
+
+ GEN str = input_string("seed:");
+ const char *cstr = GSTR(str);
+ if (!brainpool_seed_valid(cstr)) {
+ fprintf(err, "SEED must be exactly 160 bits(40 hex characters).\n");
+ avma = ltop;
+ return 0;
+ }
+
+ seed_t *seed = brainpool_new();
+ seed->seed = bits_from_hex(str_is_hex(cstr));
+ seed_wv(seed);
+ curve->seed = seed;
+ return INT_MIN;
+}
+
+GENERATOR(brainpool_gen_equation) {
+ // field is definitely prime
+ pari_sp btop = avma;
+ seed_t *seed = curve->seed;
+ do {
+ if (seed->brainpool.first) {
+ brainpool_update_seed(seed->seed);
+ seed->brainpool.first = 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);
+ continue;
+ }
+ seed->brainpool.seed_a = bits_copy(seed->seed);
+
+ brainpool_update_seed(seed->seed);
+
+ bits_t *b_bits =
+ 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)) {
+ brainpool_update_seed(seed->seed);
+ bits_free(&seed->brainpool.seed_a);
+ continue;
+ }
+ 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);
+ 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);
+
+ return 1;
+} \ No newline at end of file
diff --git a/src/exhaustive/brainpool.h b/src/exhaustive/brainpool.h
index cf212b1..cb79e89 100644
--- a/src/exhaustive/brainpool.h
+++ b/src/exhaustive/brainpool.h
@@ -8,12 +8,47 @@
#include "misc/types.h"
+/**
+ * @brief
+ * @param hex_str
+ * @return
+ */
+bool brainpool_seed_valid(const char *hex_str);
+
+/**
+ * @brief
+ * @param curve
+ * @param args
+ * @param state
+ * @return
+ */
GENERATOR(brainpool_gen_seed_random);
+/**
+ * @brief
+ * @param curve
+ * @param args
+ * @param state
+ * @return
+ */
GENERATOR(brainpool_gen_seed_argument);
+/**
+ * @brief
+ * @param curve
+ * @param args
+ * @param state
+ * @return
+ */
GENERATOR(brainpool_gen_seed_input);
+/**
+ * @brief
+ * @param curve
+ * @param args
+ * @param state
+ * @return
+ */
GENERATOR(brainpool_gen_equation);
#endif // ECGEN_BRAINPOOL_H
diff --git a/src/gen/seed.c b/src/gen/seed.c
index f349982..2e3f9e3 100644
--- a/src/gen/seed.c
+++ b/src/gen/seed.c
@@ -46,6 +46,9 @@ void seed_free(seed_t **seed) {
case SEED_ANSI:
break;
case SEED_BRAINPOOL:
+ bits_free(&(*seed)->brainpool.seed_a);
+ bits_free(&(*seed)->brainpool.seed_b);
+ bits_free(&(*seed)->brainpool.seed_bp);
break;
case SEED_BRAINPOOL_RFC:
break;
diff --git a/src/io/cli.c b/src/io/cli.c
index a3fef1f..63a69be 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -6,6 +6,7 @@
#include <misc/config.h>
#include <string.h>
#include "exhaustive/ansi.h"
+#include "exhaustive/brainpool.h"
char cli_doc[] =
"ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 "
@@ -19,6 +20,7 @@ enum opt_keys {
OPT_COFACTOR = 'k',
OPT_RANDOM = 'r',
OPT_ANSI = 's',
+ OPT_BRAINPOOL = 'b',
OPT_INVALID = 'i',
OPT_ORDER = 'n',
OPT_KOBLITZ = 'K',
@@ -51,6 +53,7 @@ struct argp_option cli_options[] = {
{"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 options:", 3},
@@ -130,13 +133,9 @@ static void cli_end(struct argp_state *state) {
// Only one gen method
switch (cfg->method) {
case METHOD_DEFAULT:
- break;
case METHOD_CM:
- break;
case METHOD_ANOMALOUS:
- break;
case METHOD_SEED:
- break;
case METHOD_INVALID:
break;
default:
@@ -146,6 +145,11 @@ static void cli_end(struct argp_state *state) {
break;
}
+ if (cfg->method == METHOD_SEED && cfg->seed_algo == SEED_BRAINPOOL &&
+ cfg->field == FIELD_BINARY) {
+ argp_failure(state, 1, 0,
+ "Brainpool algorithm only creates prime field curves.");
+ }
/*
// Invalid is not prime or seed by definition.
if (cfg->invalid &&
@@ -227,6 +231,18 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
cfg->seed = arg;
}
break;
+ case OPT_BRAINPOOL:
+ cfg->method |= METHOD_SEED;
+ cfg->seed_algo = SEED_BRAINPOOL;
+ 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/src/misc/types.h b/src/misc/types.h
index aecf207..9c1cff6 100644
--- a/src/misc/types.h
+++ b/src/misc/types.h
@@ -44,7 +44,13 @@ typedef struct {
GEN r;
} ansi;
struct {
- bits_t *f;
+ bool first;
+ long w;
+ long v;
+ bits_t *seed_a;
+ bits_t *seed_b;
+ bits_t *seed_bp;
+ GEN mult;
} brainpool;
};
} seed_t;
diff --git a/src/util/bits.c b/src/util/bits.c
index 6311ba8..5e6a95e 100644
--- a/src/util/bits.c
+++ b/src/util/bits.c
@@ -4,6 +4,7 @@
*/
#include "bits.h"
+#include <misc/types.h>
#include <sha1/sha1.h>
#include "util/memory.h"
@@ -16,6 +17,36 @@ bits_t *bits_new(size_t bit_len) {
return result;
}
+bits_t *bits_new_rand(size_t bit_len) {
+ bits_t *result = bits_new(bit_len);
+ for (size_t i = 0; i < result->allocated; ++i) {
+ if (i == result->allocated - 1) {
+ size_t last_bits = bit_len % 8;
+ result->bits[i] = (unsigned char)random_bits(last_bits)
+ << (8 - last_bits);
+ } else {
+ result->bits[i] = (unsigned char)random_bits(8);
+ }
+ }
+ return result;
+}
+
+void bits_cpy(bits_t *dest, const bits_t *src) {
+ if (src->bitlen == 0) {
+ return;
+ }
+
+ if (src->allocated < dest->allocated) {
+ memset(dest->bits + src->allocated, 0,
+ dest->allocated - src->allocated);
+ } else if (src->allocated > dest->allocated) {
+ dest->bits = try_realloc(dest->bits, src->allocated);
+ }
+ memcpy(dest->bits, src->bits, src->allocated);
+ dest->allocated = src->allocated;
+ dest->bitlen = src->bitlen;
+}
+
bits_t *bits_copy(const bits_t *bits) {
bits_t *result = try_calloc(sizeof(bits_t));
result->bitlen = bits->bitlen;
diff --git a/src/util/bits.h b/src/util/bits.h
index 9b37539..000d64f 100644
--- a/src/util/bits.h
+++ b/src/util/bits.h
@@ -29,6 +29,10 @@
bits_t *bits_new(size_t bit_len);
+bits_t *bits_new_rand(size_t bit_len);
+
+void bits_cpy(bits_t *dest, const bits_t *src);
+
bits_t *bits_copy(const bits_t *bits);
void bits_free(bits_t **bits);
diff --git a/src/util/str.c b/src/util/str.c
index 933eb83..3f9f39c 100644
--- a/src/util/str.c
+++ b/src/util/str.c
@@ -3,9 +3,25 @@
* Copyright (C) 2017 J08nY
*/
#include "str.h"
+#include <ctype.h>
#include <string.h>
#include "util/memory.h"
+const char *str_is_hex(const char *hex_str) {
+ const char *str_start = hex_str;
+ if (strlen(hex_str) > 2) {
+ if (hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X')) {
+ str_start = hex_str + 2;
+ }
+ }
+ const char *s = str_start;
+ while (*s != 0) {
+ char c = *s++;
+ if (!isxdigit(c)) return NULL;
+ }
+ return str_start;
+}
+
char *str_join(char *strings[], size_t len) {
size_t total = 0;
for (size_t i = 0; i < len; ++i) {
diff --git a/src/util/str.h b/src/util/str.h
index 2e14272..9b5709e 100644
--- a/src/util/str.h
+++ b/src/util/str.h
@@ -12,6 +12,13 @@
/**
* @brief
+ * @param hex_str
+ * @return
+ */
+const char *str_is_hex(const char *hex_str);
+
+/**
+ * @brief
* @param strings
* @param len
* @return