summaryrefslogtreecommitdiff
path: root/src/gp.c
diff options
context:
space:
mode:
authorJ08nY2017-02-05 03:59:52 +0100
committerJ08nY2017-02-05 03:59:52 +0100
commit763fc80153c5e9287f1b0f0609b11fb4f50c90ab (patch)
tree5cd6e7acc4512cca65bcc16a74f3b63879b2d3bc /src/gp.c
parent3d9bf583ccc5eea61c5f78f52d1e2073daee924c (diff)
downloadecgen-0.2.0.tar.gz
ecgen-0.2.0.tar.zst
ecgen-0.2.0.zip
Diffstat (limited to 'src/gp.c')
-rw-r--r--src/gp.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/gp.c b/src/gp.c
new file mode 100644
index 0000000..d15e117
--- /dev/null
+++ b/src/gp.c
@@ -0,0 +1,207 @@
+#include "gp.h"
+
+void init_gp(void) /* void */
+{
+ pari_sp ltop = avma;
+ avma = ltop;
+ return;
+}
+
+/*
+* ecgen, tool for generating Elliptic curve domain parameters
+* Copyright (C) 2017 J08nY
+*/
+
+/*
+* ecgen, tool for generating Elliptic curve domain parameters
+* Copyright (C) 2017 J08nY
+*/
+
+GEN random_primer(GEN range) /* int */
+{
+ pari_sp ltop = avma;
+ GEN p = gen_0; /* int */
+ if (!is_matvec_t(typ(range))) pari_err_TYPE("random_primer", range);
+ {
+ pari_sp btop = avma;
+ do {
+ p = randomprime(range);
+ if (gc_needed(btop, 1)) p = gerepilecopy(btop, p);
+ } while (!isprime(p));
+ }
+ p = gerepilecopy(ltop, p);
+ return p;
+}
+
+/**
+* Calculates a random prime of bit size bits.
+*
+* @param bits bit size of the requested prime
+* @return random prime between 2^(bits - 1) and 2^bits
+*/
+GEN random_prime(long bits) /* int */
+{
+ pari_sp ltop = avma;
+ GEN p1 = gen_0; /* vec */
+ GEN p2 = gen_0; /* int */
+ p1 = cgetg(3, t_VEC);
+ gel(p1, 1) = powis(gen_2, bits - 1);
+ gel(p1, 2) = powis(gen_2, bits);
+ p2 = random_primer(p1);
+ p2 = gerepilecopy(ltop, p2);
+ return p2;
+}
+
+GEN random_intr(GEN range) {
+ pari_sp ltop = avma;
+ GEN p1 = gen_0;
+ if (!is_matvec_t(typ(range))) pari_err_TYPE("random_intr", range);
+ p1 = genrand(range);
+ p1 = gerepilecopy(ltop, p1);
+ return p1;
+}
+
+/**
+* Generates a random integer with bit size bits.
+*
+* @param bits bit size of the requested integer
+* @return random int between 2^(bits - 1) and 2^bits
+*/
+GEN random_int(long bits) {
+ pari_sp ltop = avma;
+ GEN p1 = gen_0; /* vec */
+ GEN p2 = gen_0;
+ p1 = cgetg(3, t_VEC);
+ gel(p1, 1) = powis(gen_2, bits - 1);
+ gel(p1, 2) = powis(gen_2, bits);
+ p2 = random_intr(p1);
+ p2 = gerepilecopy(ltop, p2);
+ return p2;
+}
+
+/**
+* Converts a list to a vector.
+*
+* @param l list to convert
+* @return a vector of the lists values
+*/
+GEN list_to_vec(GEN l) /* vec */
+{
+ pari_sp ltop = avma;
+ GEN v = gen_0; /* vec */
+ GEN n = gen_0; /* int */
+ GEN p1 = gen_0; /* vec */
+ n = stoi(glength(l));
+ {
+ long l2;
+ p1 = cgetg(itos(n) + 1, t_VEC);
+ for (l2 = 1; cmpsi(l2, n) <= 0; ++l2) gel(p1, l2) = gen_0;
+ }
+ v = p1;
+ {
+ pari_sp btop = avma;
+ GEN i = gen_0;
+ for (i = gen_1; gcmp(i, n) <= 0; i = gaddgs(i, 1)) {
+ gel(v, gtos(i)) = gcopy(gel(list_data(l), gtos(i)));
+ if (gc_needed(btop, 1)) gerepileall(btop, 2, &v, &i);
+ }
+ }
+ v = gerepilecopy(ltop, v);
+ return v;
+}
+
+/*
+* ecgen, tool for generating Elliptic curve domain parameters
+* Copyright (C) 2017 J08nY
+*/
+
+/**
+* Computes primes upto some upper bound.
+*
+* @param bound an upper bound on primes
+* @return a vector of primes up to bound^2
+*/
+GEN prime_upto(GEN bound) /* vec */
+{
+ pari_sp ltop = avma;
+ GEN p = gen_0; /* list */
+ GEN product = gen_0, last = gen_0; /* int */
+ GEN result = gen_0; /* vec */
+ if (typ(bound) != t_INT) pari_err_TYPE("prime_upto", bound);
+ p = mklist();
+ bound = sqri(bound);
+ listput0(p, gen_2, 0);
+ product = gen_2;
+ last = gen_2;
+ {
+ pari_sp btop = avma;
+ while (cmpii(product, bound) < 0) {
+ last = nextprime(addis(last, 1));
+ listput0(p, last, 0);
+ product = mulii(product, last);
+ if (gc_needed(btop, 1)) gerepileall(btop, 3, &p, &product, &last);
+ }
+ }
+ result = list_to_vec(p);
+ listkill(p);
+ result = gerepilecopy(ltop, result);
+ return result;
+}
+
+/**
+*
+*/
+GEN invalid(GEN coeffs, GEN field, GEN primes, GEN bits, long prec) /* vec */
+{
+ pari_sp ltop = avma;
+ GEN bs = gen_0, cs = gen_0, eq = gen_0; /* vec */
+ GEN e = gen_0; /* ell */
+ GEN b = gen_0, n = gen_0, c = gen_0, o = gen_0; /* int */
+ GEN p1 = gen_0; /* vec */
+ if (!is_matvec_t(typ(coeffs))) pari_err_TYPE("invalid", coeffs);
+ if (typ(field) != t_POL) pari_err_TYPE("invalid", field);
+ if (!is_matvec_t(typ(primes))) pari_err_TYPE("invalid", primes);
+ if (typ(bits) != t_INT) pari_err_TYPE("invalid", bits);
+ n = stoi(lg(primes) - 1);
+ {
+ long l2;
+ p1 = cgetg(itos(n) + 1, t_VEC);
+ for (l2 = 1; cmpsi(l2, n) <= 0; ++l2) gel(p1, l2) = gen_0;
+ }
+ bs = p1;
+ eq = gcopy(coeffs);
+ c = gen_0;
+ {
+ pari_sp btop = avma;
+ while (cmpii(c, n) < 0) {
+ b = random_int(itos(bits));
+ gel(eq, 4) = icopy(b);
+ /* Times field? */
+
+ pari_CATCH(CATCH_ALL) {
+ GEN E = pari_err_last(); /* error */
+ continue;
+ }
+ pari_TRY { e = ellinit(eq, field, prec); }
+ pari_ENDCATCH o = ellsea(e, 0);
+ {
+ pari_sp btop = avma;
+ GEN i = gen_0;
+ for (i = gen_1; gcmp(i, n) <= 0; i = gaddgs(i, 1)) {
+ if (gequal0(gmod(o, gel(primes, gtos(i)))) &&
+ gequal0(gel(bs, gtos(i)))) {
+ gel(bs, gtos(i)) = icopy(b);
+ gel(cs, gtos(i)) = gcopy(e);
+ c = addis(c, 1);
+ }
+ if (gc_needed(btop, 1))
+ gerepileall(btop, 4, &bs, &cs, &c, &i);
+ }
+ }
+ if (gc_needed(btop, 1))
+ gerepileall(btop, 7, &bs, &cs, &eq, &e, &b, &c, &o);
+ }
+ }
+ cs = gerepilecopy(ltop, cs);
+ return cs;
+}