diff options
| author | J08nY | 2017-02-05 03:59:52 +0100 |
|---|---|---|
| committer | J08nY | 2017-02-05 03:59:52 +0100 |
| commit | 763fc80153c5e9287f1b0f0609b11fb4f50c90ab (patch) | |
| tree | 5cd6e7acc4512cca65bcc16a74f3b63879b2d3bc /src/gp.c | |
| parent | 3d9bf583ccc5eea61c5f78f52d1e2073daee924c (diff) | |
| download | ecgen-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.c | 207 |
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; +} |
