aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exhaustive/anomalous.c10
-rw-r--r--src/io/cli.c2
-rw-r--r--src/io/config.h1
-rw-r--r--src/io/output.c132
-rw-r--r--src/math/curve.c35
-rw-r--r--src/math/curve.h12
-rwxr-xr-xtest/ecgen.sh12
-rw-r--r--test/econvert_format.csv1
-rw-r--r--test/econvert_format.json29
-rw-r--r--test/f2m_10_a.csv2
-rw-r--r--test/f2m_10_a.json41
-rw-r--r--test/fp_10_a.csv2
-rw-r--r--test/fp_10_a.json29
-rw-r--r--test/verify.gp0
14 files changed, 216 insertions, 92 deletions
diff --git a/src/exhaustive/anomalous.c b/src/exhaustive/anomalous.c
index 7838aa8..93adf7d 100644
--- a/src/exhaustive/anomalous.c
+++ b/src/exhaustive/anomalous.c
@@ -56,10 +56,12 @@ static GEN anomalous_prime(size_t i, unsigned long bits) {
GEN lower = divii(subii(int2n(bits - 1), last), D);
GEN upper = divii(subii(int2n(bits), last), D);
- GEN lower_bound = gceil(gdiv(
- gsub(gsqrt(addis(mulis(lower, 4), 1), BIGDEFAULTPREC*2), gen_1), gen_2));
- GEN upper_bound = gfloor(gdiv(
- gsub(gsqrt(addis(mulis(upper, 4), 1), BIGDEFAULTPREC*2), gen_1), gen_2));
+ GEN lower_bound = gceil(
+ gdiv(gsub(gsqrt(addis(mulis(lower, 4), 1), BIGDEFAULTPREC * 2), gen_1),
+ gen_2));
+ GEN upper_bound = gfloor(
+ gdiv(gsub(gsqrt(addis(mulis(upper, 4), 1), BIGDEFAULTPREC * 2), gen_1),
+ gen_2));
GEN range = gtovec0(gen_0, 2);
gel(range, 1) = lower_bound;
diff --git a/src/io/cli.c b/src/io/cli.c
index cc2f156..ae27d06 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -227,6 +227,8 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
}
cfg->bits = strtoul(arg, NULL, 10);
+ cfg->hex_digits =
+ 2 * (cfg->bits / 8 + (cfg->bits % 8 != 0 ? 1 : 0));
break;
case ARGP_KEY_END:
// validate all option states here.
diff --git a/src/io/config.h b/src/io/config.h
index 426661c..42a48be 100644
--- a/src/io/config.h
+++ b/src/io/config.h
@@ -53,6 +53,7 @@ typedef struct {
char *verbose_log;
unsigned long bits;
+ unsigned long hex_digits;
} config_t;
diff --git a/src/io/output.c b/src/io/output.c
index 6fe8802..749d008 100644
--- a/src/io/output.c
+++ b/src/io/output.c
@@ -5,7 +5,6 @@
#include "output.h"
#include <parson/parson.h>
-#include "math/curve.h"
#include "math/field.h"
FILE *out;
@@ -23,36 +22,99 @@ char *output_malloc(const char *what) {
char *output_scsv(curve_t *curve, const config_t *cfg) {
pari_sp ltop = avma;
- GEN vector = curve_params(curve);
+ char *params[OFFSET_END];
- long len = glength(vector);
- char *params[len];
- size_t lengths[len];
- size_t total = 0;
- for (long i = 0; i < len; ++i) {
- params[i] = pari_sprintf("%P#x", gel(vector, i + 1));
- lengths[i] = strlen(params[i]);
- total += lengths[i];
+ for (int i = 0; i < OFFSET_END; ++i) {
+ params[i] = NULL;
}
- char *result = (char *)malloc(total + len);
- if (!result) {
- perror("Couldn't malloc.");
- exit(1);
+ switch (cfg->field) {
+ case FIELD_PRIME:
+ params[OFFSET_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));
+ break;
+ }
+ }
+
+ if (curve->a)
+ params[OFFSET_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));
+
+ if (curve->generators) {
+ char *gens[curve->ngens];
+ size_t len = 0;
+ for (size_t i = 0; i < curve->ngens; ++i) {
+ point_t *generator = curve->generators[i];
+ 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);
+ len += strlen(gens[i]);
+ }
+ size_t lenn = sizeof(char) * (len + curve->ngens);
+ params[OFFSET_GENERATORS] = pari_malloc(lenn);
+ params[OFFSET_GENERATORS][0] = '\0';
+ for (size_t i = 0; i < curve->ngens; ++i) {
+ if (i > 0) strncat(params[OFFSET_GENERATORS], ",", lenn - 1);
+ strncat(params[OFFSET_GENERATORS], gens[i], lenn - 1);
+ pari_free(gens[i]);
+ }
}
- size_t offset = 0;
- for (long i = 0; i < len; ++i) {
- memcpy(result + offset, params[i], lengths[i]);
- free(params[i]);
+ if (curve->order)
+ params[OFFSET_ORDER] =
+ pari_sprintf("%P0#*x", cfg->hex_digits, curve->order);
- offset += lengths[i];
- if (i != len - 1) {
- result[offset] = ',';
- offset++;
+ if (curve->points) {
+ char *points[curve->npoints];
+ size_t len = 0;
+ for (size_t i = 0; i < curve->npoints; ++i) {
+ point_t *point = curve->points[i];
+ 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);
+ len += strlen(points[i]);
+ }
+ size_t lenn = sizeof(char) * (len + curve->npoints);
+ params[OFFSET_POINTS] = pari_malloc(lenn);
+ params[OFFSET_POINTS][0] = '\0';
+ for (size_t i = 0; i < curve->npoints; ++i) {
+ if (i > 0) strncat(params[OFFSET_POINTS], ",", lenn - 1);
+ strncat(params[OFFSET_POINTS], points[i], lenn - 1);
+ pari_free(points[i]);
+ }
+ }
+
+ size_t len = 0;
+ size_t count = 0;
+ for (int i = OFFSET_FIELD; i < OFFSET_END; ++i) {
+ if (params[i]) {
+ len += strlen(params[i]);
+ ++count;
+ }
+ }
+ size_t lenn = sizeof(char) * (len + count);
+ char *result = pari_malloc(lenn);
+ result[0] = '\0';
+
+ for (int i = OFFSET_FIELD; i < OFFSET_END; ++i) {
+ if (params[i]) {
+ if (i > OFFSET_FIELD) strncat(result, ",", lenn - 1);
+ strncat(result, params[i], lenn - 1);
+ pari_free(params[i]);
}
}
- memset(result + offset, 0, 1);
avma = ltop;
return result;
@@ -72,7 +134,7 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
switch (cfg->field) {
case FIELD_PRIME: {
- char *prime = pari_sprintf("%P#x", curve->field);
+ char *prime = pari_sprintf("%P0#*x", cfg->hex_digits, curve->field);
json_object_dotset_string(root_object, "field.p", prime);
pari_free(prime);
break;
@@ -98,13 +160,13 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
exit(1);
}
- char *a = pari_sprintf("%P#x", field_elementi(curve->a));
+ char *a = pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->a));
json_object_set_string(root_object, "a", a);
pari_free(a);
- char *b = pari_sprintf("%P#x", field_elementi(curve->b));
+ char *b = pari_sprintf("%P0#*x", cfg->hex_digits, field_elementi(curve->b));
json_object_set_string(root_object, "b", b);
pari_free(b);
- char *order = pari_sprintf("%P#x", curve->order);
+ char *order = pari_sprintf("%P0#*x", cfg->hex_digits, curve->order);
json_object_set_string(root_object, "order", order);
pari_free(order);
if (curve->ngens) {
@@ -116,11 +178,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(
- "%P#x", 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(
- "%P#x", 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);
@@ -147,12 +211,14 @@ static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
JSON_Value *point_value = json_value_init_object();
JSON_Object *point_object = json_value_get_object(point_value);
- char *x = pari_sprintf(
- "%P#x", field_elementi(gel(curve->points[i]->point, 1)));
+ char *x =
+ 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(
- "%P#x", field_elementi(gel(curve->points[i]->point, 2)));
+ char *y =
+ 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);
diff --git a/src/math/curve.c b/src/math/curve.c
index 00e65f0..633cf27 100644
--- a/src/math/curve.c
+++ b/src/math/curve.c
@@ -168,38 +168,3 @@ int curve_unroll(curve_t *curve, const config_t *cfg, pari_sp from,
}
return -1;
}
-
-GEN curve_params(const curve_t *curve) {
- pari_sp ltop = avma;
-
- GEN result = field_params(curve->field);
- if (curve->a) result = gconcat(result, field_elementi(curve->a));
- if (curve->b) result = gconcat(result, field_elementi(curve->b));
- if (curve->generators) {
- for (size_t i = 0; i < curve->ngens; ++i) {
- GEN x = field_elementi(gel(curve->generators[i]->point, 1));
- GEN y = field_elementi(gel(curve->generators[i]->point, 2));
- result = gconcat(result, x);
- result = gconcat(result, y);
- result = gconcat(result, curve->generators[i]->order);
- if (curve->generators[i]->cofactor) {
- result = gconcat(result, curve->generators[i]->cofactor);
- }
- }
- }
- if (curve->order) result = gconcat(result, gtovec(curve->order));
- if (curve->points) {
- for (size_t i = 0; i < curve->npoints; ++i) {
- GEN x = field_elementi(gel(curve->points[i]->point, 1));
- GEN y = field_elementi(gel(curve->points[i]->point, 2));
- result = gconcat(result, x);
- result = gconcat(result, y);
- result = gconcat(result, curve->points[i]->order);
- if (curve->points[i]->cofactor) {
- result = gconcat(result, curve->points[i]->cofactor);
- }
- }
- }
-
- return gerepilecopy(ltop, result);
-}
diff --git a/src/math/curve.h b/src/math/curve.h
index c250040..c8df723 100644
--- a/src/math/curve.h
+++ b/src/math/curve.h
@@ -59,18 +59,6 @@ int curve_seed(curve_t *curve, const config_t *cfg, arg_t *args);
int curve_unroll(curve_t *curve, const config_t *cfg, pari_sp from, pari_sp to);
/**
- * Serializes curve parameters into a t_VEC:
- * - prime field:
- * p,a,b,order,(point.x, point.y, point.order)*
- * - binary field:
- * e1,e2,e3,a,b,order,(point.x, point.y, point.order)*
- *
- * @param curve to serialize
- * @return a t_VEC of curve parameters
- */
-GEN curve_params(const curve_t *curve);
-
-/**
* Allocates and zeros out a new curve_t object.
* @return new curve
*/
diff --git a/test/ecgen.sh b/test/ecgen.sh
index 6e018d1..6e1dd0a 100755
--- a/test/ecgen.sh
+++ b/test/ecgen.sh
@@ -20,18 +20,18 @@ function json() {
fp=$(${ecgen} --fp -tjson --input=fp_10_a.csv.in 10)
f2m=$(${ecgen} --f2m -tjson --input=f2m_10_a.csv.in 10)
assert_raises "${JSON}" 0 "${fp}"
- assert_matches "${JSON} -x field\\\",\\\"p" "0xb" "${fp}"
- assert_matches "${JSON} -x \\\"a\\\"" "0x1" "${fp}"
- assert_matches "${JSON} -x \\\"b\\\"" "0x2" "${fp}"
- assert_matches "${JSON} -x \\\"order\\\"" "0x10" "${fp}"
+ assert_matches "${JSON} -x field\\\",\\\"p" "0x000b" "${fp}"
+ assert_matches "${JSON} -x \\\"a\\\"" "0x0001" "${fp}"
+ assert_matches "${JSON} -x \\\"b\\\"" "0x0002" "${fp}"
+ assert_matches "${JSON} -x \\\"order\\\"" "0x0010" "${fp}"
assert_raises "${JSON}" 0 "${f2m}"
assert_matches "${JSON} -x field\\\",\\\"m" "0xa" "${f2m}"
assert_matches "${JSON} -x field\\\",\\\"e1" "0x3" "${f2m}"
assert_matches "${JSON} -x field\\\",\\\"e2" "0x0" "${f2m}"
assert_matches "${JSON} -x field\\\",\\\"e3" "0x0" "${f2m}"
- assert_matches "${JSON} -x \\\"a\\\"" "0x2ed" "${f2m}"
- assert_matches "${JSON} -x \\\"b\\\"" "0xb7" "${f2m}"
+ assert_matches "${JSON} -x \\\"a\\\"" "0x02ed" "${f2m}"
+ assert_matches "${JSON} -x \\\"b\\\"" "0x00b7" "${f2m}"
assert_matches "${JSON} -x \\\"order\\\"" "0x3de" "${f2m}"
}
diff --git a/test/econvert_format.csv b/test/econvert_format.csv
new file mode 100644
index 0000000..358d807
--- /dev/null
+++ b/test/econvert_format.csv
@@ -0,0 +1 @@
+0xb,0x1,0x2,0x2,0xa,0x8,0x2,0x7,0x0,0x2,0x8,0x10,0x7,0x0,0x2 \ No newline at end of file
diff --git a/test/econvert_format.json b/test/econvert_format.json
new file mode 100644
index 0000000..8bb9bc2
--- /dev/null
+++ b/test/econvert_format.json
@@ -0,0 +1,29 @@
+{
+ "field": {
+ "p": "0xb"
+ },
+ "a": "0x1",
+ "b": "0x2",
+ "order": "0x10",
+ "generators": [
+ {
+ "x": "0x2",
+ "y": "0xa",
+ "order": "0x8",
+ "cofactor": "0x2"
+ },
+ {
+ "x": "0x7",
+ "y": "0x0",
+ "order": "0x2",
+ "cofactor": "0x8"
+ }
+ ],
+ "points": [
+ {
+ "x": "0x7",
+ "y": "0x0",
+ "order": "0x2"
+ }
+ ]
+}
diff --git a/test/f2m_10_a.csv b/test/f2m_10_a.csv
index 2ba807e..913fe0f 100644
--- a/test/f2m_10_a.csv
+++ b/test/f2m_10_a.csv
@@ -1 +1 @@
-0xa,0x3,0x0,0x0,0x2ed,0xb7,0x[0-9a-f]{1,3},0x[0-9a-f]{1,3},0x3de,0x1,0x3de,0x0,0x0,0x2,0x2fb,0x(285|7e),0x3,0x[0-9a-f]{1,2},0x[0-9a-f]{1,3},0x[0-9a-f]{1,3},0x[0-9a-f]{1,3},0x[0-9a-f]{1,3},0xb
+0xa,0x3,0x0,0x0,0x02ed,0x00b7,0x03de,0x[0-9a-f]{4},0x[0-9a-f]{4},0x3de,0x1,0x0000,0x0000,0x2,0x02fb,0x(0285|007e),0x3,0x[0-9a-f]{4},0x[0-9a-f]{4},0x[0-9a-f]{1,3},0x[0-9a-f]{4},0x[0-9a-f]{4},0xb
diff --git a/test/f2m_10_a.json b/test/f2m_10_a.json
new file mode 100644
index 0000000..e04fbd8
--- /dev/null
+++ b/test/f2m_10_a.json
@@ -0,0 +1,41 @@
+{
+ "field": {
+ "m": "0xa",
+ "e1": "0x3",
+ "e2": "0x0",
+ "e3": "0x0"
+ },
+ "a": "0x2ed",
+ "b": "0xb7",
+ "order": "0x3de",
+ "generators": [
+ {
+ "x": "0x16a",
+ "y": "0x197",
+ "order": "0x3de",
+ "cofactor": "0x1"
+ }
+ ],
+ "points": [
+ {
+ "x": "0x0",
+ "y": "0x0",
+ "order": "0x2"
+ },
+ {
+ "x": "0x2fb",
+ "y": "0x285",
+ "order": "0x3"
+ },
+ {
+ "x": "0x9d",
+ "y": "0xd7",
+ "order": "0x5"
+ },
+ {
+ "x": "0x2bc",
+ "y": "0x165",
+ "order": "0xb"
+ }
+ ]
+}
diff --git a/test/fp_10_a.csv b/test/fp_10_a.csv
index d90d75a..b9ec96c 100644
--- a/test/fp_10_a.csv
+++ b/test/fp_10_a.csv
@@ -1 +1 @@
-0xb,0x1,0x2,0x[0-9a-f],0x[0-9a-f],0x8,0x2,0x[0-9a-f],0x[0-9a-f],0x[0-9a-f],0x[0-9a-f],0x10,0x[0-9a-f],0x[0-9a-f],0x2
+0x000b,0x0001,0x0002,0x0010,0x[0-9a-f]{4},0x[0-9a-f]{4},0x8,0x2,0x[0-9a-f]{4},0x[0-9a-f]{4},0x[0-9a-f]{1,4},0x[0-9a-f]{1,4},0x[0-9a-f]{4},0x[0-9a-f]{4},0x2.*
diff --git a/test/fp_10_a.json b/test/fp_10_a.json
new file mode 100644
index 0000000..666491a
--- /dev/null
+++ b/test/fp_10_a.json
@@ -0,0 +1,29 @@
+\{
+ "field": \{
+ "p": "0xb"
+ \},
+ "a": "0x1",
+ "b": "0x2",
+ "order": "0x10",
+ "generators": \[
+ \{
+ "x": "0x\d{1,2}",
+ "y": "0x\d{1,2}",
+ "order": "0x8",
+ "cofactor": "0x2"
+ \},
+ \{
+ "x": "0x\d{1,2}",
+ "y": "0x\d{1,2}",
+ "order": "0x8",
+ "cofactor": "0x2"
+ \}
+ \],
+ "points": \[
+ \{
+ "x": "0x\d{1,2}",
+ "y": "0x\d{1,2}",
+ "order": "0x2"
+ \}
+ \]
+\} \ No newline at end of file
diff --git a/test/verify.gp b/test/verify.gp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/verify.gp