aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cm/cm.c17
-rw-r--r--src/cm/p1363.c391
-rw-r--r--src/cm/p1363.h39
-rw-r--r--src/ecgen.c3
-rw-r--r--src/exhaustive/anomalous.c100
-rw-r--r--src/exhaustive/anomalous.h32
-rw-r--r--src/exhaustive/exhaustive.c16
-rw-r--r--src/exhaustive/seed.c23
-rw-r--r--src/io/cli.c25
-rw-r--r--src/io/cli.h1
-rw-r--r--src/io/config.h3
-rw-r--r--src/math/types.h6
12 files changed, 642 insertions, 14 deletions
diff --git a/src/cm/cm.c b/src/cm/cm.c
index 71e720c..43ae515 100644
--- a/src/cm/cm.c
+++ b/src/cm/cm.c
@@ -2,10 +2,21 @@
* ecgen, tool for generating Elliptic curve domain parameters
* Copyright (C) 2017 J08nY
*/
+/**
+ * @file cm.c
+ */
#include "cm.h"
-#include "io/output.h"
+#include "exhaustive/anomalous.h"
+#include "p1363.h"
int cm_do(config_t *cfg) {
- debug("# Starting Complex Multiplication method\n");
- return INT_MIN;
+ GEN D = stoi(71);
+ form_t **forms;
+ size_t nforms = p1363_forms(D, &forms);
+ for (size_t i = 0; i < nforms; ++i) {
+ p1363_invariant(D, forms[i]);
+ }
+
+ p1363_free(&forms, nforms);
+ return 0;
}
diff --git a/src/cm/p1363.c b/src/cm/p1363.c
new file mode 100644
index 0000000..24d28cb
--- /dev/null
+++ b/src/cm/p1363.c
@@ -0,0 +1,391 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+/**
+ * @file p1363.c
+ */
+#include "p1363.h"
+#include <pari/paripriv.h>
+
+GEN p1363_group(GEN D) {
+ pari_sp ltop = avma;
+ GEN s = mpfloor(sqrtr(rdivis(D, 3, BIGDEFAULTPREC)));
+ long llen = itos(s) * 2;
+ GEN l = gtovec0(gen_0, llen);
+
+ long j = 1;
+ GEN B = gen_0;
+ for (; cmpii(B, s) <= 0; B = addii(B, gen_1)) {
+ GEN B2 = sqri(B);
+ GEN d = addii(D, B2);
+ GEN lower = mulis(B, 2);
+ GEN upper = gsqrt(d, BIGDEFAULTPREC);
+
+ GEN divs = divisors(d);
+ long len = glength(divs);
+ for (long i = 1; i <= len; ++i) {
+ GEN div = gel(divs, i);
+ if (gcmp(div, lower) >= 0 && gcmp(div, upper) <= 0) {
+ GEN A = div;
+ GEN C = divii(d, A);
+ GEN gcd = gcdii(gcdii(A, lower), C);
+
+ if (gequal1(gcd)) {
+ GEN v = gtovec0(gen_0, 3);
+ gel(v, 1) = A;
+ gel(v, 2) = B;
+ gel(v, 3) = C;
+ gel(l, j++) = v;
+ if (cmpii(gen_0, lower) < 0 && cmpii(lower, A) < 0 &&
+ cmpii(A, C) < 0) {
+ GEN n = gtovec0(gen_0, 3);
+ gel(n, 1) = A;
+ gel(n, 2) = negi(B);
+ gel(n, 3) = C;
+ gel(l, j++) = n;
+ }
+ }
+ }
+ }
+ }
+ return gerepilecopy(ltop, vec_shorten(l, j - 1));
+}
+
+long p1363_num(GEN group) { return glength(group); }
+
+size_t p1363_forms(GEN D, form_t ***forms) {
+ GEN group = p1363_group(D);
+ size_t nforms = (size_t)p1363_num(group);
+ *forms = pari_malloc(nforms * sizeof(form_t *));
+ memset(*forms, 0, nforms * sizeof(form_t *));
+
+ for (size_t i = 0; i < nforms; ++i) {
+ (*forms)[i] = pari_malloc(sizeof(form_t));
+ memset((*forms)[i], 0, sizeof(form_t));
+ (*forms)[i]->A = gel(gel(group, i + 1), 1);
+ (*forms)[i]->B = gel(gel(group, i + 1), 2);
+ (*forms)[i]->C = gel(gel(group, i + 1), 3);
+ }
+
+ return nforms;
+}
+
+void p1363_free(form_t ***forms, size_t nforms) {
+ if (*forms) {
+ for (size_t i = 0; i < nforms; ++i) {
+ if ((*forms)[i]) {
+ pari_free((*forms)[i]);
+ (*forms)[i] = NULL;
+ }
+ }
+ pari_free(*forms);
+ *forms = NULL;
+ }
+}
+
+GEN p1363_func_F(GEN z) {
+ pari_sp ltop = avma;
+
+ if (gequal0(z)) {
+ return gcopy(gen_1);
+ }
+ GEN sum = cgetc(BIGDEFAULTPREC * 5);
+ gel(sum, 1) = real_1(BIGDEFAULTPREC * 5);
+ gel(sum, 2) = real_0(BIGDEFAULTPREC * 5);
+ pari_printf("initial sum = %Ps\n", sum);
+ GEN last;
+
+ GEN j = gcopy(gen_1);
+ do {
+ last = gcopy(sum);
+
+ GEN j3 = mulsi(3, sqri(j));
+ GEN quota = divis(subii(j3, j), 2);
+ GEN quotb = divis(addii(j3, j), 2);
+
+ GEN term = gadd(gpow(z, quota, BIGDEFAULTPREC),
+ gpow(z, quotb, BIGDEFAULTPREC));
+ pari_printf("%Ps %Ps \n", sum, term);
+ if (mod2(j) == 0) {
+ sum = gadd(sum, term);
+ } else {
+ sum = gsub(sum, term);
+ }
+
+ addiiz(j, gen_1, j);
+ if (gc_needed(ltop, 1)) gerepileall(ltop, 3, &j, &sum, &last);
+ } while (!gequal(sum, last));
+
+ pari_printf("end sum = %Ps, last = %Ps\n", sum, last);
+
+ return gerepilecopy(ltop, sum);
+}
+
+GEN p1363_func_fzero(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+
+ GEN upper = p1363_func_F(gneg(form->theta));
+ GEN lower = p1363_func_F(gsqr(form->theta));
+ GEN front = gpow(form->theta, gdivgs(gen_m1, 24), BIGDEFAULTPREC * 5);
+
+ GEN result = gmul(gdiv(upper, lower), front);
+
+ return gerepilecopy(ltop, result);
+}
+
+GEN p1363_func_fone(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+
+ GEN upper = p1363_func_F(form->theta);
+ GEN lower = p1363_func_F(gsqr(form->theta));
+ GEN front = gpow(form->theta, gdivgs(gen_m1, 24), BIGDEFAULTPREC * 5);
+
+ GEN result = gmul(gdiv(upper, lower), front);
+
+ return gerepilecopy(ltop, result);
+}
+
+GEN p1363_func_ftwo(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+
+ GEN upper = p1363_func_F(gpowgs(form->theta, 4));
+ GEN lower = p1363_func_F(gsqr(form->theta));
+ GEN front = gmul(sqrti(gen_2),
+ gpow(form->theta, gdivgs(gen_1, 12), BIGDEFAULTPREC * 5));
+
+ GEN result = gmul(gdiv(upper, lower), front);
+
+ return gerepilecopy(ltop, result);
+}
+
+void p1363_m8(GEN D, form_t *form) { form->m8 = mod8(D); }
+
+void p1363_I(GEN D, form_t *form) {
+ switch (form->m8) {
+ case 1:
+ case 2:
+ case 6:
+ case 7:
+ form->I = 3;
+ break;
+ case 5:
+ form->I = 6;
+ break;
+ case 3:
+ if (dvdis(D, 3)) {
+ form->I = 2;
+ } else {
+ form->I = 0;
+ }
+ break;
+ default:
+ pari_err_DOMAIN("p1636_I", "D", "==", stoi(8), D);
+ }
+}
+
+void p1363_J(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+ GEN ac = mulii(form->A, form->C);
+
+ if (mod2(ac) == 1) {
+ form->J = 0;
+ } else {
+ if (mod2(form->C) == 0) {
+ form->J = 1;
+ } else if (mod2(form->A) == 0) {
+ form->J = 2;
+ } else {
+ pari_err_BUG("hwat?");
+ }
+ }
+ avma = ltop;
+}
+
+void p1363_K(GEN D, form_t *form) {
+ switch (form->m8) {
+ case 1:
+ case 2:
+ case 6:
+ form->K = 2;
+ break;
+ case 3:
+ case 7:
+ form->K = 1;
+ break;
+ case 5:
+ form->K = 5;
+ break;
+ default:
+ pari_err_DOMAIN("p1636_I", "D", "==", stoi(8), D);
+ }
+}
+
+void p1363_L(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+ GEN ac = mulii(form->A, form->C);
+ long a2 = mod2(form->A);
+ long c2 = mod2(form->C);
+
+ if (mod2(ac) == 1 || (form->m8 == 5 && mod2(form->C) == 0)) {
+ form->L = addii(subii(form->A, form->C), mulii(sqri(form->A), form->C));
+ } else {
+ if (a2 == 0) {
+ if (form->m8 == 3) {
+ form->L = addii(subii(form->A, form->C),
+ mulsi(5, mulii(form->A, sqri(form->C))));
+ } else {
+ form->L = subii(subii(form->A, form->C),
+ mulii(form->A, sqri(form->C)));
+ }
+ } else if (c2 == 0) {
+ form->L = subii(addii(form->A, mulsi(2, form->C)),
+ mulii(form->A, sqri(form->C)));
+ } else {
+ pari_err_BUG("what?");
+ }
+ }
+ form->L = gerepileupto(ltop, form->L);
+}
+
+void p1363_M(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+ GEN quot;
+ if (mod2(form->A) == 0) {
+ quot = divis(subis(sqri(form->C), 1), 8);
+ } else {
+ quot = divis(subis(sqri(form->A), 1), 8);
+ }
+ form->M = gerepileupto(ltop, powii(gen_m1, quot));
+}
+
+void p1363_N(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+ long ac2 = mod2(mulii(form->A, form->C));
+
+ switch (form->m8) {
+ case 5:
+ form->N = gen_1;
+ break;
+ case 1:
+ case 2:
+ case 6:
+ form->N = gcopy(form->M);
+ break;
+ case 3:
+ if (ac2 == 0) {
+ form->N = negi(form->M);
+ } else {
+ form->N = gen_1;
+ }
+ break;
+ case 7:
+ if (ac2 == 0) {
+ form->N = gen_1;
+ } else {
+ form->N = gcopy(form->M);
+ }
+ break;
+ default:
+ pari_err_DOMAIN("p1363_N", "D", "=", stoi(8), D);
+ }
+ form->N = gerepileupto(ltop, form->N);
+}
+
+void p1363_lambda(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+ GEN pik = mulri(mppi(BIGDEFAULTPREC), stoi(form->K));
+ GEN quot = divrs(pik, 24);
+ form->lambda = gerepileupto(ltop, expIr(quot));
+}
+
+void p1363_theta(GEN D, form_t *form) {
+ pari_sp ltop = avma;
+
+ GEN upper = gadd(gneg(gsqrt(D, BIGDEFAULTPREC)), gmul(form->B, gen_I()));
+ GEN quot = gmul(gdiv(upper, form->A), mppi(BIGDEFAULTPREC));
+
+ form->theta = gerepileupto(ltop, gexp(quot, BIGDEFAULTPREC));
+}
+
+GEN p1363_invariant(GEN D, form_t *form) {
+ pari_printf("[A,B,C] = %Pi %Pi %Pi\n", form->A, form->B, form->C);
+ pari_sp ltop = avma;
+
+ p1363_m8(D, form);
+ p1363_I(D, form);
+ printf("I = %li\n", form->I);
+ p1363_J(D, form);
+ printf("J = %li\n", form->J);
+ p1363_K(D, form);
+ printf("K = %li\n", form->K);
+ p1363_L(D, form);
+ pari_printf("L = %Pi\n", form->L);
+ p1363_M(D, form);
+ pari_printf("M = %Pi\n", form->M);
+ p1363_N(D, form);
+ pari_printf("N = %Pi\n", form->N);
+ p1363_lambda(D, form);
+ pari_printf("lambda = %Ps\n", form->lambda);
+ p1363_theta(D, form);
+ pari_printf("theta = %Ps\n", form->theta);
+
+ GEN G = gcdii(D, stoi(3));
+ pari_printf("G = %Pi\n", G);
+
+ GEN bl = mulii(form->B, form->L);
+
+ GEN lmbl = gpow(form->lambda, negi(bl), BIGDEFAULTPREC);
+ pari_printf("lmbl = %Ps\n", lmbl);
+
+ GEN mi6 = gneg(gdiv(stoi(form->I), stoi(6)));
+ GEN powmi6 = gpow(gen_2, mi6, BIGDEFAULTPREC);
+ pari_printf("powmi6 = %Ps\n", powmi6);
+
+ GEN f = gen_0;
+ switch (form->J) {
+ case 0:
+ f = p1363_func_fzero(D, form);
+ break;
+ case 1:
+ f = p1363_func_fone(D, form);
+ break;
+ case 2:
+ f = p1363_func_ftwo(D, form);
+ break;
+ default:
+ pari_err_DOMAIN("p1363_invariant", "J", ">", stoi(2),
+ stoi(form->J));
+ }
+
+ pari_printf("f = %Ps\n", f);
+
+ GEN fK = gpow(f, stoi(form->K), BIGDEFAULTPREC);
+ pari_printf("fK = %Ps\n", fK);
+
+ GEN in = gmul(lmbl, powmi6);
+ pari_printf("in = %Ps\n", in);
+ GEN inner = gmul(gmul(form->N, in), fK);
+ pari_printf("inner = %Ps\n", inner);
+ GEN result = gpow(inner, G, BIGDEFAULTPREC);
+ pari_printf("result = %Ps\n", result);
+
+ return gerepilecopy(ltop, result);
+}
+
+GEN p1363_poly(GEN D, form_t **forms, size_t nforms) {
+ pari_sp ltop = avma;
+ long v = fetch_var();
+ name_var(v, "t");
+
+ GEN terms = gtovec0(gen_0, nforms);
+ for (size_t i = 0; i < nforms; ++i) {
+ gel(terms, i + 1) = gsub(pol_x(v), p1363_invariant(D, forms[i]));
+ }
+
+ GEN result = gen_1;
+ for (size_t i = 0; i < nforms; ++i) {
+ gmulz(result, gel(terms, i + 1), result);
+ }
+ return gerepilecopy(ltop, result);
+}
diff --git a/src/cm/p1363.h b/src/cm/p1363.h
new file mode 100644
index 0000000..e5c9fbd
--- /dev/null
+++ b/src/cm/p1363.h
@@ -0,0 +1,39 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+/**
+ * @file p1363.h
+ */
+#ifndef ECGEN_P1363_H
+#define ECGEN_P1363_H
+
+#include <pari/pari.h>
+
+typedef struct form_t {
+ GEN A;
+ GEN B;
+ GEN C;
+
+ long m8;
+
+ long I;
+ long J;
+ long K;
+ GEN L;
+ GEN M;
+ GEN N;
+
+ GEN lambda;
+ GEN theta;
+} form_t;
+
+size_t p1363_forms(GEN D, form_t ***forms);
+
+void p1363_free(form_t ***forms, size_t nforms);
+
+GEN p1363_invariant(GEN D, form_t *form);
+
+GEN p1363_poly(GEN D, form_t **forms, size_t nforms);
+
+#endif // ECGEN_P1363_H
diff --git a/src/ecgen.c b/src/ecgen.c
index 987a495..f482fcd 100644
--- a/src/ecgen.c
+++ b/src/ecgen.c
@@ -60,8 +60,7 @@ bool init(void) {
pari_sp ltop = avma;
pari_CATCH(e_FILE) {}
pari_TRY { ellmodulareqn(2, -1, -1); }
- pari_ENDCATCH
- avma = ltop;
+ pari_ENDCATCH avma = ltop;
// open outfile
output_init(&cfg);
diff --git a/src/exhaustive/anomalous.c b/src/exhaustive/anomalous.c
new file mode 100644
index 0000000..fea27ed
--- /dev/null
+++ b/src/exhaustive/anomalous.c
@@ -0,0 +1,100 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+/**
+ * @file anomalous.c
+ */
+#include "anomalous.h"
+#include "math/random.h"
+
+static disc_t **disc_table;
+
+void anomalous_init() {
+ disc_table = pari_malloc(sizeof(disc_t *) * 5);
+ if (!disc_table) {
+ perror("Couldn't malloc.");
+ exit(1);
+ }
+ for (int i = 0; i < 5; ++i) {
+ disc_table[i] = pari_malloc(sizeof(disc_t));
+ if (!disc_table[i]) {
+ perror("Couldn't malloc.");
+ exit(1);
+ }
+ }
+
+ /*
+ * Discriminant, j-invariant and field-element (Alpha) from Atsuko Miyaji's
+ * paper.
+ */
+ GEN a = stoi(-32);
+ GEN b = stoi(-64);
+ disc_table[0]->D = stoi(11);
+ disc_table[0]->j = powis(a, 3);
+ disc_table[0]->a = stoi(21);
+ disc_table[1]->D = stoi(19);
+ disc_table[1]->j = powis(mulis(a, 3), 3);
+ disc_table[1]->a = stoi(3);
+ disc_table[2]->D = stoi(43);
+ disc_table[2]->j = powis(mulis(b, 16), 3);
+ disc_table[2]->a = stoi(70);
+ disc_table[3]->D = stoi(67);
+ disc_table[3]->j = powis(mulis(a, 165), 3);
+ disc_table[3]->a = stoi(35805);
+ disc_table[3]->D = stoi(163);
+ disc_table[3]->j = powis(mulis(b, 10005), 3);
+ disc_table[3]->a = stoi(3717878010);
+}
+
+static GEN anomalous_prime(GEN D, const config_t *cfg) {
+ pari_sp ltop = avma;
+ GEN last = divis(addis(D, 1), 4);
+ GEN middle;
+ GEN first;
+ GEN p;
+ GEN b;
+
+ do {
+ b = random_int(cfg->bits);
+ middle = mulii(D, b);
+ first = mulii(middle, b);
+ p = addii(addii(first, middle), last);
+ if (gc_needed(ltop, 1)) {
+ gerepileall(ltop, 2, &p, &last);
+ }
+ } while (!isprime(p));
+
+ // TODO: this does not give me a bits sized prime..
+ // but quite a larger one
+ return gerepilecopy(ltop, p);
+}
+
+int anomalous_field(curve_t *curve, const config_t *cfg, arg_t *args) {
+ // find suitable prime field
+ curve->field = anomalous_prime(disc_table[0]->D, cfg);
+ return 1;
+}
+
+int anomalous_equation(curve_t *curve, const config_t *cfg, arg_t *args) {
+ // 1 on success, -2 on failure
+ pari_sp ltop = avma;
+ return INT_MIN; // TODO this
+}
+
+int anomalous_order(curve_t *curve, const config_t *cfg, arg_t *args) {
+ // copy field to order
+ curve->order = gcopy(curve->field);
+ return 1;
+}
+
+void anomalous_quit() {
+ if (disc_table) {
+ for (int i = 0; i < 5; ++i) {
+ if (disc_table[i]) {
+ pari_free(disc_table[i]);
+ }
+ }
+ pari_free(disc_table);
+ }
+}
diff --git a/src/exhaustive/anomalous.h b/src/exhaustive/anomalous.h
new file mode 100644
index 0000000..eff4686
--- /dev/null
+++ b/src/exhaustive/anomalous.h
@@ -0,0 +1,32 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+/**
+ * @file anomalous.h
+ */
+#ifndef ECGEN_ANOMALOUS_H
+#define ECGEN_ANOMALOUS_H
+
+#include <pari/pari.h>
+#include "io/cli.h"
+#include "math/arg.h"
+#include "math/types.h"
+
+typedef struct disc_t {
+ GEN D;
+ GEN j;
+ GEN a;
+} disc_t;
+
+int anomalous_field(curve_t *curve, const config_t *cfg, arg_t *args);
+
+int anomalous_equation(curve_t *curve, const config_t *cfg, arg_t *args);
+
+int anomalous_order(curve_t *curve, const config_t *cfg, arg_t *args);
+
+void anomalous_init();
+
+void anomalous_quit();
+
+#endif // ECGEN_ANOMALOUS_H
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 9202c7a..5e2fcc8 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -3,6 +3,7 @@
* Copyright (C) 2017 J08nY
*/
#include "exhaustive.h"
+#include "anomalous.h"
#include "io/output.h"
#include "math/arg.h"
#include "math/curve.h"
@@ -30,7 +31,10 @@ static void exhaustive_ginit(gen_t *generators, const config_t *cfg) {
} else {
generators[OFFSET_SEED] = &gen_skip;
- if (cfg->random) {
+ if (cfg->anomalous) {
+ generators[OFFSET_A] = &gen_skip;
+ generators[OFFSET_B] = &anomalous_equation;
+ } else if (cfg->random) {
generators[OFFSET_A] = &a_random;
generators[OFFSET_B] = &b_random;
} else {
@@ -48,6 +52,8 @@ static void exhaustive_ginit(gen_t *generators, const config_t *cfg) {
generators[OFFSET_ORDER] = &order_prime;
} else if (cfg->cofactor) {
generators[OFFSET_ORDER] = &order_smallfact;
+ } else if (cfg->anomalous) {
+ generators[OFFSET_ORDER] = &anomalous_order;
} else {
generators[OFFSET_ORDER] = &order_any;
}
@@ -58,7 +64,9 @@ static void exhaustive_ginit(gen_t *generators, const config_t *cfg) {
generators[OFFSET_GENERATORS] = &gens_any;
}
- if (cfg->random) {
+ if (cfg->anomalous) {
+ generators[OFFSET_FIELD] = &anomalous_field;
+ } else if (cfg->random) {
generators[OFFSET_FIELD] = &field_random;
} else {
generators[OFFSET_FIELD] = &field_input;
@@ -186,8 +194,11 @@ int exhaustive_gen(curve_t *curve, const config_t *cfg, gen_t generators[],
start_offset, end_offset, 0);
}
+static void exhaustive_init() { anomalous_init(); }
+
static void exhaustive_quit(arg_t *argss[]) {
equation_quit();
+ anomalous_quit();
for (size_t i = 0; i < OFFSET_END; ++i) {
if (argss[i]) {
arg_free(&(argss[i]));
@@ -204,6 +215,7 @@ int exhaustive_do(config_t *cfg) {
exhaustive_ginit(generators, cfg);
exhaustive_ainit(argss, cfg);
exhaustive_uinit(unrolls, cfg);
+ exhaustive_init();
for (unsigned long i = 0; i < cfg->count; ++i) {
curve_t *curve = curve_new();
diff --git a/src/exhaustive/seed.c b/src/exhaustive/seed.c
index bd6f274..d35fc05 100644
--- a/src/exhaustive/seed.c
+++ b/src/exhaustive/seed.c
@@ -61,15 +61,38 @@ static GEN seed_stoi(const char *cstr) {
return gerepilecopy(ltop, seed);
}
+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 = pari_malloc((size_t)bytes);
+ if (!result) {
+ perror("Couldn't malloc.");
+ exit(1);
+ }
+
+ for (long i = 0; i < len; ++i) {
+ // TODO
+ }
+ avma = ltop;
+ return result;
+}
+
int seed_random(curve_t *curve, const config_t *cfg, arg_t *args) {
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;
}
int seed_argument(curve_t *curve, const config_t *cfg, arg_t *args) {
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;
}
diff --git a/src/io/cli.c b/src/io/cli.c
index e7de595..228e339 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -34,7 +34,8 @@ enum opt_keys {
OPT_F2M,
OPT_POINTS,
OPT_THREADS,
- OPT_TSTACK
+ OPT_TSTACK,
+ OPT_ANOMALOUS
};
// clang-format off
@@ -46,12 +47,13 @@ struct argp_option options[] = {
{"random", OPT_RANDOM, 0, 0, "Generate a random curve (using Random approach).", 2},
{"prime", OPT_PRIME, 0, 0, "Generate a curve with prime order.", 2},
{"cofactor", OPT_COFACTOR, "BOUND", 0, "Generate a curve with cofactor up to BOUND.", 2},
- {"seed", OPT_SEED, "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).", 2},
{"koblitz", OPT_KOBLITZ, 0, 0, "Generate a Koblitz curve (a = 0).", 2},
{"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/none).", 2},
+ {"seed", OPT_SEED, "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).", 2},
{"count", OPT_COUNT, "COUNT", 0, "Generate multiple curves.", 2},
{0, 0, 0, 0, "Input/Output options:", 3},
{"format", OPT_FORMAT, "FORMAT", 0, "Format to output in. One of [csv,json], default is json.", 3},
@@ -179,6 +181,9 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
case OPT_UNIQUE:
cfg->unique = true;
break;
+ case OPT_ANOMALOUS:
+ cfg->anomalous = true;
+ break;
case OPT_POINTS:
if (arg) {
if (strstr(arg, "random")) {
@@ -241,13 +246,23 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
"from seed, exhaustive or prime order.");
}
if (cfg->cm && (cfg->prime || cfg->from_seed || cfg->invalid ||
- cfg->cofactor)) {
+ cfg->cofactor || cfg->anomalous)) {
argp_failure(state, 1, 0,
"Fixed order curve generation can not generate "
"curves from seed, or invalid curves. Prime order "
"also doesn't make sense if the given one isn't "
"prime.");
}
+ if (cfg->anomalous &&
+ (cfg->binary_field || cfg->cofactor || cfg->from_seed ||
+ cfg->cm || cfg->invalid || cfg->koblitz)) {
+ argp_failure(
+ state, 1, 0,
+ "Anomalous curve generation can not generate "
+ "binary field curves, curves with a cofactor, from seed "
+ "with fixed order, invalid or Koblitz curves.");
+ }
+
// default values
if (!cfg->count) {
cfg->count = 1;
diff --git a/src/io/cli.h b/src/io/cli.h
index 82dcf4b..c670328 100644
--- a/src/io/cli.h
+++ b/src/io/cli.h
@@ -9,6 +9,7 @@
#define ECGEN_CLI_H
#include <argp.h>
+#include <stdbool.h>
#include <stdlib.h>
extern char doc[];
diff --git a/src/io/config.h b/src/io/config.h
index 70018a9..426661c 100644
--- a/src/io/config.h
+++ b/src/io/config.h
@@ -24,12 +24,13 @@ typedef struct {
bool binary_field;
bool prime_field;
- unsigned long count;
+ long count;
bool random;
bool prime;
bool invalid;
bool cm;
char *order;
+ bool anomalous;
bool koblitz;
bool cofactor;
long cofactor_bound;
diff --git a/src/math/types.h b/src/math/types.h
index d6c0cca..6793453 100644
--- a/src/math/types.h
+++ b/src/math/types.h
@@ -15,7 +15,11 @@
/**
* @brief
*/
-typedef struct { GEN seed; } seed_t;
+typedef struct seed_t {
+ char *raw;
+ size_t raw_len;
+ GEN seed;
+} seed_t;
/**
* @brief