summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-09-19 13:07:45 +0200
committerJ08nY2017-09-19 13:07:45 +0200
commit0d068cefe5f43d69fb7bae0c7882598c1213f60b (patch)
tree29bf69e2bf51e33617b78e4439c8b0077e543b1d
parentbfeeedd8b158288b1e66e241620966e933c9e3c7 (diff)
parent8448edf40ea8d8b128ff83dc08335b3bf14718cb (diff)
downloadecgen-0d068cefe5f43d69fb7bae0c7882598c1213f60b.tar.gz
ecgen-0d068cefe5f43d69fb7bae0c7882598c1213f60b.tar.zst
ecgen-0d068cefe5f43d69fb7bae0c7882598c1213f60b.zip
-rw-r--r--.codecov.yml7
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/cm/cm.h2
-rw-r--r--src/exhaustive/anomalous.h2
-rw-r--r--src/exhaustive/ansi.c188
-rw-r--r--src/exhaustive/ansi.h55
-rw-r--r--src/exhaustive/arg.h2
-rw-r--r--src/exhaustive/exhaustive.c27
-rw-r--r--src/exhaustive/exhaustive.h2
-rw-r--r--src/gen/curve.c24
-rw-r--r--src/gen/curve.h14
-rw-r--r--src/gen/equation.c9
-rw-r--r--src/gen/equation.h2
-rw-r--r--src/gen/field.c3
-rw-r--r--src/gen/field.h2
-rw-r--r--src/gen/gens.h2
-rw-r--r--src/gen/order.h2
-rw-r--r--src/gen/point.h2
-rw-r--r--src/gen/seed.c84
-rw-r--r--src/gen/seed.h40
-rw-r--r--src/invalid/invalid.h2
-rw-r--r--src/invalid/invalid_thread.h2
-rw-r--r--src/io/cli.c22
-rw-r--r--src/io/input.c16
-rw-r--r--src/io/input.h2
-rw-r--r--src/io/output.c52
-rw-r--r--src/io/output.h2
-rw-r--r--src/math/subgroups.c14
-rw-r--r--src/math/subgroups.h2
-rw-r--r--src/misc/config.h (renamed from src/io/config.h)2
-rw-r--r--src/misc/types.c (renamed from src/gen/types.c)0
-rw-r--r--src/misc/types.h (renamed from src/gen/types.h)38
-rw-r--r--src/util/bits.c430
-rw-r--r--src/util/bits.h96
-rw-r--r--src/util/memory.c22
-rw-r--r--src/util/memory.h19
-rw-r--r--src/util/random.c9
-rw-r--r--test/Makefile2
-rwxr-xr-xtest/ecgen.sh2
-rw-r--r--test/src/exhaustive/test_ansi.c286
-rw-r--r--test/src/gen/test_point.c2
-rw-r--r--test/src/io/test_cli.c25
-rw-r--r--test/src/io/test_input.c54
-rw-r--r--test/src/math/test_subgroups.c2
-rw-r--r--test/src/test/default.c (renamed from test/src/test/utils.c)8
-rw-r--r--test/src/test/default.h (renamed from test/src/test/utils.h)6
-rw-r--r--test/src/test/input.c27
-rw-r--r--test/src/test/input.h16
-rw-r--r--test/src/test/memory.c17
-rw-r--r--test/src/test/memory.h13
-rw-r--r--test/src/test/output.c49
-rw-r--r--test/src/test/output.h18
-rw-r--r--test/src/util/test_bits.c486
-rw-r--r--test/src/util/test_random.c16
54 files changed, 1907 insertions, 323 deletions
diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 0000000..5fc845c
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,7 @@
+coverage:
+ range: 50..100
+ round: up
+ precision: 2
+ ignore:
+ - "**/test_*.c"
+ - "lib"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a13030d..6d7c624 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@ include_directories(lib)
find_library(parson parson/libparson.a)
find_library(sha1 sha1/libsha1.a)
-file(GLOB SRC "src/math/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/util/*.c")
+file(GLOB SRC "src/math/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/misc/*.c" "src/util/*.c")
set(ECGEN_SRC "src/ecgen.c" ${SRC})
set(ECONVERT_SRC "src/econvert.c")
diff --git a/src/cm/cm.h b/src/cm/cm.h
index 546c0d5..d59db87 100644
--- a/src/cm/cm.h
+++ b/src/cm/cm.h
@@ -9,7 +9,7 @@
#define ECGEN_CM_H
#include "io/cli.h"
-#include "io/config.h"
+#include "misc/config.h"
/**
*
diff --git a/src/exhaustive/anomalous.h b/src/exhaustive/anomalous.h
index ff6c053..cf8c208 100644
--- a/src/exhaustive/anomalous.h
+++ b/src/exhaustive/anomalous.h
@@ -10,7 +10,7 @@
#include <pari/pari.h>
#include "arg.h"
-#include "gen/types.h"
+#include "misc/types.h"
#include "io/cli.h"
typedef struct disc_t {
diff --git a/src/exhaustive/ansi.c b/src/exhaustive/ansi.c
new file mode 100644
index 0000000..40fbf41
--- /dev/null
+++ b/src/exhaustive/ansi.c
@@ -0,0 +1,188 @@
+
+#include <misc/config.h>
+#include <misc/types.h>
+#include "ansi.h"
+#include "gen/seed.h"
+#include "gen/field.h"
+#include "util/bits.h"
+#include "util/memory.h"
+#include "io/output.h"
+
+
+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);
+}
+
+static void seed_hash(seed_t *seed) {
+ seed->hash20 = try_malloc(20);
+ bits_sha1(seed->seed, seed->hash20);
+}
+
+static void seed_tsh(seed_t *seed, const config_t *cfg) {
+ pari_sp ltop = avma;
+ seed->ansi.t = utoi(cfg->bits);
+ seed->ansi.s = floorr(
+ rdivii(subis(seed->ansi.t, 1), stoi(160), DEFAULTPREC));
+ seed->ansi.h = subii(seed->ansi.t, mulis(seed->ansi.s, 160));
+ gerepileall(ltop, 3, &seed->ansi.t, &seed->ansi.s, &seed->ansi.h);
+}
+
+GENERATOR(ansi_gen_seed_random) {
+ seed_t *seed = seed_new();
+ seed->seed = bits_from_i(random_int(160));
+ seed_hash(seed);
+ seed_tsh(seed, cfg);
+ curve->seed = seed;
+ return 1;
+}
+
+GENERATOR(ansi_gen_seed_argument) {
+ seed_t *seed = seed_new();
+ seed->seed = seed_stoi(cfg->seed);
+ seed_hash(seed);
+ seed_tsh(seed, cfg);
+ curve->seed = seed;
+ return 1;
+}
+
+GENERATOR(ansi_gen_seed_input) {
+ pari_sp ltop = avma;
+
+ GEN str = input_string("seed:");
+ const char *cstr = GSTR(str);
+ if (!ansi_seed_valid(cstr)) {
+ fprintf(err, "SEED must be at least 160 bits(40 hex characters).\n");
+ avma = ltop;
+ return 0;
+ }
+
+ seed_t *seed = seed_new();
+ seed->seed = seed_stoi(cstr);
+ seed_hash(seed);
+ seed_tsh(seed, cfg);
+ curve->seed = seed;
+ return 1;
+}
+
+static bits_t *seed_process(seed_t *seed, const bits_t *first) {
+ pari_sp ltop = avma;
+
+ bits_t *result = bits_copy(first);
+
+ long is = itos(seed->ansi.s);
+ GEN seedi = bits_to_i(seed->seed);
+ GEN two_g = int2n(seed->seed->bitlen);
+
+ for (long i = 1; i <= is; ++i) {
+ pari_sp btop = avma;
+ GEN inner = addis(seedi, i);
+ inner = modii(inner, two_g);
+
+ bits_t *to_hash = bits_from_i(inner);
+ if (to_hash->bitlen < seed->seed->bitlen) {
+ bits_lengthenz(to_hash, seed->seed->bitlen - to_hash->bitlen);
+ }
+ unsigned char hashout[20];
+ bits_sha1(to_hash, hashout);
+ bits_t *Wi = bits_from_raw(hashout, 160);
+ bits_concatz(result, Wi, NULL);
+
+ bits_free(&to_hash);
+ bits_free(&Wi);
+ avma = btop;
+ }
+
+ avma = ltop;
+ return result;
+}
+
+UNROLL(ansi_unroll_seed) {
+ seed_free(&curve->seed);
+ return -1;
+}
+
+static GENERATOR(ansi_gen_equation_fp) {
+ pari_sp ltop = avma;
+ bits_t *c0 = bits_from_raw(curve->seed->hash20, 160);
+ bits_shortenz(c0, 160 - itos(curve->seed->ansi.h));
+
+ bits_t *W0 = bits_copy(c0);
+ SET_BIT(W0->bits, 0, 0);
+
+ bits_t *W = seed_process(curve->seed, W0);
+
+ long ti = itos(curve->seed->ansi.t);
+ GEN r = gen_0;
+ for (long i = 1; i <= ti; ++i) {
+ GEN Wi = stoi(GET_BIT(W->bits, i - 1));
+ r = addii(r, mulii(Wi, int2n(ti - i)));
+ }
+ curve->seed->ansi.r = r;
+
+ GEN r_inv = Fp_invsafe(r, curve->field);
+ GEN a;
+ GEN b2;
+ do {
+ a = random_int(cfg->bits);
+ b2 = mulii(powis(a, 3), r_inv);
+ }while (!Fp_issquare(b2, curve->field));
+ GEN b = Fp_sqrt(b2, curve->field);
+
+ curve->a = a;
+ curve->b = b;
+
+ gerepileall(ltop, 3, &curve->seed->ansi.r, &curve->a, &curve->b);
+ bits_free(&c0);
+ bits_free(&W0);
+ bits_free(&W);
+ return 1;
+}
+
+static GENERATOR(ansi_gen_equation_f2m) {
+ pari_sp ltop = avma;
+ bits_t *b0 = bits_from_raw(curve->seed->hash20, 160);
+ bits_shortenz(b0, 160 - itos(curve->seed->ansi.h));
+
+ bits_t *b = seed_process(curve->seed, b0);
+ GEN ib = bits_to_i(b);
+ if (gequal0(ib)) {
+ avma = ltop;
+ return -3;
+ }
+ GEN a = random_int(cfg->bits);
+ curve->a = field_ielement(curve->field, a);
+ curve->b = field_ielement(curve->field, ib);
+
+ gerepileall(ltop, 2, &curve->a, &curve->b);
+ bits_free(&b0);
+ bits_free(&b);
+ return 1;
+}
+
+GENERATOR(ansi_gen_equation) {
+ switch (cfg->field) {
+ case FIELD_PRIME: return ansi_gen_equation_fp(curve, cfg, args);
+ case FIELD_BINARY: return ansi_gen_equation_f2m(curve, cfg, args);
+ default: pari_err_BUG("Field not prime or binary?");
+ return INT_MIN; /* NOT REACHABLE */
+ }
+}
diff --git a/src/exhaustive/ansi.h b/src/exhaustive/ansi.h
new file mode 100644
index 0000000..74e787e
--- /dev/null
+++ b/src/exhaustive/ansi.h
@@ -0,0 +1,55 @@
+
+#ifndef ECGEN_ANSI_H
+#define ECGEN_ANSI_H
+
+#include "misc/types.h"
+
+bool ansi_seed_valid(const char *hex_str);
+
+/**
+ * @brief
+ * @param curve A curve_t being generated
+ * @param cfg An application config
+ * @param args unused
+ * @return state diff
+ */
+GENERATOR(ansi_gen_seed_random);
+
+/**
+ * @brief
+ * @param curve A curve_t being generated
+ * @param cfg An application config
+ * @param args unused
+ * @return state diff
+ */
+GENERATOR(ansi_gen_seed_argument);
+
+/**
+ * @brief
+ * @param curve A curve_t being generated
+ * @param cfg An application config
+ * @param args unused
+ * @return state diff
+ */
+GENERATOR(ansi_gen_seed_input);
+
+/**
+ * @brief
+ * @param curve
+ * @param cfg
+ * @param from
+ * @param to
+ * @return
+ */
+UNROLL(ansi_unroll_seed);
+
+/**
+ * @brief
+ * @param curve A curve_t being generated
+ * @param cfg An application config
+ * @param args unused
+ * @return state diff
+ */
+GENERATOR(ansi_gen_equation);
+
+#endif //ECGEN_ANSI_H
diff --git a/src/exhaustive/arg.h b/src/exhaustive/arg.h
index 1a4d0ed..415008c 100644
--- a/src/exhaustive/arg.h
+++ b/src/exhaustive/arg.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_ARG_H
#define ECGEN_ARG_H
-#include "gen/types.h"
+#include "misc/types.h"
/**
* @brief
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 6b77f3a..0506409 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -2,33 +2,35 @@
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
+#include <misc/config.h>
#include "exhaustive.h"
#include "anomalous.h"
+#include "ansi.h"
#include "gen/curve.h"
#include "gen/equation.h"
#include "gen/field.h"
#include "gen/gens.h"
#include "gen/order.h"
#include "gen/point.h"
-#include "gen/seed.h"
#include "io/output.h"
#include "util/memory.h"
static void exhaustive_ginit(gen_t *generators, const config_t *cfg) {
- if (cfg->from_seed) {
+ if (cfg->ansi) {
// setup ANSI X9.62 generators
if (cfg->seed) {
- generators[OFFSET_SEED] = &seed_gen_argument;
+ generators[OFFSET_SEED] = &ansi_gen_seed_argument;
} else {
if (cfg->random) {
- generators[OFFSET_SEED] = &seed_gen_random;
+ generators[OFFSET_SEED] = &ansi_gen_seed_random;
} else {
- generators[OFFSET_SEED] = &seed_gen_input;
+ generators[OFFSET_SEED] = &ansi_gen_seed_input;
}
}
- generators[OFFSET_A] = &a_gen_seed;
- generators[OFFSET_B] = &b_gen_seed;
- generators[OFFSET_CURVE] = &curve_gen_seed;
+ generators[OFFSET_A] = &gen_skip;
+ generators[OFFSET_B] = &ansi_gen_equation;
+ generators[OFFSET_CURVE] = &curve_gen_nonzero;
+ generators[OFFSET_ORDER] = &order_gen_any;
} else {
// setup normal generators
generators[OFFSET_SEED] = &gen_skip;
@@ -142,7 +144,11 @@ static void exhaustive_ainit(arg_t **argss, const config_t *cfg) {
}
void exhaustive_uinit(unroll_t *unrolls, const config_t *cfg) {
- unrolls[OFFSET_SEED] = &unroll_skip;
+ if (cfg->ansi) {
+ unrolls[OFFSET_SEED] = &ansi_unroll_seed;
+ } else {
+ unrolls[OFFSET_SEED] = &unroll_skip;
+ }
unrolls[OFFSET_FIELD] = &unroll_skip;
unrolls[OFFSET_A] = &unroll_skip;
unrolls[OFFSET_B] = &unroll_skip;
@@ -176,8 +182,7 @@ int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
if (diff <= 0) {
if (diff == INT_MIN || state + diff < 0) {
- fprintf(err, "Error generating a curve. state = %i\n",
- state);
+ fprintf(err, "Error generating a curve. state = %i\n", state);
return 0;
}
// record try
diff --git a/src/exhaustive/exhaustive.h b/src/exhaustive/exhaustive.h
index 3b26d73..446dff2 100644
--- a/src/exhaustive/exhaustive.h
+++ b/src/exhaustive/exhaustive.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_GENERATORS_H
#define ECGEN_GENERATORS_H
-#include "gen/types.h"
+#include "misc/types.h"
/**
*
diff --git a/src/gen/curve.c b/src/gen/curve.c
index ea5ed95..3a8d00d 100644
--- a/src/gen/curve.c
+++ b/src/gen/curve.c
@@ -2,6 +2,7 @@
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
+#include <misc/config.h>
#include "curve.h"
#include "point.h"
#include "seed.h"
@@ -130,29 +131,6 @@ GENERATOR(curve_gen_nonzero) {
}
}
-static int curve_gen_seed_fp(curve_t *curve, const config_t *cfg, arg_t *args) {
- // TODO implement
- return INT_MIN;
-}
-
-static int curve_gen_seed_f2m(curve_t *curve, const config_t *cfg,
- arg_t *args) {
- // TODO implement
- return INT_MIN;
-}
-
-GENERATOR(curve_gen_seed) {
- switch (typ(curve->field)) {
- case t_INT:
- return curve_gen_seed_fp(curve, cfg, args);
- case t_FFELT:
- return curve_gen_seed_f2m(curve, cfg, args);
- default:
- pari_err_TYPE("curve_gen_seed", curve->field);
- return INT_MIN; /* NOT REACHABLE */
- }
-}
-
UNROLL(curve_unroll) {
if (curve->curve) {
obj_free(curve->curve);
diff --git a/src/gen/curve.h b/src/gen/curve.h
index 2e7651f..f5e6553 100644
--- a/src/gen/curve.h
+++ b/src/gen/curve.h
@@ -9,7 +9,7 @@
#define ECGEN_CURVE_H
#include <pari/pari.h>
-#include "types.h"
+#include "misc/types.h"
/**
* GENERATOR(gen_t)
@@ -35,18 +35,6 @@ GENERATOR(curve_gen_any);
*/
GENERATOR(curve_gen_nonzero);
-/**
- * GENERATOR(gen_t)
- * Creates a curve GEN in curve_t curve from field, a and b. Using the ANSI
- * X9.62 verifiably random algorithm.
- * Succeeds if a curve exists(non-zero discriminant).
- *
- * @param curve A curve_t being generated
- * @param cfg An application config
- * @param args unused
- * @return state diff
- */
-GENERATOR(curve_gen_seed);
/**
*
diff --git a/src/gen/equation.c b/src/gen/equation.c
index 9524df7..33d41a9 100644
--- a/src/gen/equation.c
+++ b/src/gen/equation.c
@@ -56,10 +56,6 @@ GENERATOR(a_gen_one) {
return 1;
}
-GENERATOR(a_gen_seed) {
- // TODO implement
- return INT_MIN;
-}
GENERATOR(b_gen_random) {
curve->b = genrand(curve->field);
@@ -111,11 +107,6 @@ GENERATOR(b_gen_one) {
return 1;
}
-GENERATOR(b_gen_seed) {
- // TODO implement
- return INT_MIN;
-}
-
void equation_quit(void) {
if (a && isclone(a)) {
gunclone(a);
diff --git a/src/gen/equation.h b/src/gen/equation.h
index 58e2e6e..665c153 100644
--- a/src/gen/equation.h
+++ b/src/gen/equation.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_EQUATION_H
#define ECGEN_EQUATION_H
-#include "types.h"
+#include "misc/types.h"
/**
* GENERATOR(gen_t)
diff --git a/src/gen/field.c b/src/gen/field.c
index 482bcc5..9a908cc 100644
--- a/src/gen/field.c
+++ b/src/gen/field.c
@@ -13,7 +13,8 @@ static GEN field_binaryr(unsigned long bits) {
if (poly_exists(bits)) {
return poly_find_gen(bits);
} else {
- fprintf(err, "Unable to find a suitable binary field. Use an explicit one.");
+ fprintf(err,
+ "Unable to find a suitable binary field. Use an explicit one.");
exit(1);
}
}
diff --git a/src/gen/field.h b/src/gen/field.h
index 04af2c6..da31298 100644
--- a/src/gen/field.h
+++ b/src/gen/field.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_FIELD_H
#define ECGEN_FIELD_H
-#include "types.h"
+#include "misc/types.h"
/**
* GENERATOR(gen_t)
diff --git a/src/gen/gens.h b/src/gen/gens.h
index f46efbf..c9e8169 100644
--- a/src/gen/gens.h
+++ b/src/gen/gens.h
@@ -9,7 +9,7 @@
#ifndef ECGEN_GENS_H
#define ECGEN_GENS_H
-#include "types.h"
+#include "misc/types.h"
/**
* GENERATOR(gen_t)
diff --git a/src/gen/order.h b/src/gen/order.h
index da62c4d..e798012 100644
--- a/src/gen/order.h
+++ b/src/gen/order.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_ORDER_H
#define ECGEN_ORDER_H
-#include "types.h"
+#include "misc/types.h"
/**
* GENERATOR(gen_t)
diff --git a/src/gen/point.h b/src/gen/point.h
index c8cae17..fdca6f7 100644
--- a/src/gen/point.h
+++ b/src/gen/point.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_POINT_H
#define ECGEN_POINT_H
-#include "types.h"
+#include "misc/types.h"
/**
*
diff --git a/src/gen/seed.c b/src/gen/seed.c
index 505493a..1653a50 100644
--- a/src/gen/seed.c
+++ b/src/gen/seed.c
@@ -4,13 +4,21 @@
*/
#include "seed.h"
+#include <misc/config.h>
#include "io/output.h"
+#include "misc/types.h"
+#include "util/bits.h"
#include "util/memory.h"
seed_t *seed_new(void) { return try_calloc(sizeof(seed_t)); }
seed_t *seed_copy(const seed_t *src, seed_t *dest) {
- if (src->seed) dest->seed = gcopy(src->seed);
+ if (src->seed) {
+ dest->seed = bits_copy(src->seed);
+ }
+ if (src->hash20) {
+ dest->hash20 = try_memdup(src->hash20, 20);
+ }
return dest;
}
@@ -20,8 +28,7 @@ seed_t *seed_new_copy(const seed_t *src) {
}
seed_t *seed_clone(const seed_t *src, seed_t *dest) {
- if (src->seed) dest->seed = gclone(src->seed);
- return dest;
+ return seed_copy(src, dest);
}
seed_t *seed_new_clone(const seed_t *src) {
@@ -31,75 +38,14 @@ seed_t *seed_new_clone(const seed_t *src) {
void seed_free(seed_t **seed) {
if (*seed) {
- if ((*seed)->seed && isclone((*seed)->seed)) {
- gunclone((*seed)->seed);
+ if ((*seed)->seed) {
+ bits_free(&(*seed)->seed);
+ }
+ if ((*seed)->hash20) {
+ try_free((*seed)->hash20);
}
try_free(*seed);
*seed = NULL;
}
}
-static GEN seed_stoi(const char *cstr) {
- pari_sp ltop = avma;
- GEN seed = gen_0;
-
- size_t len = strlen(cstr);
- for (size_t i = 0; i < len; ++i) {
- pari_sp btop = avma;
- GEN s = stoi(cstr[i]);
- s = shifti(s, (len - i - 1) * 8);
- seed = addii(seed, s);
- gerepileall(btop, 1, &seed);
- }
-
- return gerepilecopy(ltop, seed);
-}
-
-static char *seed_itos(GEN seed) {
- pari_sp ltop = avma;
- GEN bits = binary_zv(seed);
-
- long len = glength(bits);
- long bytes = (len / 8) + (len % 8 == 0 ? 0 : 1);
- char *result = try_malloc((size_t)bytes);
-
- for (long i = 0; i < len; ++i) {
- // TODO
- }
- avma = ltop;
- return result;
-}
-
-GENERATOR(seed_gen_random) {
- curve->seed = seed_new();
- curve->seed->seed = random_int(160);
- curve->seed->raw = seed_itos(curve->seed->seed);
- curve->seed->raw_len = strlen(curve->seed->raw);
- return 1;
-}
-
-GENERATOR(seed_gen_argument) {
- curve->seed = seed_new();
- curve->seed->seed = seed_stoi(cfg->seed);
- curve->seed->raw = cfg->seed;
- curve->seed->raw_len = strlen(cfg->seed);
- return 1;
-}
-
-GENERATOR(seed_gen_input) {
- pari_sp ltop = avma;
-
- GEN str = input_string("seed:");
- const char *cstr = GSTR(str);
- if (strlen(cstr) < 20) {
- fprintf(err, "SEED must be at least 160 bits(20 characters).\n");
- avma = ltop;
- return 0;
- }
-
- GEN seed = seed_stoi(cstr);
-
- curve->seed = seed_new();
- curve->seed->seed = gerepilecopy(ltop, seed);
- return 1;
-}
diff --git a/src/gen/seed.h b/src/gen/seed.h
index 82eb499..c89fc1d 100644
--- a/src/gen/seed.h
+++ b/src/gen/seed.h
@@ -9,16 +9,16 @@
#define ECGEN_SEED_H
#include "io/input.h"
-#include "types.h"
+#include "misc/types.h"
/**
- *
+ * @brief
* @return
*/
seed_t *seed_new(void);
/**
- *
+ * @brief
* @param src
* @param dest
* @return
@@ -26,14 +26,14 @@ seed_t *seed_new(void);
seed_t *seed_copy(const seed_t *src, seed_t *dest);
/**
- *
+ * @brief
* @param src
* @return
*/
seed_t *seed_new_copy(const seed_t *src);
/**
- *
+ * @brief
* @param src
* @param dest
* @return
@@ -41,43 +41,17 @@ seed_t *seed_new_copy(const seed_t *src);
seed_t *seed_clone(const seed_t *src, seed_t *dest);
/**
- *
+ * @brief
* @param src
* @return
*/
seed_t *seed_new_clone(const seed_t *src);
/**
- *
+ * @brief
* @param seed
*/
void seed_free(seed_t **seed);
-/**
- *
- * @param curve A curve_t being generated
- * @param cfg An application config
- * @param args unused
- * @return state diff
- */
-GENERATOR(seed_gen_random);
-
-/**
- *
- * @param curve A curve_t being generated
- * @param cfg An application config
- * @param args unused
- * @return state diff
- */
-GENERATOR(seed_gen_argument);
-
-/**
- *
- * @param curve A curve_t being generated
- * @param cfg An application config
- * @param args unused
- * @return state diff
- */
-GENERATOR(seed_gen_input);
#endif // ECGEN_SEED_H
diff --git a/src/invalid/invalid.h b/src/invalid/invalid.h
index 035692c..a08c5d8 100644
--- a/src/invalid/invalid.h
+++ b/src/invalid/invalid.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_INVALID_H
#define ECGEN_INVALID_H
-#include "io/config.h"
+#include "misc/config.h"
/**
*
diff --git a/src/invalid/invalid_thread.h b/src/invalid/invalid_thread.h
index bedaf60..0f1b4d0 100644
--- a/src/invalid/invalid_thread.h
+++ b/src/invalid/invalid_thread.h
@@ -9,7 +9,7 @@
#define ECGEN_INVALID_THREAD_H
#include <pthread.h>
-#include "gen/types.h"
+#include "misc/types.h"
typedef enum { STATE_FREE, STATE_GENERATING, STATE_GENERATED } state_e;
diff --git a/src/io/cli.c b/src/io/cli.c
index 1cbf3b9..4545e7f 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -5,7 +5,8 @@
#include "cli.h"
#include <string.h>
#include <unistd.h>
-#include "config.h"
+#include "misc/config.h"
+#include "exhaustive/ansi.h"
char cli_doc[] =
"ecgen, tool for generating Elliptic curve domain parameters.\v(C) 2017 "
@@ -18,7 +19,7 @@ enum opt_keys {
OPT_PRIME = 'p',
OPT_COFACTOR = 'k',
OPT_RANDOM = 'r',
- OPT_SEED = 's',
+ OPT_ANSI = 's',
OPT_INVALID = 'i',
OPT_ORDER = 'n',
OPT_KOBLITZ = 'K',
@@ -51,7 +52,7 @@ struct argp_option cli_options[] = {
{"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/all/nonprime/none).", 2},
- {"seed", OPT_SEED, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure). **NOT IMPLEMENTED**", 2},
+ {"ansi", OPT_ANSI, "SEED", OPTION_ARG_OPTIONAL, "Generate a curve from SEED (ANSI X9.62 verifiable procedure).", 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},
@@ -197,14 +198,13 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
}
break;
}
- case OPT_SEED:
- cfg->from_seed = true;
+ case OPT_ANSI:
+ cfg->ansi = true;
if (arg) {
- // ANSI X9.62 specifies seed as at least 160 bits in length.
- if (strlen(arg) < 20) {
+ if (!ansi_seed_valid(arg)) {
argp_failure(
state, 1, 0,
- "SEED must be at least 160 bits (20 characters).");
+ "SEED must be at least 160 bits (40 characters).");
}
cfg->seed = arg;
}
@@ -236,13 +236,13 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
}
// Invalid is not prime or seed by definition.
if (cfg->invalid &&
- (cfg->prime || cfg->from_seed || cfg->cofactor)) {
+ (cfg->prime || cfg->ansi || cfg->cofactor)) {
// not seed, not prime
argp_failure(state, 1, 0,
"Invalid curve generation can not generate curves "
"from seed, exhaustive or prime order.");
}
- if (cfg->cm && (cfg->prime || cfg->from_seed || cfg->invalid ||
+ if (cfg->cm && (cfg->prime || cfg->ansi || cfg->invalid ||
cfg->cofactor || cfg->anomalous)) {
argp_failure(state, 1, 0,
"Fixed order curve generation can not generate "
@@ -251,7 +251,7 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
"prime.");
}
if (cfg->anomalous &&
- (cfg->binary_field || cfg->cofactor || cfg->from_seed ||
+ (cfg->binary_field || cfg->cofactor || cfg->ansi ||
cfg->cm || cfg->invalid || cfg->koblitz)) {
argp_failure(
state, 1, 0,
diff --git a/src/io/input.c b/src/io/input.c
index 2c0398a..f86afe4 100644
--- a/src/io/input.c
+++ b/src/io/input.c
@@ -26,20 +26,8 @@ static GEN input_i(const char *prompt, unsigned long bits) {
free(line);
return gen_m1;
}
- for (size_t i = 0, j = 0; (line[j] = line[i]); j += !isspace(line[i++]));
-
-/* if (len <= 3 || !(line[0] == '0' && (line[1] == 'x' || line[1] == 'X'))) {
- char *new_line = try_realloc(line, (size_t)(len + 2));
- memmove(new_line + 2, new_line, (size_t)len);
- new_line[0] = '0';
- new_line[1] = 'x';
- if (!feof(in)) {
- new_line[len + 1] = 0;
- } else {
- new_line[len + 2] = 0;
- }
- line = new_line;
- }*/
+ for (size_t i = 0, j = 0; (line[j] = line[i]); j += !isspace(line[i++]))
+ ;
pari_sp ltop = avma;
GEN in = strtoi(line);
diff --git a/src/io/input.h b/src/io/input.h
index 2759973..eb836e2 100644
--- a/src/io/input.h
+++ b/src/io/input.h
@@ -8,7 +8,7 @@
#ifndef ECGEN_INPUT_H
#define ECGEN_INPUT_H
-#include "gen/types.h"
+#include "misc/types.h"
#include "util/random.h"
/**
diff --git a/src/io/output.c b/src/io/output.c
index 2d05bec..4e951a2 100644
--- a/src/io/output.c
+++ b/src/io/output.c
@@ -5,6 +5,7 @@
#include "output.h"
#include <parson/parson.h>
+#include "util/bits.h"
#include "gen/field.h"
#include "util/memory.h"
@@ -29,23 +30,23 @@ char *output_scsv(curve_t *curve, const config_t *cfg) {
switch (cfg->field) {
case FIELD_PRIME:
params[OFFSET_FIELD] =
- pari_sprintf("%P0#*x", cfg->hex_digits, curve->field);
+ pari_sprintf("%P0#*x", cfg->hex_digits, curve->field);
break;
case FIELD_BINARY: {
GEN field = field_params(curve->field);
params[OFFSET_FIELD] =
- pari_sprintf("%P#x,%P#x,%P#x,%P#x", gel(field, 1),
- gel(field, 2), gel(field, 3), gel(field, 4));
+ pari_sprintf("%P#x,%P#x,%P#x,%P#x", gel(field, 1),
+ gel(field, 2), gel(field, 3), gel(field, 4));
break;
}
}
if (curve->a)
params[OFFSET_A] =
- pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->a));
+ pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->a));
if (curve->b)
params[OFFSET_B] =
- pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->b));
+ pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->b));
if (curve->generators) {
char *gens[curve->ngens];
@@ -55,8 +56,8 @@ char *output_scsv(curve_t *curve, const config_t *cfg) {
GEN x = field_elementi(gel(generator->point, 1));
GEN y = field_elementi(gel(generator->point, 2));
gens[i] = pari_sprintf("%P0#*x,%P0#*x,%P#x,%P#x", cfg->hex_digits,
- x, cfg->hex_digits, y, generator->order,
- generator->cofactor);
+ x, cfg->hex_digits, y, generator->order,
+ generator->cofactor);
len += strlen(gens[i]);
}
size_t lenn = sizeof(char) * (len + curve->ngens);
@@ -70,7 +71,7 @@ char *output_scsv(curve_t *curve, const config_t *cfg) {
if (curve->order)
params[OFFSET_ORDER] =
- pari_sprintf("%P0#*x", cfg->hex_digits, curve->order);
+ pari_sprintf("%P0#*x", cfg->hex_digits, curve->order);
if (curve->points) {
char *points[curve->npoints];
@@ -80,7 +81,7 @@ char *output_scsv(curve_t *curve, const config_t *cfg) {
GEN x = field_elementi(gel(point->point, 1));
GEN y = field_elementi(gel(point->point, 2));
points[i] = pari_sprintf("%P0#*x,%P0#*x,%P#x", cfg->hex_digits, x,
- cfg->hex_digits, y, point->order);
+ cfg->hex_digits, y, point->order);
len += strlen(points[i]);
}
size_t lenn = sizeof(char) * (len + curve->npoints);
@@ -150,9 +151,20 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
pari_free(e3);
break;
}
- default: fprintf(err, "Error, field has unknown amount of elements.\n");
+ default:
+ fprintf(err, "Error, field has unknown amount of elements.\n");
exit(1);
}
+ if (curve->seed) {
+ char *hex_str = bits_to_hex(curve->seed->seed);
+ char *hex = try_calloc(strlen(hex_str) + 3);
+ hex[0] = '0';
+ hex[1] = 'x';
+ strcat(hex, hex_str);
+ json_object_set_string(root_object, "seed", hex);
+ try_free(hex_str);
+ try_free(hex);
+ }
char *a = pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->a));
json_object_set_string(root_object, "a", a);
@@ -172,13 +184,13 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
JSON_Object *point_object = json_value_get_object(point_value);
char *x = pari_sprintf(
- "%P0#*x", cfg->hex_digits,
- field_elementi(gel(curve->generators[i]->point, 1)));
+ "%P0#*x", cfg->hex_digits,
+ field_elementi(gel(curve->generators[i]->point, 1)));
json_object_set_string(point_object, "x", x);
pari_free(x);
char *y = pari_sprintf(
- "%P0#*x", cfg->hex_digits,
- field_elementi(gel(curve->generators[i]->point, 2)));
+ "%P0#*x", cfg->hex_digits,
+ field_elementi(gel(curve->generators[i]->point, 2)));
json_object_set_string(point_object, "y", y);
pari_free(y);
char *p_order = pari_sprintf("%P#x", curve->generators[i]->order);
@@ -186,7 +198,7 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
pari_free(p_order);
if (curve->generators[i]->cofactor) {
char *cofactor =
- pari_sprintf("%P#x", curve->generators[i]->cofactor);
+ pari_sprintf("%P#x", curve->generators[i]->cofactor);
json_object_set_string(point_object, "cofactor", cofactor);
pari_free(cofactor);
}
@@ -206,13 +218,13 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
JSON_Object *point_object = json_value_get_object(point_value);
char *x =
- pari_sprintf("%P0#*x", cfg->hex_digits,
- field_elementi(gel(curve->points[i]->point, 1)));
+ pari_sprintf("%P0#*x", cfg->hex_digits,
+ field_elementi(gel(curve->points[i]->point, 1)));
json_object_set_string(point_object, "x", x);
pari_free(x);
char *y =
- pari_sprintf("%P0#*x", cfg->hex_digits,
- field_elementi(gel(curve->points[i]->point, 2)));
+ pari_sprintf("%P0#*x", cfg->hex_digits,
+ field_elementi(gel(curve->points[i]->point, 2)));
json_object_set_string(point_object, "y", y);
pari_free(y);
char *p_order = pari_sprintf("%P#x", curve->points[i]->order);
@@ -220,7 +232,7 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
pari_free(p_order);
if (curve->points[i]->cofactor) {
char *cofactor =
- pari_sprintf("%P#x", curve->points[i]->cofactor);
+ pari_sprintf("%P#x", curve->points[i]->cofactor);
json_object_set_string(point_object, "cofactor", cofactor);
pari_free(cofactor);
}
diff --git a/src/io/output.h b/src/io/output.h
index 586f4e8..6c241d5 100644
--- a/src/io/output.h
+++ b/src/io/output.h
@@ -10,7 +10,7 @@
#include <pari/pari.h>
#include <stdbool.h>
-#include "gen/types.h"
+#include "misc/types.h"
#ifdef DEBUG
diff --git a/src/math/subgroups.c b/src/math/subgroups.c
index 93526ae..45523ad 100644
--- a/src/math/subgroups.c
+++ b/src/math/subgroups.c
@@ -54,6 +54,7 @@ static GEN subgroups_divisors(GEN order) {
* @return a t_VEC of factors
*/
static GEN subgroups_2n_factors(GEN factors, size_t min_bits) {
+ pari_sp ltop = avma;
long nprimes = glength(factors);
if (nprimes == min_bits) return NULL;
GEN amount = int2n(nprimes);
@@ -77,17 +78,8 @@ static GEN subgroups_2n_factors(GEN factors, size_t min_bits) {
avma = btop;
}
}
- GEN sorted = sort(groups);
- size_t k = 1;
- for (size_t j = 1; j <= i; j++) {
- GEN k_value = gel(sorted, k);
- GEN j_value = gel(sorted, j);
- if (!gequal(k_value, j_value)) {
- gel(sorted, ++k) = j_value;
- }
- }
- sorted = vec_shorten(sorted, k);
- return sorted;
+ GEN ret = gtoset(groups);
+ return gerepilecopy(ltop, ret);
}
/**
diff --git a/src/math/subgroups.h b/src/math/subgroups.h
index fee095b..1c11d4c 100644
--- a/src/math/subgroups.h
+++ b/src/math/subgroups.h
@@ -9,7 +9,7 @@
#define ECGEN_SUBGROUPS_H
#include <pari/pari.h>
-#include "gen/types.h"
+#include "misc/types.h"
/**
* @brief Enumerates prime subgroup orders of a given curve.
diff --git a/src/io/config.h b/src/misc/config.h
index 0894b5e..7b9a9dc 100644
--- a/src/io/config.h
+++ b/src/misc/config.h
@@ -41,7 +41,7 @@ typedef struct {
long koblitz_value;
bool cofactor;
long cofactor_bound;
- bool from_seed;
+ bool ansi;
char *seed;
bool unique;
struct points_s points;
diff --git a/src/gen/types.c b/src/misc/types.c
index 63d5401..63d5401 100644
--- a/src/gen/types.c
+++ b/src/misc/types.c
diff --git a/src/gen/types.h b/src/misc/types.h
index 5500e85..b75394c 100644
--- a/src/gen/types.h
+++ b/src/misc/types.h
@@ -10,15 +10,37 @@
#include <limits.h>
#include <pari/pari.h>
-#include "io/config.h"
+#include "misc/config.h"
+
+/**
+ * @brief
+ * @param bits
+ * @param bitlen
+ * @param allocated
+ */
+typedef struct {
+ unsigned char *bits;
+ size_t bitlen;
+ size_t allocated;
+} bits_t;
/**
* @brief
*/
typedef struct seed_t {
- char *raw;
- size_t raw_len;
- GEN seed;
+ bits_t *seed;
+ unsigned char *hash20;
+ union {
+ struct {
+ GEN t;
+ GEN s;
+ GEN h;
+ GEN r;
+ } ansi;
+ struct {
+ bits_t *f;
+ } brainpool;
+ };
} seed_t;
/**
@@ -91,7 +113,8 @@ typedef struct {
* @return state diff
*/
#define GENERATOR(gen_name) \
- int gen_name(curve_t *curve, const config_t *cfg, arg_t *args)
+ int gen_name(curve_t *curve, const config_t *cfg, arg_t *args)
+
typedef GENERATOR((*gen_t));
/**
@@ -103,8 +126,9 @@ typedef GENERATOR((*gen_t));
* @return
*/
#define UNROLL(unroll_name) \
- int unroll_name(curve_t *curve, const config_t *cfg, pari_sp from, \
- pari_sp to)
+ int unroll_name(curve_t *curve, const config_t *cfg, pari_sp from, \
+ pari_sp to)
+
typedef UNROLL((*unroll_t));
/**
diff --git a/src/util/bits.c b/src/util/bits.c
new file mode 100644
index 0000000..55d5bf3
--- /dev/null
+++ b/src/util/bits.c
@@ -0,0 +1,430 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+
+#include "bits.h"
+#include <sha1/sha1.h>
+#include "util/memory.h"
+
+bits_t *bits_new(size_t bit_len) {
+ bits_t *result = try_calloc(sizeof(bits_t));
+ size_t byte_len = BYTE_LEN(bit_len);
+ if (byte_len > 0) result->bits = try_calloc(byte_len);
+ result->allocated = byte_len;
+ result->bitlen = bit_len;
+ return result;
+}
+
+bits_t *bits_copy(const bits_t *bits) {
+ bits_t *result = try_calloc(sizeof(bits_t));
+ result->bitlen = bits->bitlen;
+ result->allocated = bits->allocated;
+ if (bits->allocated != 0)
+ result->bits = try_memdup(bits->bits, result->allocated);
+ return result;
+}
+
+void bits_free(bits_t **bits) {
+ if (*bits) {
+ if ((*bits)->bits) {
+ try_free((*bits)->bits);
+ }
+ try_free(*bits);
+ *bits = NULL;
+ }
+}
+
+bits_t *bits_from_i(GEN i) {
+ pari_sp ltop = avma;
+ GEN bitvec = binary_zv(i);
+ size_t bit_len = (size_t)glength(bitvec);
+ bits_t *result = bits_new(bit_len);
+ for (size_t j = 0; j < bit_len; ++j) {
+ if (gel(bitvec, j + 1) == (GEN)1) {
+ result->bits[j / 8] |= 1 << (7 - (j % 8));
+ }
+ }
+ avma = ltop;
+ return result;
+}
+
+bits_t *bits_from_hex(const char *hex_str) {
+ size_t nibble_len = strlen(hex_str);
+ bits_t *result = bits_new(nibble_len * 4);
+ for (size_t i = 0; i < nibble_len; ++i) {
+ char hex = hex_str[i];
+ char nibble = 0;
+ if ('0' <= hex && hex <= '9') {
+ nibble = (char)(hex - '0');
+ } else if ('a' <= hex && hex <= 'f') {
+ nibble = (char)(hex - 'a' + 10);
+ } else if ('A' <= hex && hex <= 'F') {
+ nibble = (char)(hex - 'A' + 10);
+ }
+ result->bits[i / 2] |= (nibble << (1 - (i % 2)) * 4);
+ }
+ return result;
+}
+
+bits_t *bits_from_bin(const char *bin_str) {
+ size_t bit_len = strlen(bin_str);
+ bits_t *result = bits_new(bit_len);
+ for (size_t i = 0; i < bit_len; ++i) {
+ if (bin_str[i] == '1') {
+ result->bits[i / 8] |= 1 << (7 - (i % 8));
+ }
+ }
+ return result;
+}
+
+bits_t *bits_from_raw(const unsigned char *bits, size_t bit_len) {
+ bits_t *result = try_calloc(sizeof(bits_t));
+ result->bitlen = bit_len;
+ result->allocated = BYTE_LEN(bit_len);
+ if (bit_len > 0) result->bits = try_memdup(bits, result->allocated);
+ return result;
+}
+
+bits_t *bits_from_bitvec(GEN v) {
+ size_t bit_len = (size_t)glength(v);
+ bits_t *result = bits_new(bit_len);
+ for (size_t i = 0; i < bit_len; ++i) {
+ if (gel(v, i + 1) == (GEN)1) result->bits[i / 8] |= 1 << (7 - (i % 8));
+ }
+ return result;
+}
+
+GEN bits_to_i(const bits_t *bits) {
+ pari_sp ltop = avma;
+ GEN result = stoi(0);
+ for (size_t i = 0; i < bits->bitlen; ++i) {
+ if (GET_BIT(bits->bits, i) != 0)
+ result = addii(result, int2n(bits->bitlen - i - 1));
+ }
+ return gerepileupto(ltop, result);
+}
+
+char *bits_to_hex(const bits_t *bits) {
+ char *result = try_calloc(BYTE_LEN(bits->bitlen) * 2 + 1);
+ // probably right pad with zeroes, as thats what is actually stored.
+ for (size_t i = 0; i < BYTE_LEN(bits->bitlen); ++i) {
+ sprintf(result + (i * 2), "%02x", bits->bits[i]);
+ }
+ return result;
+}
+
+char *bits_to_bin(const bits_t *bits) {
+ char *result = try_calloc(bits->bitlen + 1);
+ for (size_t i = 0; i < bits->bitlen; ++i) {
+ sprintf(result + i, "%1u", GET_BIT(bits->bits, i));
+ }
+ return result;
+}
+
+unsigned char *bits_to_raw(const bits_t *bits) {
+ if (bits->bitlen == 0) {
+ return NULL;
+ }
+ return try_memdup(bits->bits, BYTE_LEN(bits->bitlen));
+}
+
+size_t bits_to_rawlen(const bits_t *bits) { return BYTE_LEN(bits->bitlen); }
+
+GEN bits_to_bitvec(const bits_t *bits) {
+ GEN bitvec = gtovecsmall0(gen_0, bits->bitlen);
+ for (size_t i = 0; i < bits->bitlen; ++i) {
+ if (GET_BIT(bits->bits, i) != 0) gel(bitvec, i + 1) = (GEN)1;
+ }
+ return bitvec;
+}
+
+static unsigned char or_func(unsigned char one, unsigned char other) {
+ return one | other;
+}
+
+static unsigned char and_func(unsigned char one, unsigned char other) {
+ return one & other;
+}
+
+static bits_t *bits_bitwise(const bits_t *one, const bits_t *other,
+ unsigned char (*bitwise_func)(unsigned char,
+ unsigned char)) {
+ const bits_t *shorter;
+ const bits_t *longer;
+ if (one->bitlen > other->bitlen) {
+ shorter = other;
+ longer = one;
+ } else {
+ shorter = one;
+ longer = other;
+ }
+
+ bits_t *result = bits_new(longer->bitlen);
+ for (size_t i = 0; i < longer->bitlen; ++i) {
+ size_t longer_pos = longer->bitlen - i - 1;
+
+ unsigned char longer_bit =
+ (unsigned char)GET_BIT(longer->bits, longer_pos);
+ unsigned char shorter_bit = 0;
+ if (shorter->bitlen > i) {
+ size_t shorter_pos = shorter->bitlen - i - 1;
+ shorter_bit = (unsigned char)GET_BIT(shorter->bits, shorter_pos);
+ }
+
+ unsigned char result_bit = bitwise_func(longer_bit, shorter_bit);
+ result->bits[longer_pos / 8] |= result_bit << (7 - (longer_pos % 8));
+ }
+
+ return result;
+}
+
+void bits_concatzv(bits_t *one, va_list valist) {
+ const bits_t *next;
+ while ((next = va_arg(valist, const bits_t *)) != NULL) {
+ if (next->bitlen == 0) continue;
+ size_t new_bitlen = one->bitlen + next->bitlen;
+ size_t new_alloc = BYTE_LEN(new_bitlen);
+ if (new_alloc > one->allocated) {
+ one->bits = try_realloc(one->bits, new_alloc);
+ for (size_t i = one->allocated; i < new_alloc; ++i) {
+ one->bits[i] = 0;
+ }
+ one->allocated = new_alloc;
+ }
+ for (size_t j = 0; j < next->bitlen; ++j) {
+ SET_BIT(one->bits, one->bitlen + j, GET_BIT(next->bits, j));
+ }
+ one->bitlen = new_bitlen;
+ }
+}
+
+void bits_concatz(bits_t *one, ...) {
+ va_list valist;
+ va_start(valist, one);
+
+ bits_concatzv(one, valist);
+
+ va_end(valist);
+}
+
+bits_t *bits_concat(const bits_t *one, ...) {
+ va_list valist;
+ va_start(valist, one);
+
+ bits_t *result = bits_copy(one);
+
+ bits_concatzv(result, valist);
+
+ va_end(valist);
+ return result;
+}
+
+bits_t *bits_or(const bits_t *one, const bits_t *other) {
+ return bits_bitwise(one, other, or_func);
+}
+
+bits_t *bits_and(const bits_t *one, const bits_t *other) {
+ return bits_bitwise(one, other, and_func);
+}
+
+void bits_notz(bits_t *bits) {
+ if (bits->bitlen == 0) return;
+ for (size_t i = 0; i < bits->bitlen / 8; ++i) {
+ bits->bits[i] = ~bits->bits[i];
+ }
+ if (bits->bitlen % 8 != 0) {
+ size_t mask_len = bits->bitlen % 8;
+ unsigned char mask = 0;
+ for (size_t i = 7; i >= 0; --i) {
+ mask |= 1 << i;
+ if (--mask_len == 0) break;
+ }
+ size_t last_pos = (bits->bitlen / 8);
+ unsigned char anti_mask = ~mask;
+ unsigned char last_byte = bits->bits[last_pos];
+ bits->bits[last_pos] = (~last_byte & mask) | (last_byte & anti_mask);
+ }
+}
+
+bits_t *bits_not(const bits_t *bits) {
+ bits_t *result = bits_copy(bits);
+ bits_notz(result);
+ return result;
+}
+
+void bits_rotz(bits_t *bits) {
+ unsigned char original_bits[bits->allocated];
+ for (size_t i = 0; i < bits->allocated; ++i) {
+ original_bits[i] = bits->bits[i];
+ bits->bits[i] = 0;
+ }
+ for (size_t i = 0; i < bits->bitlen / 2; ++i) {
+ size_t left_pos = i;
+ size_t right_pos = bits->bitlen - i - 1;
+ unsigned char left_bit =
+ (unsigned char)GET_BIT(original_bits, left_pos);
+ unsigned char right_bit =
+ (unsigned char)GET_BIT(original_bits, right_pos);
+ bits->bits[right_pos / 8] |= left_bit << (7 - (right_pos % 8));
+ bits->bits[left_pos / 8] |= right_bit << (7 - (left_pos % 8));
+ }
+ if (bits->bitlen % 2 == 1) {
+ size_t middle_pos = bits->bitlen / 2;
+
+ unsigned char middle_bit =
+ (unsigned char)GET_BIT(original_bits, middle_pos);
+ bits->bits[middle_pos / 8] |= middle_bit << (7 - (middle_pos % 8));
+ }
+}
+
+bits_t *bits_rot(const bits_t *bits) {
+ bits_t *result = bits_copy(bits);
+ bits_rotz(result);
+ return result;
+}
+
+void bits_shiftz(bits_t *bits, long amount) {
+ if (amount == 0) return;
+ unsigned char original_bits[bits->allocated];
+ for (size_t i = 0; i < bits->allocated; ++i) {
+ original_bits[i] = bits->bits[i];
+ bits->bits[i] = 0;
+ }
+ for (size_t i = 0; i < bits->bitlen; ++i) {
+ unsigned char new_bit = 0;
+ if ((amount > 0 && i + amount < bits->bitlen) ||
+ (amount < 0 && i >= -amount)) {
+ new_bit = (unsigned char)GET_BIT(original_bits, i + amount);
+ }
+ bits->bits[i / 8] |= new_bit << (7 - (i % 8));
+ }
+}
+
+bits_t *bits_shift(const bits_t *bits, long amount) {
+ bits_t *result = bits_copy(bits);
+ bits_shiftz(result, amount);
+ return result;
+}
+
+void bits_shiftrz(bits_t *bits, long amount) {
+ if (amount == 0) return;
+ unsigned char original_bits[bits->allocated];
+ for (size_t i = 0; i < bits->allocated; ++i) {
+ original_bits[i] = bits->bits[i];
+ bits->bits[i] = 0;
+ }
+ for (size_t i = 0; i < bits->bitlen; ++i) {
+ unsigned char new_bit = 0;
+ size_t new_pos = 0;
+ if ((amount > 0 && i + amount < bits->bitlen) ||
+ (amount < 0 && i >= -amount)) {
+ new_pos = i + amount;
+ } else if (amount > 0) {
+ new_pos = (i + amount) % bits->bitlen;
+ } else if (amount < 0) {
+ long mod_amount = amount % bits->bitlen;
+ new_pos = (i + mod_amount) % bits->bitlen;
+ }
+ new_bit = (unsigned char)GET_BIT(original_bits, new_pos);
+ bits->bits[i / 8] |= new_bit << (7 - (i % 8));
+ }
+}
+
+bits_t *bits_shiftr(const bits_t *bits, long amount) {
+ bits_t *result = bits_copy(bits);
+ bits_shiftrz(result, amount);
+ return result;
+}
+
+void bits_shiftiz(bits_t *bits, long amount) {
+ if (amount > 0) {
+ bits_lengthenz(bits, -amount);
+ } else if (amount < 0) {
+ bits_shortenz(bits, amount);
+ }
+}
+
+bits_t *bits_shifti(const bits_t *bits, long amount) {
+ bits_t *result = bits_copy(bits);
+ bits_shiftiz(result, amount);
+ return result;
+}
+
+void bits_lengthenz(bits_t *bits, long amount) {
+ size_t abs_amount;
+ if (amount > 0) {
+ abs_amount = (size_t)amount;
+ } else if (amount < 0) {
+ abs_amount = (size_t)-amount;
+ } else {
+ return;
+ }
+ size_t new_alloc = BYTE_LEN(bits->bitlen + abs_amount);
+ if (new_alloc > bits->allocated) {
+ bits->bits = try_realloc(bits->bits, new_alloc);
+ for (size_t i = bits->allocated; i < new_alloc; ++i) {
+ bits->bits[i] = 0;
+ }
+ bits->allocated = new_alloc;
+ }
+ bits->bitlen += abs_amount;
+
+ if (amount > 0) {
+ bits_shiftz(bits, -amount);
+ }
+}
+
+bits_t *bits_lengthen(const bits_t *bits, long amount) {
+ bits_t *result = bits_copy(bits);
+ bits_lengthenz(result, amount);
+ return result;
+}
+
+void bits_shortenz(bits_t *bits, long amount) {
+ size_t new_bits;
+ if (amount > 0) {
+ new_bits = bits->bitlen - amount;
+ bits_shiftz(bits, amount);
+ } else if (amount < 0) {
+ new_bits = bits->bitlen + amount;
+ for (size_t i = new_bits; i < bits->bitlen; ++i) {
+ bits->bits[i / 8] &= ~(1 << (7 - (i % 8)));
+ }
+ } else {
+ return;
+ }
+ bits->bitlen = new_bits;
+}
+
+bits_t *bits_shorten(const bits_t *bits, long amount) {
+ bits_t *result = bits_copy(bits);
+ bits_shortenz(result, amount);
+ return result;
+}
+
+void bits_sha1(const bits_t *bits, unsigned char hashout[20]) {
+ SHA_CTX ctx = {0};
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, bits->bits, (int)BYTE_LEN(bits->bitlen));
+ SHA1_Final(hashout, &ctx);
+}
+
+bool bits_eq(const bits_t *one, const bits_t *other) {
+ if (one->bitlen != other->bitlen) return false;
+ if (one->bitlen == 0) return true;
+ if (memcmp(one->bits, other->bits, one->bitlen / 8) != 0) return false;
+ if (one->bitlen % 8 != 0) {
+ size_t mask_len = one->bitlen % 8;
+ unsigned char mask = 0;
+ for (size_t i = 7; i >= 0; --i) {
+ mask |= 1 << i;
+ if (--mask_len == 0) break;
+ }
+ size_t last_byte = (one->bitlen / 8);
+ unsigned char one_masked = one->bits[last_byte] & mask;
+ unsigned char other_masked = other->bits[last_byte] & mask;
+ return one_masked == other_masked;
+ }
+ return true;
+}
diff --git a/src/util/bits.h b/src/util/bits.h
new file mode 100644
index 0000000..3ea0dd2
--- /dev/null
+++ b/src/util/bits.h
@@ -0,0 +1,96 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+
+#ifndef ECGEN_BITS_H
+#define ECGEN_BITS_H
+
+#include "misc/types.h"
+
+#define BYTE_LEN(bit_len) \
+ (((bit_len) % 8 == 0) ? (bit_len) / 8 : ((bit_len) / 8) + 1)
+
+#define GET_BIT(bit_array, bit_pos) \
+ (((bit_array)[(bit_pos) / 8] & (1 << (7 - ((bit_pos) % 8)))) >> \
+ (7 - ((bit_pos) % 8)))
+
+#define SET_BIT(bit_array, bit_pos, bit_value) \
+ do { \
+ unsigned char val = 1 << (7 - ((bit_pos) % 8)); \
+ if ((bit_value) == 1) { \
+ (bit_array)[(bit_pos) / 8] |= val; \
+ } else { \
+ (bit_array)[(bit_pos) / 8] &= ~val; \
+ } \
+ } while (0);
+
+bits_t *bits_new(size_t bit_len);
+
+bits_t *bits_copy(const bits_t *bits);
+
+void bits_free(bits_t **bits);
+
+bits_t *bits_from_i(GEN i);
+
+bits_t *bits_from_hex(const char *hex_str);
+
+bits_t *bits_from_bin(const char *bin_str);
+
+bits_t *bits_from_raw(const unsigned char *bits, size_t bit_len);
+
+bits_t *bits_from_bitvec(GEN v);
+
+GEN bits_to_i(const bits_t *bits);
+
+char *bits_to_hex(const bits_t *bits);
+
+char *bits_to_bin(const bits_t *bits);
+
+unsigned char *bits_to_raw(const bits_t *bits);
+
+size_t bits_to_rawlen(const bits_t *bits);
+
+GEN bits_to_bitvec(const bits_t *bits);
+
+void bits_concatz(bits_t *one, ...);
+
+bits_t *bits_concat(const bits_t *one, ...);
+
+bits_t *bits_or(const bits_t *one, const bits_t *other);
+
+bits_t *bits_and(const bits_t *one, const bits_t *other);
+
+void bits_notz(bits_t *bits);
+
+bits_t *bits_not(const bits_t *bits);
+
+void bits_rotz(bits_t *bits);
+
+bits_t *bits_rot(const bits_t *bits);
+
+void bits_shiftz(bits_t *bits, long amount);
+
+bits_t *bits_shift(const bits_t *bits, long amount);
+
+void bits_shiftrz(bits_t *bits, long amount);
+
+bits_t *bits_shiftr(const bits_t *bits, long amount);
+
+void bits_shiftiz(bits_t *bits, long amount);
+
+bits_t *bits_shifti(const bits_t *bits, long amount);
+
+void bits_lengthenz(bits_t *bits, long amount);
+
+bits_t *bits_lengthen(const bits_t *bits, long amount);
+
+void bits_shortenz(bits_t *bits, long amount);
+
+bits_t *bits_shorten(const bits_t *bits, long amount);
+
+void bits_sha1(const bits_t *bits, unsigned char hashout[20]);
+
+bool bits_eq(const bits_t *one, const bits_t *other);
+
+#endif // ECGEN_BITS_H
diff --git a/src/util/memory.c b/src/util/memory.c
index 53f68c9..6051459 100644
--- a/src/util/memory.c
+++ b/src/util/memory.c
@@ -5,7 +5,6 @@
#include "memory.h"
#include <pari/pari.h>
-
static void *(*malloc_func)(size_t) = pari_malloc;
static void *(*calloc_func)(size_t) = pari_calloc;
@@ -25,9 +24,7 @@ void *alloc(void *(*fun)(size_t), size_t size) {
void *try_malloc(size_t size) { return alloc(malloc_func, size); }
-void *try_calloc(size_t size) {
- return alloc(calloc_func, size);
-}
+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);
@@ -38,13 +35,22 @@ void *try_realloc(void *ptr, size_t size) {
return result;
}
-void try_free(void *ptr) {
- free_func(ptr);
+char *try_strdup(const char *str) {
+ size_t len = strlen(str);
+ return try_memdup(str, len + 1);
+}
+
+void *try_memdup(const void *mem, size_t len) {
+ void *result = try_malloc(len);
+ memcpy(result, mem, len);
+ return result;
}
+void try_free(void *ptr) { free_func(ptr); }
+
void set_mem_funcs(void *(*malloc_fun)(size_t), void *(*calloc_fun)(size_t),
- void *(*realloc_fun)(void *, size_t),
- void(*free_fun)(void *)) {
+ void *(*realloc_fun)(void *, size_t),
+ void (*free_fun)(void *)) {
malloc_func = malloc_fun;
calloc_func = calloc_fun;
realloc_func = realloc_fun;
diff --git a/src/util/memory.h b/src/util/memory.h
index 7070430..29b2df9 100644
--- a/src/util/memory.h
+++ b/src/util/memory.h
@@ -34,6 +34,21 @@ void *try_realloc(void *ptr, size_t size);
/**
* @brief
+ * @param str
+ * @return
+ */
+char *try_strdup(const char *str);
+
+/**
+ * @brief
+ * @param mem
+ * @param len
+ * @return
+ */
+void *try_memdup(const void *mem, size_t len);
+
+/**
+ * @brief
* @param ptr
*/
void try_free(void *ptr);
@@ -46,7 +61,7 @@ void try_free(void *ptr);
* @param free_fun
*/
void set_mem_funcs(void *(*malloc_fun)(size_t), void *(*calloc_fun)(size_t),
- void *(*realloc_fun)(void *, size_t),
- void(*free_fun)(void *));
+ void *(*realloc_fun)(void *, size_t),
+ void (*free_fun)(void *));
#endif // ECGEN_MEMORY_H
diff --git a/src/util/random.c b/src/util/random.c
index bd7b89b..9af43cc 100644
--- a/src/util/random.c
+++ b/src/util/random.c
@@ -43,9 +43,7 @@ bool random_init(void) {
GEN random_prime(unsigned long bits) {
pari_sp ltop = avma;
- GEN range = gtovec0(gen_0, 2);
- gel(range, 1) = powis(gen_2, bits - 1);
- gel(range, 2) = powis(gen_2, bits);
+ GEN range = mkvec2(int2n(bits - 1), int2n(bits));
GEN p;
pari_sp btop = avma;
@@ -60,9 +58,6 @@ GEN random_prime(unsigned long bits) {
GEN random_int(unsigned long bits) {
pari_sp ltop = avma;
- GEN range = gtovec0(gen_0, 2);
- gel(range, 1) = powis(gen_2, bits - 1);
- gel(range, 2) = powis(gen_2, bits);
-
+ GEN range = mkvec2(int2n(bits - 1), int2n(bits));
return gerepilecopy(ltop, genrand(range));
}
diff --git a/test/Makefile b/test/Makefile
index 7ac8236..0aacdeb 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -10,7 +10,7 @@ test: ecgen econvert
unittest: unit ecgen econvert
unit:
- cd lib/criterion && mkdir -p build && cd build && cmake .. && cmake --build .
+ cd lib/criterion && mkdir -p build && cd build && cmake .. >/dev/null && cmake --build . >/dev/null
+$(MAKE) -C src all
ecgen:
diff --git a/test/ecgen.sh b/test/ecgen.sh
index 5ec9ccd..76b1bd1 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -97,7 +97,7 @@ function cli() {
assert_raises "${ecgen} --format=something" 1
assert_raises "${ecgen} --koblitz=2" 1
assert_raises "${ecgen} --points=something" 1
- assert_raises "${ecgen} --seed=some" 1
+ assert_raises "${ecgen} --seed=some" 64
assert_raises "${ecgen} 1 2 3" 64
assert_raises "${ecgen} --fp --f2m 1" 1
}
diff --git a/test/src/exhaustive/test_ansi.c b/test/src/exhaustive/test_ansi.c
new file mode 100644
index 0000000..4217a15
--- /dev/null
+++ b/test/src/exhaustive/test_ansi.c
@@ -0,0 +1,286 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+
+#include <criterion/criterion.h>
+#include <criterion/parameterized.h>
+#include "misc/types.h"
+#include "math/poly.h"
+#include "exhaustive/ansi.h"
+#include "gen/seed.h"
+#include "gen/field.h"
+#include "test/default.h"
+#include "test/memory.h"
+#include "test/input.h"
+#include "test/output.h"
+#include "util/bits.h"
+#include "util/memory.h"
+
+void ansi_suite_setup(void) {
+ default_setup();
+ input_setup();
+ output_setup();
+}
+
+void ansi_suite_teardown(void) {
+ default_teardown();
+ input_teardown();
+ output_teardown();
+}
+
+TestSuite(ansi, .init = ansi_suite_setup, .fini = ansi_suite_teardown);
+
+Test(ansi, test_seed_random) {
+ curve_t curve = {};
+ config_t cfg = {.bits = 256};
+ int ret = ansi_gen_seed_random(&curve, &cfg, NULL);
+
+ cr_assert_eq(ret, 1, );
+ cr_assert_not_null(curve.seed, );
+
+ seed_free(&curve.seed);
+}
+
+Test(ansi, test_seed_argument) {
+ curve_t curve = {};
+ char *seed = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
+ config_t cfg = {.seed = seed, .bits = 256};
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+
+ cr_assert_eq(ret, 1, );
+ cr_assert_not_null(curve.seed, );
+ char *hex = bits_to_hex(curve.seed->seed);
+ cr_assert_str_eq(hex, seed, );
+
+ try_free(hex);
+ seed_free(&curve.seed);
+}
+
+Test(ansi, test_seed_argument_hex) {
+ curve_t curve = {};
+ char *seed = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd";
+ config_t cfg = {.seed = seed, .bits = 256};
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+
+ cr_assert_eq(ret, 1, );
+ cr_assert_not_null(curve.seed, );
+ char *hex = bits_to_hex(curve.seed->seed);
+ cr_assert_str_eq(hex, seed + 2, );
+
+ try_free(hex);
+ seed_free(&curve.seed);
+}
+
+Test(ansi, test_seed_input) {
+ curve_t curve = {};
+ char *seed = "abcdefabcdefabcdefabcdefabcdefabcdefabcd";
+ config_t cfg = {.bits = 256};
+ fprintf(write_in, "%s\n", seed);
+ int ret = ansi_gen_seed_input(&curve, &cfg, NULL);
+
+ cr_assert_eq(ret, 1, );
+ cr_assert_not_null(curve.seed, );
+ char *hex = bits_to_hex(curve.seed->seed);
+ cr_assert_str_eq(hex, seed, );
+
+ try_free(hex);
+ seed_free(&curve.seed);
+}
+
+Test(ansi, test_seed_input_short) {
+ curve_t curve = {};
+ char *seed = "abcdef";
+ config_t cfg = {};
+ fprintf(write_in, "%s\n", seed);
+ int ret = ansi_gen_seed_input(&curve, &cfg, NULL);
+
+ cr_assert_eq(ret, 0, );
+}
+
+struct prime_params {
+ size_t bits;
+ char *p;
+ char *seed;
+ char *r;
+ char *a;
+ char *b;
+};
+
+void prime_params_cleanup(struct criterion_test_params *ctp) {
+ struct prime_params *params = (struct prime_params *)ctp->params;
+ cr_free(params->p);
+ cr_free(params->seed);
+ cr_free(params->r);
+ cr_free(params->a);
+ cr_free(params->b);
+}
+
+ParameterizedTestParameters(ansi, test_seed_prime_examples) {
+ static struct prime_params params[7] = {};
+ // Taken from ANSI X9.62 J.5.1 - J.5.3; p. 115 - 117
+ params[0].bits = 192;
+ params[0].p = cr_strdup("fffffffffffffffffffffffffffffffeffffffffffffffff");
+ params[0].seed = cr_strdup("3045AE6FC8422F64ED579528D38120EAE12196D5");
+ params[0].r = cr_strdup("3099D2BBBFCB2538542DCD5FB078B6EF5F3D6FE2C745DE65");
+ params[0].a = cr_strdup("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
+ params[0].b = cr_strdup("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1");
+ params[1].bits = 192;
+ params[1].p = cr_strdup("fffffffffffffffffffffffffffffffeffffffffffffffff");
+ params[1].seed = cr_strdup("31A92EE2029FD10D901B113E990710F0D21AC6B6");
+ params[1].r = cr_strdup("15038D1D2E1CAFEE0299F3011C1DC75B3C2A86E135DB1E6B");
+ params[1].a = cr_strdup("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
+ params[1].b = cr_strdup("CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953");
+ params[2].bits = 192;
+ params[2].p = cr_strdup("fffffffffffffffffffffffffffffffeffffffffffffffff");
+ params[2].seed = cr_strdup("C469684435DEB378C4B65CA9591E2A5763059A2E");
+ params[2].r = cr_strdup("25191F95024D839546D9A3375639A9967D52F1373BC4EE0B");
+ params[2].a = cr_strdup("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC");
+ params[2].b = cr_strdup("22123DC2395A05CAA7423DAECCC94760A7D462256BD56916");
+ params[3].bits = 239;
+ params[3].p = cr_strdup("7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff");
+ params[3].seed = cr_strdup("E43BB460F0B80CC0C0B075798E948060F8321B7D");
+ params[3].r = cr_strdup("28B85EC1ECC19EFE769EB741A6D1BA29476AA5A8F2610957D6EFE78D3783");
+ params[3].a = cr_strdup("7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC");
+ params[3].b = cr_strdup("6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A");
+ params[4].bits = 239;
+ params[4].p = cr_strdup("7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff");
+ params[4].seed = cr_strdup("E8B4011604095303CA3B8099982BE09FCB9AE616");
+ params[4].r = cr_strdup("1DF491E44E7CCAF4D1EAD8A6B90DAE09E0D33F2C6CFE7A6BA76E86713D52");
+ params[4].a = cr_strdup("7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC");
+ params[4].b = cr_strdup("617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C");
+ params[5].bits = 239;
+ params[5].p = cr_strdup("7fffffffffffffffffffffff7fffffffffff8000000000007fffffffffff");
+ params[5].seed = cr_strdup("7D7374168FFE3471B60A857686A19475D3BFA2FF");
+ params[5].r = cr_strdup("3A4F9DC9A6CEFD5F9D1193B9C9968C202430003C2819C2E498618DC58330");
+ params[5].a = cr_strdup("7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC");
+ params[5].b = cr_strdup("255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E");
+ params[6].bits = 256;
+ params[6].p = cr_strdup("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff");
+ params[6].seed = cr_strdup("C49D360886E704936A6678E1139D26B7819F7E90");
+ params[6].r = cr_strdup("7EFBA1662985BE9403CB055C75D4F7E0CE8D84A9C5114ABCAF3177680104FA0D");
+ params[6].a = cr_strdup("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");
+ params[6].b = cr_strdup("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");
+
+ 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_seed_prime_examples) {
+ config_t cfg = {};
+ cfg.bits = param->bits;
+ cfg.field = FIELD_PRIME;
+ cfg.seed = param->seed;
+ curve_t curve = {};
+ bits_t *p = bits_from_hex(param->p);
+ curve.field = bits_to_i(p);
+
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ cr_assert_eq(ret, 1,);
+
+ ret = ansi_gen_equation(&curve, &cfg, NULL);
+ cr_assert_eq(ret, 1,);
+ GEN expected_r = bits_to_i(bits_from_hex(param->r));
+ cr_assert(gequal(curve.seed->ansi.r, expected_r),);
+
+ bits_free(&p);
+ seed_free(&curve.seed);
+}
+
+struct binary_params {
+ size_t bits;
+ polynomial_t field;
+ char *seed;
+ char *a;
+ char *b;
+};
+
+void binary_params_cleanup(struct criterion_test_params *ctp) {
+ struct binary_params *params = (struct binary_params *)ctp->params;
+ cr_free(params->seed);
+ cr_free(params->a);
+ cr_free(params->b);
+}
+
+ParameterizedTestParameters(ansi, test_seed_binary_examples) {
+ static struct binary_params params[10] = {};
+ // Taken from ANSI X9.62 J.4.1, J.4.3, J.4.5 and J.4.8; p. 107 - 113
+ polynomial_t p163 = {163, 9, 3, 2};
+ params[0].bits = 163;
+ params[0].field = p163;
+ params[0].seed = cr_strdup("D2C0FB15760860DEF1EEF4D696E6768756151754");
+ params[0].a = cr_strdup("072546B5435234A422E0789675F432C89435DE5242");
+ params[0].b = cr_strdup("00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9");
+ params[1].bits = 163,
+ params[1].field = p163;
+ params[1].seed = cr_strdup("53814C050D44D696E67687561517580CA4E29FFD");
+ params[1].a = cr_strdup("0108B39E77C4B108BED981ED0E890E117C511CF072");
+ params[1].b = cr_strdup("0667ACEB38AF4E488C407433FFAE4F1C811638DF20");
+ params[2].bits = 163;
+ params[2].field = p163;
+ params[2].seed = cr_strdup("50CBF1D95CA94D696E676875615175F16A36A3B8");
+ params[2].a = cr_strdup("07A526C63D3E25A256A007699F5447E32AE456B50E");
+ params[2].b = cr_strdup("03F7061798EB99E238FD6F1BF95B48FEEB4854252B");
+ polynomial_t p191 = {191, 10};
+ params[3].bits = 191;
+ params[3].field = p191;
+ params[3].seed = cr_strdup("4E13CA542744D696E67687561517552F279A8C84");
+ params[3].a = cr_strdup("2866537B676752636A68F56554E12640276B649EF7526267");
+ params[3].b = cr_strdup("2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC");
+ params[4].bits = 191;
+ params[4].field = p191;
+ params[4].seed = cr_strdup("0871EF2FEF24D696E6768756151758BEE0D95C15");
+ params[4].a = cr_strdup("401028774D7777C7B7666D1366EA432071274F89FF01E718");
+ params[4].b = cr_strdup("0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01");
+ params[5].bits = 191;
+ params[5].field = p191;
+ params[5].seed = cr_strdup("E053512DC684D696E676875615175067AE786D1F");
+ params[5].a = cr_strdup("6C01074756099122221056911C77D77E77A777E7E7E77FCB");
+ params[5].b = cr_strdup("71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8");
+ polynomial_t p239 = {239, 37};
+ params[6].bits = 239;
+ params[6].field = p239;
+ params[6].seed = cr_strdup("D34B9A4D696E676875615175CA71B920BFEFB05D");
+ params[6].a = cr_strdup("32010857077C5431123A46B808906756F543423E8D27877578125778AC76");
+ params[6].b = cr_strdup("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16");
+ params[7].bits = 239;
+ params[7].field = p239;
+ params[7].seed = cr_strdup("2AA6982FDFA4D696E676875615175D266727277D");
+ params[7].a = cr_strdup("4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F");
+ params[7].b = cr_strdup("5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B");
+ params[8].bits = 239;
+ params[8].field = p239;
+ params[8].seed = cr_strdup("9E076F4D696E676875615175E11E9FDD77F92041");
+ params[8].a = cr_strdup("01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F");
+ params[8].b = cr_strdup("6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40");
+ polynomial_t p359 = {359, 69};
+ params[9].bits = 359;
+ params[9].field = p359;
+ params[9].seed = cr_strdup("2B354920B724D696E67687561517585BA1332DC6");
+ params[9].a = cr_strdup("5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557");
+ params[9].b = cr_strdup("2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988");
+
+ size_t nb_params = sizeof(params) / sizeof(struct binary_params);
+ return cr_make_param_array(struct binary_params, params, nb_params, binary_params_cleanup);
+}
+ParameterizedTest(struct binary_params *param, ansi, test_seed_binary_examples) {
+ config_t cfg = {};
+ cfg.bits = param->bits;
+ cfg.field = FIELD_BINARY;
+ cfg.seed = param->seed;
+ curve_t curve = {};
+ curve.field = poly_gen(&param->field);
+
+ GEN expected_b = bits_to_i(bits_from_hex(param->b));
+ bits_t *b = bits_from_i(expected_b);
+
+ int ret = ansi_gen_seed_argument(&curve, &cfg, NULL);
+ cr_assert_eq(ret, 1,);
+
+ ret = ansi_gen_equation(&curve, &cfg, NULL);
+ cr_assert_eq(ret, 1,);
+ GEN curve_b = field_elementi(curve.b);
+ cr_assert(gequal(curve_b, expected_b),);
+
+ bits_free(&b);
+ seed_free(&curve.seed);
+} \ No newline at end of file
diff --git a/test/src/gen/test_point.c b/test/src/gen/test_point.c
index 48872be..d77f83d 100644
--- a/test/src/gen/test_point.c
+++ b/test/src/gen/test_point.c
@@ -5,7 +5,7 @@
#include <criterion/criterion.h>
#include "gen/point.h"
-#include "test/utils.h"
+#include "test/default.h"
TestSuite(point, .init = default_setup, .fini = default_teardown);
diff --git a/test/src/io/test_cli.c b/test/src/io/test_cli.c
index c90bbfa..e5077ef 100644
--- a/test/src/io/test_cli.c
+++ b/test/src/io/test_cli.c
@@ -3,26 +3,25 @@
* Copyright (C) 2017 J08nY
*/
-#include "test/utils.h"
-#include "io/cli.h"
-#include "io/config.h"
#include <criterion/criterion.h>
#include <unistd.h>
+#include "io/cli.h"
+#include "misc/config.h"
+#include "test/default.h"
static struct argp test_argp = {cli_options, cli_parse, cli_args_doc,
- cli_doc, 0, cli_filter};
+ cli_doc, 0, cli_filter};
TestSuite(cli, .init = default_setup, .fini = default_teardown);
-
Test(cli, test_memory) {
int argc = 4;
char *argv[] = {"ecgen", "--memory=2k", "--fp", "1"};
config_t cfg;
memset(&cfg, 0, sizeof(cfg));
int ret = argp_parse(&test_argp, argc, argv, 0, 0, &cfg);
- cr_assert_eq(ret, 0,);
- cr_assert_eq(cfg.memory, 2000,);
+ cr_assert_eq(ret, 0, );
+ cr_assert_eq(cfg.memory, 2000, );
}
Test(cli, test_thread_memory) {
@@ -31,8 +30,8 @@ Test(cli, test_thread_memory) {
config_t cfg;
memset(&cfg, 0, sizeof(cfg));
int ret = argp_parse(&test_argp, argc, argv, 0, 0, &cfg);
- cr_assert_eq(ret, 0,);
- cr_assert_eq(cfg.thread_memory, 2000,);
+ cr_assert_eq(ret, 0, );
+ cr_assert_eq(cfg.thread_memory, 2000, );
}
Test(cli, test_threads) {
@@ -41,8 +40,8 @@ Test(cli, test_threads) {
config_t cfg;
memset(&cfg, 0, sizeof(cfg));
int ret = argp_parse(&test_argp, argc, argv, 0, 0, &cfg);
- cr_assert_eq(ret, 0,);
- cr_assert_eq(cfg.threads, 2,);
+ cr_assert_eq(ret, 0, );
+ cr_assert_eq(cfg.threads, 2, );
}
Test(cli, test_auto_threads) {
@@ -51,6 +50,6 @@ Test(cli, test_auto_threads) {
config_t cfg;
memset(&cfg, 0, sizeof(cfg));
int ret = argp_parse(&test_argp, argc, argv, 0, 0, &cfg);
- cr_assert_eq(ret, 0,);
- cr_assert_eq(cfg.threads, sysconf(_SC_NPROCESSORS_ONLN),);
+ cr_assert_eq(ret, 0, );
+ cr_assert_eq(cfg.threads, sysconf(_SC_NPROCESSORS_ONLN), );
} \ No newline at end of file
diff --git a/test/src/io/test_input.c b/test/src/io/test_input.c
index de4ac0f..d32d71c 100644
--- a/test/src/io/test_input.c
+++ b/test/src/io/test_input.c
@@ -3,92 +3,78 @@
* Copyright (C) 2017 J08nY
*/
-#include "test/utils.h"
-#include "io/input.h"
-#include "io/output.h"
#include <criterion/criterion.h>
+#include "io/input.h"
+#include "test/default.h"
+#include "test/input.h"
+#include "test/output.h"
-static FILE *write_in;
-
-void input_setup() {
+void input_suite_setup(void) {
default_setup();
- config_t cfg;
- memset(&cfg, 0, sizeof(cfg));
-
- cfg.output = "/dev/null";
- input_init(&cfg);
- output_init(&cfg);
-
- int in_fd[2];
- pipe(in_fd);
-
- write_in = fdopen(in_fd[1], "w");
- setlinebuf(write_in);
- in = fdopen(in_fd[0], "r");
- err = fopen("/dev/null", "w");
+ input_setup();
+ output_setup();
}
-void input_teardown() {
+void input_suite_teardown(void) {
default_teardown();
- input_quit();
- output_quit();
- fclose(write_in);
+ input_teardown();
+ output_teardown();
}
-TestSuite(input, .init = input_setup, .fini = input_teardown);
+TestSuite(input, .init = input_suite_setup, .fini = input_suite_teardown);
Test(input, test_prime) {
fprintf(write_in, "5\n");
GEN p = input_prime(NULL, 10);
- cr_assert(gequal(p, stoi(5)),);
+ cr_assert(gequal(p, stoi(5)), );
}
Test(input, test_prime_nan) {
fprintf(write_in, "....\n");
GEN p = input_prime(NULL, 10);
- cr_assert(gequal(p, gen_m1),);
+ cr_assert(gequal(p, gen_m1), );
}
Test(input, test_prime_nonprime) {
fprintf(write_in, "6\n");
GEN p = input_prime(NULL, 10);
- cr_assert(gequal(p, gen_m1),);
+ cr_assert(gequal(p, gen_m1), );
}
Test(input, test_prime_newline) {
fprintf(write_in, "\n");
GEN p = input_prime(NULL, 10);
- cr_assert(gequal(p, gen_m1),);
+ cr_assert(gequal(p, gen_m1), );
}
Test(input, test_int) {
fprintf(write_in, "256\n");
GEN i = input_int(NULL, 10);
- cr_assert(gequal(i, stoi(256)),);
+ cr_assert(gequal(i, stoi(256)), );
}
Test(input, test_int_too_big) {
fprintf(write_in, "256\n");
GEN i = input_int(NULL, 4);
- cr_assert(gequal(i, gen_m1),);
+ cr_assert(gequal(i, gen_m1), );
}
Test(input, test_int_newline) {
fprintf(write_in, "\n");
GEN i = input_int(NULL, 4);
- cr_assert(gequal(i, gen_m1),);
+ cr_assert(gequal(i, gen_m1), );
}
Test(input, test_str) {
fprintf(write_in, "something\n");
GEN s = input_string(NULL);
GEN expected = strtoGENstr("something");
- cr_assert(gequal(s, expected),);
+ cr_assert(gequal(s, expected), );
}
Test(input, test_str_newline) {
fprintf(write_in, "\n");
GEN s = input_string(NULL);
GEN expected = strtoGENstr("");
- cr_assert(gequal(s, expected),);
+ cr_assert(gequal(s, expected), );
}
diff --git a/test/src/math/test_subgroups.c b/test/src/math/test_subgroups.c
index b9368d0..8a3c8da 100644
--- a/test/src/math/test_subgroups.c
+++ b/test/src/math/test_subgroups.c
@@ -5,7 +5,7 @@
#include <criterion/criterion.h>
#include "gen/point.h"
#include "math/subgroups.h"
-#include "test/utils.h"
+#include "test/default.h"
TestSuite(subgroups, .init = default_setup, .fini = default_teardown);
diff --git a/test/src/test/utils.c b/test/src/test/default.c
index a5de092..c695fea 100644
--- a/test/src/test/utils.c
+++ b/test/src/test/default.c
@@ -2,17 +2,15 @@
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
-#include "utils.h"
+#include "default.h"
#include <criterion/criterion.h>
#include <pari/pari.h>
-static void *cr_simple_calloc(size_t size) {
- return cr_calloc(1, size);
-}
+
void default_setup(void) {
pari_init(1000000, 1000000);
- //set_mem_funcs(cr_malloc, cr_simple_calloc, cr_realloc, cr_free);
+ // set_mem_funcs(cr_malloc, cr_simple_calloc, cr_realloc, cr_free);
}
void default_teardown(void) { pari_close(); } \ No newline at end of file
diff --git a/test/src/test/utils.h b/test/src/test/default.h
index 2780bd2..12ee4cb 100644
--- a/test/src/test/utils.h
+++ b/test/src/test/default.h
@@ -2,11 +2,11 @@
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
-#ifndef ECGEN_UTILS_H
-#define ECGEN_UTILS_H
+#ifndef ECGEN_TEST_DEFAULT_H
+#define ECGEN_TEST_DEFAULT_H
void default_setup(void);
void default_teardown(void);
-#endif //ECGEN_UTILS_H
+#endif // ECGEN_UTILS_H
diff --git a/test/src/test/input.c b/test/src/test/input.c
new file mode 100644
index 0000000..f171ca8
--- /dev/null
+++ b/test/src/test/input.c
@@ -0,0 +1,27 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#include "input.h"
+#include "io/input.h"
+
+FILE *write_in;
+
+void input_setup(void) {
+ config_t cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ input_init(&cfg);
+
+ int in_fd[2];
+ pipe(in_fd);
+
+ write_in = fdopen(in_fd[1], "w");
+ setlinebuf(write_in);
+ in = fdopen(in_fd[0], "r");
+ setlinebuf(in);
+}
+
+void input_teardown(void) {
+ input_quit();
+ fclose(write_in);
+} \ No newline at end of file
diff --git a/test/src/test/input.h b/test/src/test/input.h
new file mode 100644
index 0000000..5e57c01
--- /dev/null
+++ b/test/src/test/input.h
@@ -0,0 +1,16 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#ifndef ECGEN_TEST_INPUT_H
+#define ECGEN_TEST_INPUT_H
+
+#include <stdio.h>
+
+extern FILE *write_in;
+
+void input_setup(void);
+
+void input_teardown(void);
+
+#endif // ECGEN_TEST_INPUT_H
diff --git a/test/src/test/memory.c b/test/src/test/memory.c
new file mode 100644
index 0000000..38c75c2
--- /dev/null
+++ b/test/src/test/memory.c
@@ -0,0 +1,17 @@
+
+#include <string.h>
+#include <criterion/alloc.h>
+#include "memory.h"
+
+char *cr_strdup(const char *str) {
+ size_t len = strlen(str);
+ return cr_memdup(str, len + 1);
+}
+
+void *cr_memdup(const void *str, size_t len) {
+ void *result = cr_malloc(len);
+ memcpy(result, str, len);
+ return result;
+}
+
+void *cr_simple_calloc(size_t size) { return cr_calloc(1, size); } \ No newline at end of file
diff --git a/test/src/test/memory.h b/test/src/test/memory.h
new file mode 100644
index 0000000..d97e3cc
--- /dev/null
+++ b/test/src/test/memory.h
@@ -0,0 +1,13 @@
+
+#ifndef ECGEN_TEST_MEMORY_H
+#define ECGEN_TEST_MEMORY_H
+
+#include <stddef.h>
+
+char *cr_strdup(const char *str);
+
+void *cr_memdup(const void *str, size_t len);
+
+void *cr_simple_calloc(size_t size);
+
+#endif //ECGEN_TEST_MEMORY_H
diff --git a/test/src/test/output.c b/test/src/test/output.c
new file mode 100644
index 0000000..66c5809
--- /dev/null
+++ b/test/src/test/output.c
@@ -0,0 +1,49 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#include "output.h"
+#include "misc/types.h"
+#include "io/output.h"
+
+FILE *read_out = NULL;
+FILE *read_err = NULL;
+FILE *read_verbose = NULL;
+
+static void setup_stream(FILE **original_out, FILE **redirected_out) {
+ int fd[2];
+ pipe(fd);
+
+ *redirected_out = fdopen(fd[0], "r");
+ setlinebuf(*redirected_out);
+ *original_out = fdopen(fd[1], "w");
+ setlinebuf(*original_out);
+}
+
+void output_setup(void) {
+ config_t cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ output_init(&cfg);
+
+ int in_fd[2];
+ pipe(in_fd);
+
+ setup_stream(&out, &read_out);
+ setup_stream(&err, &read_err);
+ setup_stream(&verbose, &read_verbose);
+}
+
+void output_teardown(void) {
+ if (read_out) {
+ fclose(out);
+ fclose(read_out);
+ }
+ if (read_err) {
+ fclose(err);
+ fclose(read_err);
+ }
+ if (read_verbose) {
+ fclose(verbose);
+ fclose(read_verbose);
+ }
+}
diff --git a/test/src/test/output.h b/test/src/test/output.h
new file mode 100644
index 0000000..733cb5c
--- /dev/null
+++ b/test/src/test/output.h
@@ -0,0 +1,18 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#ifndef ECGEN_TEST_OUTPUT_H
+#define ECGEN_TEST_OUTPUT_H
+
+#include <stdio.h>
+
+extern FILE *read_out;
+extern FILE *read_err;
+extern FILE *read_verbose;
+
+void output_setup(void);
+
+void output_teardown(void);
+
+#endif // ECGEN_TEST_OUTPUT_H
diff --git a/test/src/util/test_bits.c b/test/src/util/test_bits.c
new file mode 100644
index 0000000..372541a
--- /dev/null
+++ b/test/src/util/test_bits.c
@@ -0,0 +1,486 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+
+#include <criterion/criterion.h>
+#include <criterion/parameterized.h>
+#include <misc/types.h>
+#include "test/default.h"
+#include "test/memory.h"
+#include "util/bits.h"
+#include "util/memory.h"
+
+TestSuite(bits, .init = default_setup, .fini = default_teardown);
+
+Test(bits, test_bits_new) {
+ bits_t *bits = bits_new(10);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 10, );
+ cr_assert_eq(bits->allocated, 2, );
+ cr_assert_eq(bits->bits[0], 0, );
+ cr_assert_eq(bits->bits[1], 0, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_copy) {
+ bits_t *bits = bits_new(10);
+ bits->bits[0] = 0b10101010;
+ bits->bits[1] = 0b11000000;
+
+ bits_t *other_bits = bits_copy(bits);
+ cr_assert_not_null(other_bits, );
+ cr_assert_eq(other_bits->allocated, bits->allocated, );
+ cr_assert_eq(other_bits->bitlen, bits->bitlen, );
+ cr_assert_eq(other_bits->bits[0], bits->bits[0], );
+ cr_assert_eq(other_bits->bits[1], bits->bits[1], );
+ bits_free(&bits);
+ bits_free(&other_bits);
+}
+
+Test(bits, test_bits_from_i) {
+ GEN i = int2n(5);
+
+ bits_t *bits = bits_from_i(i);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 6, );
+ cr_assert_eq(bits->allocated, 1, );
+ cr_assert_eq(bits->bits[0], 0b10000000, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_from_hex) {
+ char *hex = "0ab";
+
+ bits_t *bits = bits_from_hex(hex);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 12, );
+ cr_assert_eq(bits->allocated, 2, );
+ cr_assert_eq(bits->bits[0], 0x0a, );
+ cr_assert_eq(bits->bits[1], 0xb0, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_from_bin) {
+ char *bin = "000010101101";
+
+ bits_t *bits = bits_from_bin(bin);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 12, );
+ cr_assert_eq(bits->allocated, 2, );
+ cr_assert_eq(bits->bits[0], 0b00001010, );
+ cr_assert_eq(bits->bits[1], 0b11010000, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_from_raw) {
+ unsigned char *raw = (unsigned char *)"\x0a\xb0";
+
+ bits_t *bits = bits_from_raw(raw, 16);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 16, );
+ cr_assert_eq(bits->allocated, 2, );
+ cr_assert_eq(bits->bits[0], 0x0a, );
+ cr_assert_eq(bits->bits[1], 0xb0, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_from_bitvec) {
+ GEN bitvec = binary_zv(int2n(5));
+
+ bits_t *bits = bits_from_bitvec(bitvec);
+ cr_assert_not_null(bits, );
+ cr_assert_eq(bits->bitlen, 6, );
+ cr_assert_eq(bits->allocated, 1, );
+ cr_assert_eq(bits->bits[0], 0b10000000, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_to_i) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ GEN i = bits_to_i(bits);
+ cr_assert_not_null(bits, );
+ cr_assert(gequal(i, int2n(5)), );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_to_hex) {
+ bits_t *bits = bits_new(12);
+ bits->bits[0] = 0xab;
+ bits->bits[1] = 0xc0;
+
+ char *hex = bits_to_hex(bits);
+ cr_assert_not_null(hex, );
+ cr_assert_str_eq(hex, "abc0", );
+ try_free(hex);
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_to_bin) {
+ bits_t *bits = bits_new(12);
+ bits->bits[0] = 0b10101010;
+ bits->bits[1] = 0b11110000;
+
+ char *bin = bits_to_bin(bits);
+ cr_assert_not_null(bin, );
+ cr_assert_str_eq(bin, "101010101111", );
+ try_free(bin);
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_to_raw) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ unsigned char *raw = bits_to_raw(bits);
+ size_t rawlen = bits_to_rawlen(bits);
+ cr_assert_not_null(raw, );
+ cr_assert_eq(rawlen, 1, );
+ cr_assert_eq(raw[0], 0b10000000, );
+ try_free(raw);
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_to_bitvec) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ GEN bitvec = bits_to_bitvec(bits);
+ cr_assert_not_null(bitvec, );
+ cr_assert(gequal(bitvec, binary_zv(int2n(5))), );
+}
+
+Test(bits, test_bits_concat) {
+ bits_t *one = bits_new(6);
+ one->bits[0] = 0b00000000;
+
+ bits_t *other = bits_new(8);
+ other->bits[0] = 0b11001100;
+
+ bits_t *cat = bits_concat(one, other, NULL);
+ cr_assert_not_null(cat, );
+ cr_assert_eq(cat->bitlen, 14, );
+ cr_assert_eq(cat->bits[0], 0b00000011, );
+ cr_assert_eq(cat->bits[1], 0b00110000, );
+
+ bits_free(&one);
+ bits_free(&other);
+ bits_free(&cat);
+}
+
+Test(bits, test_bits_or) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *other_bits = bits_new(10);
+ other_bits->bits[0] = 0b00000000;
+ other_bits->bits[1] = 0b11000000;
+
+ bits_t * or = bits_or(bits, other_bits);
+ cr_assert_not_null(or, );
+ cr_assert_eq(or->bitlen, 10, );
+ cr_assert_eq(or->bits[0], 0b00001000, );
+ cr_assert_eq(or->bits[1], 0b11000000, );
+ bits_free(&bits);
+ bits_free(&other_bits);
+ bits_free(& or);
+}
+
+Test(bits, test_bits_and) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *other_bits = bits_new(10);
+ other_bits->bits[0] = 0b00001000;
+ other_bits->bits[1] = 0b11000000;
+
+ bits_t *and = bits_and(bits, other_bits);
+ cr_assert_not_null(and, );
+ cr_assert_eq(and->bitlen, 10, );
+ cr_assert_eq(and->bits[0], 0b00001000, );
+ cr_assert_eq(and->bits[1], 0b00000000, );
+ bits_free(&bits);
+ bits_free(&other_bits);
+ bits_free(&and);
+}
+
+Test(bits, test_bits_notz) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_notz(bits);
+ cr_assert_eq(bits->bitlen, 6, );
+ cr_assert_eq(bits->bits[0], 0b01111100, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_not) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *not = bits_not(bits);
+ cr_assert_not_null(not, );
+ cr_assert_eq(not->bitlen, 6, );
+ cr_assert_eq(not->bits[0], 0b01111100, );
+ bits_free(&bits);
+ bits_free(&not);
+}
+
+Test(bits, test_bits_rotz) {
+ bits_t *bits = bits_new(10);
+ bits->bits[0] = 0b11111000;
+ bits->bits[1] = 0b00000000;
+
+ bits_rotz(bits);
+ cr_assert_eq(bits->bitlen, 10, );
+ cr_assert_eq(bits->bits[0], 0b00000111, );
+ cr_assert_eq(bits->bits[1], 0b11000000, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_rot) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *rot = bits_rot(bits);
+ cr_assert_not_null(rot, );
+ cr_assert_eq(rot->bitlen, 6, );
+ cr_assert_eq(rot->bits[0], 0b00000100, );
+ bits_free(&bits);
+ bits_free(&rot);
+
+ bits = bits_new(5);
+ bits->bits[0] = 0b10100000;
+
+ rot = bits_rot(bits);
+ cr_assert_not_null(rot, );
+ cr_assert_eq(rot->bitlen, 5, );
+ cr_assert_eq(rot->bits[0], 0b00101000, );
+ bits_free(&bits);
+ bits_free(&rot);
+}
+
+Test(bits, test_bits_shiftz) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10101000;
+
+ bits_shiftz(bits, -1);
+ cr_assert_eq(bits->bitlen, 6, );
+ cr_assert_eq(bits->bits[0], 0b01010100, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_shift) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_t *shift = bits_shift(bits, 2);
+ cr_assert_not_null(shift, );
+ cr_assert_eq(shift->bitlen, 8, );
+ cr_assert_eq(shift->bits[0], 0b00110000, );
+ bits_free(&bits);
+ bits_free(&shift);
+}
+
+Test(bits, test_bits_shiftrz) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_shiftrz(bits, 1);
+ cr_assert_eq(bits->bitlen, 8, );
+ cr_assert_eq(bits->bits[0], 0b10011001, );
+ bits->bits[0] = 0b11001100;
+
+ bits_shiftrz(bits, 9);
+ cr_assert_eq(bits->bitlen, 8, );
+ cr_assert_eq(bits->bits[0], 0b10011001, );
+ bits->bits[0] = 0b11001100;
+
+ bits_shiftrz(bits, -10);
+ cr_assert_eq(bits->bitlen, 8, );
+ cr_assert_eq(bits->bits[0], 0b00110011, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_shiftr) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_t *shift = bits_shiftr(bits, 1);
+ cr_assert_eq(shift->bitlen, 8, );
+ cr_assert_eq(shift->bits[0], 0b10011001, );
+ bits_free(&bits);
+ bits_free(&shift);
+}
+
+Test(bits, test_bits_shiftiz) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_shiftiz(bits, 2);
+ cr_assert_eq(bits->bitlen, 10, );
+ cr_assert_eq(bits->bits[0], 0b11001100, );
+ cr_assert_eq(bits->bits[1], 0b00000000, );
+
+ bits_shiftiz(bits, -2);
+ cr_assert_eq(bits->bitlen, 8, );
+ cr_assert_eq(bits->bits[0], 0b11001100, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_shitfi) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_t *shift = bits_shifti(bits, -4);
+ cr_assert_eq(shift->bitlen, 4, );
+ cr_assert_eq(shift->bits[0], 0b11000000, );
+ bits_free(&bits);
+ bits_free(&shift);
+}
+
+Test(bits, test_bits_lengthenz) {
+ bits_t *bits = bits_new(8);
+ bits->bits[0] = 0b11001100;
+
+ bits_lengthenz(bits, 4);
+ cr_assert_eq(bits->bitlen, 12, );
+ cr_assert_eq(bits->bits[0], 0b00001100, );
+ cr_assert_eq(bits->bits[1], 0b11000000, );
+
+ bits_lengthenz(bits, -4);
+ cr_assert_eq(bits->bitlen, 16, );
+ cr_assert_eq(bits->bits[0], 0b00001100, );
+ cr_assert_eq(bits->bits[1], 0b11000000, );
+
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_lengthen) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b11111100;
+
+ bits_t *longer = bits_lengthen(bits, 2);
+ cr_assert_not_null(longer, );
+ cr_assert_eq(longer->bitlen, 8, );
+ cr_assert_eq(longer->bits[0], 0b00111111, );
+ bits_free(&bits);
+ bits_free(&longer);
+}
+
+Test(bits, test_bits_shortenz) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10110100;
+
+ bits_shortenz(bits, 2);
+ cr_assert_eq(bits->bitlen, 4, );
+ cr_assert_eq(bits->bits[0], 0b11010000, );
+
+ bits_shortenz(bits, -2);
+ cr_assert_eq(bits->bitlen, 2, );
+ cr_assert_eq(bits->bits[0], 0b11000000, );
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_shorten) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10110100;
+
+ bits_t *shorter = bits_shorten(bits, 4);
+ cr_assert_not_null(shorter, );
+ cr_assert_eq(shorter->bitlen, 2, );
+ cr_assert_eq(shorter->bits[0], 0b01000000, );
+ bits_free(&bits);
+ bits_free(&shorter);
+}
+
+struct sha1_params {
+ char *data;
+ unsigned char *hashout;
+};
+
+void sha1_params_cleanup(struct criterion_test_params *ctp) {
+ struct sha1_params *params = (struct sha1_params *)ctp->params;
+ cr_free(params->data);
+ cr_free(params->hashout);
+}
+
+ParameterizedTestParameters(bits, test_bits_sha1) {
+ static struct sha1_params params[5] = {};
+ params[0].data = cr_strdup("The quick brown fox jumps over the lazy dog");
+ params[0].hashout = cr_memdup("\x2f\xd4\xe1\xc6\x7a\x2d\x28\xfc\xed\x84\x9e\xe1\xbb\x76\xe7\x39\x1b\x93\xeb\x12", 20);
+ params[1].data = cr_strdup("abc");
+ params[1].hashout = cr_memdup("\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c\x9c\xd0\xd8\x9d", 20);
+ params[2].data = cr_strdup("");
+ params[2].hashout = cr_memdup("\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", 20);
+ params[3].data = cr_strdup("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
+ params[3].hashout = cr_memdup("\x84\x98\x3e\x44\x1c\x3b\xd2\x6e\xba\xae\x4a\xa1\xf9\x51\x29\xe5\xe5\x46\x70\xf1", 20);
+ params[4].data = cr_strdup("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
+ params[4].hashout = cr_memdup("\xa4\x9b\x24\x46\xa0\x2c\x64\x5b\xf4\x19\xf9\x95\xb6\x70\x91\x25\x3a\x04\xa2\x59", 20);
+
+ size_t nb_params = sizeof(params) / sizeof(struct sha1_params);
+ return cr_make_param_array(struct sha1_params, params, nb_params, sha1_params_cleanup);
+}
+
+ParameterizedTest(struct sha1_params *param, bits, test_bits_sha1) {
+ bits_t *bits = bits_from_raw((unsigned char *)param->data, strlen(param->data) * 8);
+ unsigned char hashout[20] = {};
+ bits_sha1(bits, hashout);
+
+ for (size_t i = 0; i < 20; ++i) {
+ cr_assert_eq(hashout[i], param->hashout[i], );
+ }
+
+ bits_free(&bits);
+}
+
+Test(bits, test_bits_eq) {
+ bits_t *bits = bits_new(6);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *other_bits = bits_new(6);
+ other_bits->bits[0] = 0b10000000;
+
+ cr_assert(bits_eq(bits, other_bits), );
+
+ bits->bits[0] = 0b10010000;
+ other_bits->bits[0] = 0b10000000;
+
+ cr_assert_not(bits_eq(bits, other_bits), );
+
+ bits_free(&bits);
+ bits_free(&other_bits);
+}
+
+Test(bits, test_bits_eq_len) {
+ bits_t *bits = bits_new(5);
+ bits->bits[0] = 0b10000000;
+
+ bits_t *other_bits = bits_new(6);
+ other_bits->bits[0] = 0b10000000;
+ cr_assert_not(bits_eq(bits, other_bits), );
+ bits_free(&bits);
+ bits_free(&other_bits);
+}
+
+Test(bits, test_bits_eq_large) {
+ bits_t *bits = bits_new(10);
+ bits->bits[0] = 0b10000010;
+ bits->bits[1] = 0b11000000;
+
+ bits_t *other_bits = bits_new(10);
+ other_bits->bits[0] = 0b10000010;
+ other_bits->bits[1] = 0b11000000;
+
+ cr_assert(bits_eq(bits, other_bits), );
+
+ bits->bits[0] = 0b10000000;
+ other_bits->bits[0] = 0b00000010;
+
+ cr_assert_not(bits_eq(bits, other_bits), );
+
+ bits_free(&bits);
+ bits_free(&other_bits);
+}
diff --git a/test/src/util/test_random.c b/test/src/util/test_random.c
index 5e7f854..bb632a6 100644
--- a/test/src/util/test_random.c
+++ b/test/src/util/test_random.c
@@ -3,9 +3,9 @@
* Copyright (C) 2017 J08nY
*/
-#include "test/utils.h"
-#include "util/random.h"
#include <criterion/criterion.h>
+#include "test/default.h"
+#include "util/random.h"
void random_setup() {
default_setup();
@@ -17,18 +17,16 @@ TestSuite(random, .init = random_setup, .fini = default_teardown);
Test(random, test_random_prime) {
for (size_t i = 0; i < 100; ++i) {
GEN p = random_prime(10);
- cr_assert(isprime(p),);
- cr_assert_lt(gcmp(p, int2n(10)), 0,);
- cr_assert_gt(gcmp(p, int2n(9)), 0,);
+ cr_assert(isprime(p), );
+ cr_assert_leq(cmpii(p, int2n(10)), 0, );
+ cr_assert_geq(cmpii(p, int2n(9)), 0, );
}
}
Test(random, test_random_int) {
for (size_t i = 0; i < 100; ++i) {
GEN j = random_int(10);
- cr_assert_lt(gcmp(j, int2n(10)), 0,);
- cr_assert_gt(gcmp(j, int2n(9)), 0,);
+ cr_assert_leq(cmpii(j, int2n(10)), 0, );
+ cr_assert_geq(cmpii(j, int2n(9)), 0, );
}
}
-
-