diff options
| author | J08nY | 2017-08-30 00:11:18 +0200 |
|---|---|---|
| committer | J08nY | 2017-08-30 00:11:18 +0200 |
| commit | e14198f1feaf82cf6d803ab51d440afa8eee4cdd (patch) | |
| tree | e3e320dce027be9b0934b5a5bb9c00ee250462ba | |
| parent | dad32a97eb61ddb4c9cbbb6b87d26de25f966b91 (diff) | |
| download | ecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.tar.gz ecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.tar.zst ecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.zip | |
| -rw-r--r-- | src/math/subgroups.c | 63 | ||||
| -rw-r--r-- | test/src/math/test_subgroups.c | 35 |
2 files changed, 58 insertions, 40 deletions
diff --git a/src/math/subgroups.c b/src/math/subgroups.c index 3b84d5c..b0317c5 100644 --- a/src/math/subgroups.c +++ b/src/math/subgroups.c @@ -3,7 +3,6 @@ * Copyright (C) 2017 J08nY */ #include "subgroups.h" -#include "gen/types.h" /** * @brief All prime divisors of a given integer. @@ -12,15 +11,17 @@ */ static GEN subgroups_factors(GEN order) { GEN factors = Z_factor(order); - return gel(factors, 1); + return gtovec(gel(factors, 1)); } /** * @brief All prime divisors of a given integer with multiplicity. + * + * subgroups_divisors(27) = [3, 3, 3] * @param order * @return */ -static GEN __attribute__((unused)) subgroups_divisors(GEN order) { +static GEN subgroups_divisors(GEN order) { GEN factors = Z_factor(order); GEN primes = gel(factors, 1); GEN multiples = gel(factors, 2); @@ -42,31 +43,6 @@ static GEN __attribute__((unused)) subgroups_divisors(GEN order) { return result; } -/* -static GEN subgroups_exponents(GEN order) { - GEN factors = Z_factor(order); - GEN primes = gel(factors, 1); - GEN multiples = gel(factors, 2); - - long len = glength(primes); - pari_ulong count = 1; - for (long i = 1; i <= len; ++i) { - count *= itou(gel(multiples,i)) + 1; - } - - GEN result = gtovec0(gen_0, count); - -} -*/ - -GEN subgroups_prime(const curve_t *curve, const config_t *cfg) { - if (cfg->prime || isprime(curve->order)) { - return gtocol(curve->order); - } else { - return subgroups_factors(curve->order); - } -} - /** * @brief * @param factors @@ -80,12 +56,12 @@ static GEN subgroups_2n(GEN factors, size_t min_bits) { GEN groups = gtovec0(gen_0, itos(amount) - (min_bits * nprimes) - 1); size_t i = 0; - for (size_t count = 1; count < (size_t)(1 << nprimes); ++count) { + for (size_t count = 1; count < (size_t)(1) << nprimes; ++count) { pari_sp btop = avma; GEN result = gen_1; size_t bits = 0; for (long bit = 0; bit < nprimes; ++bit) { - size_t mask = (size_t)(1 << bit); + size_t mask = (size_t)(1) << bit; if (count & mask) { result = mulii(result, gel(factors, bit + 1)); bits++; @@ -97,7 +73,17 @@ static GEN subgroups_2n(GEN factors, size_t min_bits) { avma = btop; } } - return groups; + GEN sorted = sort(groups); + size_t k = 1; + for (size_t j = 1; j <= i; j++) { + GEN k_value = gel(sorted, k); + GEN j_value = gel(sorted, j); + if (!gequal(k_value, j_value)) { + gel(sorted, ++k) = j_value; + } + } + sorted = vec_shorten(sorted, k); + return sorted; } /** @@ -107,9 +93,9 @@ static GEN subgroups_2n(GEN factors, size_t min_bits) { * @return */ static GEN subgroups_2n_gens(const curve_t *curve, size_t min_bits) { - GEN one_factors = subgroups_factors(curve->generators[0]->order); + GEN one_factors = subgroups_divisors(curve->generators[0]->order); GEN one = subgroups_2n(one_factors, min_bits); - GEN other_factors = subgroups_factors(curve->generators[1]->order); + GEN other_factors = subgroups_divisors(curve->generators[1]->order); GEN other = subgroups_2n(other_factors, min_bits); if (!one) { return other; @@ -128,12 +114,19 @@ static GEN subgroups_2n_gens(const curve_t *curve, size_t min_bits) { return result; } +GEN subgroups_prime(const curve_t *curve, const config_t *cfg) { + if (cfg->prime || isprime(curve->order)) { + return gtovec(curve->order); + } + return subgroups_factors(curve->order); +} + GEN subgroups_nonprime(const curve_t *curve, const config_t *cfg) { if (cfg->prime || isprime(curve->order)) { return NULL; } else { if (curve->ngens == 1) { - GEN factors = subgroups_factors(curve->order); + GEN factors = subgroups_divisors(curve->order); return subgroups_2n(factors, 1); } else { return subgroups_2n_gens(curve, 1); @@ -146,7 +139,7 @@ GEN subgroups_all(const curve_t *curve, const config_t *cfg) { return gtovec(curve->order); } else { if (curve->ngens == 1) { - GEN factors = subgroups_factors(curve->order); + GEN factors = subgroups_divisors(curve->order); return subgroups_2n(factors, 0); } else { return subgroups_2n_gens(curve, 0); diff --git a/test/src/math/test_subgroups.c b/test/src/math/test_subgroups.c index ad42282..b554def 100644 --- a/test/src/math/test_subgroups.c +++ b/test/src/math/test_subgroups.c @@ -13,9 +13,15 @@ Test(subgroups, test_prime_factors) { curve_t curve = {.order = stoi(12)}; config_t cfg = {.prime = false}; GEN divs = subgroups_prime(&curve, &cfg); - GEN vec = gtocol0(gen_0, 2); - gel(vec, 1) = stoi(2); - gel(vec, 2) = stoi(3); + GEN vec = mkvec2s(2, 3); + cr_assert(gequal(divs, vec), "Factors not equal!"); +} + +Test(subgroups, test_prime_factors_other) { + curve_t curve = {.order = stoi(27)}; + config_t cfg = {.prime = false}; + GEN divs = subgroups_prime(&curve, &cfg); + GEN vec = gtovec(stoi(3)); cr_assert(gequal(divs, vec), "Factors not equal!"); } @@ -23,6 +29,25 @@ Test(subgroups, test_prime_prime) { curve_t curve = {.order = stoi(5)}; config_t cfg = {.prime = true}; GEN divs = subgroups_prime(&curve, &cfg); - GEN vec = gtocol(stoi(5)); + GEN vec = gtovec(stoi(5)); cr_assert(gequal(divs, vec), "Factors not equal!"); -}
\ No newline at end of file +} + +Test(subgroups, test_nonprime_factors) { + // curve = ellinit([1, 3], 23), order = 27 + curve_t curve = {.order = stoi(27), .ngens = 1}; + config_t cfg = {.prime = false}; + GEN divs = subgroups_nonprime(&curve, &cfg); + GEN vec = mkvec2s(9, 27); + cr_assert(gequal(divs, vec), + "Factors not equal!"); +} + +Test(subgroups, test_all_factors) { + // curve = ellinit([1, 3], 23), order = 27 + curve_t curve = {.order = stoi(27), .ngens = 1}; + config_t cfg = {.prime = false}; + GEN divs = subgroups_all(&curve, &cfg); + GEN vec = mkvec3s(3, 9, 27); + cr_assert(gequal(divs, vec), "Factors not equal!"); +} |
