aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-08-30 00:11:18 +0200
committerJ08nY2017-08-30 00:11:18 +0200
commite14198f1feaf82cf6d803ab51d440afa8eee4cdd (patch)
treee3e320dce027be9b0934b5a5bb9c00ee250462ba
parentdad32a97eb61ddb4c9cbbb6b87d26de25f966b91 (diff)
downloadecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.tar.gz
ecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.tar.zst
ecgen-e14198f1feaf82cf6d803ab51d440afa8eee4cdd.zip
-rw-r--r--src/math/subgroups.c63
-rw-r--r--test/src/math/test_subgroups.c35
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!");
+}