diff options
Diffstat (limited to 'src/gen/point.c')
| -rw-r--r-- | src/gen/point.c | 158 |
1 files changed, 50 insertions, 108 deletions
diff --git a/src/gen/point.c b/src/gen/point.c index 4251913..66a77d4 100644 --- a/src/gen/point.c +++ b/src/gen/point.c @@ -5,6 +5,8 @@ #include "point.h" #include "order.h" #include "util/memory.h" +#include "math/subgroups.h" +#include "types.h" point_t *point_new(void) { return try_calloc(sizeof(point_t)); } @@ -120,53 +122,35 @@ GENERATOR(points_gen_random) { return 1; } -/* - GEN o = utoi(dprimes[i]); - GEN mul = ellmul(curve->curve, rand, o); - - if (gequal0(mul)) { - printf("Success! %lu\n", npoints); - curve->points[i] = point_new(); - - gerepileall(btop, 2, &rand, &o); - curve->points[i]->point = rand; - curve->points[i]->order = o; - npoints++; - break; - } - */ - -GENERATOR(points_gen_trial) { - // TODO stack code!!! - if (!args) { - fprintf(stderr, "No args to an arged function. points_gen_trial\n"); - return INT_MIN; - } - - pari_ulong *primes = (pari_ulong *)args->args; - size_t nprimes = args->nargs; +static int points_from_orders(curve_t *curve, const config_t *cfg, GEN orders) { + // TODO better stack code + size_t norders = (size_t)glength(orders); - curve->points = points_new(nprimes); - curve->npoints = nprimes; + curve->points = points_new(norders); + curve->npoints = norders; - size_t npoints = 0; - while (npoints < nprimes) { - GEN rand = genrand(curve->curve); - GEN ord = ellorder(curve->curve, rand, NULL); + for (size_t ngen = 0; ngen <= curve->ngens; ++ngen) { + point_t *gen = curve->generators[ngen]; - for (long i = 0; i < nprimes; ++i) { - if (curve->points[i] == NULL && dvdis(ord, primes[i])) { + for (long i = 0; i < norders; ++i) { + GEN num = gel(orders, i + 1); + if (curve->points[i] == NULL) { pari_sp ftop = avma; - GEN p = stoi(primes[i]); - GEN mul = divii(ord, p); - GEN point = ellmul(curve->curve, rand, mul); + GEN point = NULL; + if (equalii(gen->order, num)) { + point = gcopy(gen->point); + } else if (dvdii(gen->order, num)) { + GEN mul = divii(gen->order, num); + point = ellmul(curve->curve, gen->point, mul); + } - curve->points[i] = point_new(); - gerepileall(ftop, 2, &point, &p); - curve->points[i]->point = point; - curve->points[i]->order = p; - npoints++; + if (point) { + curve->points[i] = point_new(); + gerepileall(ftop, 1, &point); + curve->points[i]->point = point; + curve->points[i]->order = gcopy(num); + } } } } @@ -174,83 +158,41 @@ GENERATOR(points_gen_trial) { return 1; } -GENERATOR(points_gen_prime) { - // TODO stack code!!! - - GEN primes = order_factors(curve, cfg); - long nprimes = glength(primes); - curve->points = points_new((size_t)nprimes); - curve->npoints = (size_t)nprimes; - - long npoints = 0; - while (npoints < nprimes) { - GEN rand = genrand(curve->curve); - GEN ord = ellorder(curve->curve, rand, NULL); - // ord(rand) = ord - - for (long i = 1; i <= nprimes; ++i) { - if (curve->points[i - 1] == NULL && dvdii(ord, gel(primes, i))) { - pari_sp ftop = avma; +GENERATOR(points_gen_trial) { + if (!args) { + fprintf(stderr, "No args to an arged function. points_gen_trial\n"); + return INT_MIN; + } - // primes[i] divides ord - // mul = ord/primes[i] - GEN mul = divii(ord, gel(primes, i)); - GEN point = ellmul(curve->curve, rand, mul); + pari_ulong *primes = (pari_ulong *)args->args; + size_t nprimes = args->nargs; - curve->points[i - 1] = point_new(); - gerepileall(ftop, 1, &point); - curve->points[i - 1]->point = point; - curve->points[i - 1]->order = gcopy(gel(primes, i)); - npoints++; - } - } + GEN orders = gtovec0(gen_0, nprimes); + for (size_t i = 1; i <= nprimes; ++i) { + gel(orders, i) = utoi(primes[i - 1]); } - return 1; + return points_from_orders(curve, cfg, orders); } -GENERATOR(points_gen_allgroups) { - // TODO stack code!!! - - GEN primes = order_factors(curve, cfg); - - GEN groups = order_groups(curve, cfg, primes); - long ngroups = glength(groups); - - curve->points = points_new((size_t)ngroups); - curve->npoints = (size_t)ngroups; - - long npoints = 0; - while (npoints < ngroups) { - GEN rand = genrand(curve->curve); - GEN ord = ellorder(curve->curve, rand, NULL); - - for (long i = 1; i <= ngroups; ++i) { - pari_sp ftop = avma; - GEN num = gel(groups, i); +GENERATOR(points_gen_prime) { + GEN primes = subgroups_prime(curve->order, cfg); + return points_from_orders(curve, cfg, primes); +} - if (curve->points[i - 1] == NULL) { - GEN point = NULL; - if (equalii(ord, num)) { - point = gcopy(rand); - } else if (dvdii(ord, num)) { - GEN mul = divii(ord, num); - point = ellmul(curve->curve, rand, mul); - } +GENERATOR(points_gen_allgroups) { + GEN groups = subgroups_all(curve->order, cfg); + return points_from_orders(curve, cfg, groups); +} - if (point) { - curve->points[i - 1] = point_new(); - gerepileall(ftop, 1, &point); - curve->points[i - 1]->point = point; - curve->points[i - 1]->order = gcopy(num); - ++npoints; - } - } - } +GENERATOR(points_gen_nonprime) { + GEN groups = subgroups_nonprime(curve->order, cfg); + if (!groups) { + return -6; + } else { + return points_from_orders(curve, cfg, groups); } - - return 1; } UNROLL(points_unroll) { |
