diff options
| -rw-r--r-- | src/exhaustive/anomalous.c | 10 | ||||
| -rw-r--r-- | src/io/cli.c | 2 | ||||
| -rw-r--r-- | src/io/config.h | 1 | ||||
| -rw-r--r-- | src/io/output.c | 132 | ||||
| -rw-r--r-- | src/math/curve.c | 35 | ||||
| -rw-r--r-- | src/math/curve.h | 12 | ||||
| -rwxr-xr-x | test/ecgen.sh | 12 | ||||
| -rw-r--r-- | test/econvert_format.csv | 1 | ||||
| -rw-r--r-- | test/econvert_format.json | 29 | ||||
| -rw-r--r-- | test/f2m_10_a.csv | 2 | ||||
| -rw-r--r-- | test/f2m_10_a.json | 41 | ||||
| -rw-r--r-- | test/fp_10_a.csv | 2 | ||||
| -rw-r--r-- | test/fp_10_a.json | 29 | ||||
| -rw-r--r-- | test/verify.gp | 0 |
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 |
