aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-04-09 18:19:25 +0200
committerJ08nY2017-04-09 18:19:25 +0200
commit1834586a6850f3c93107271a0351accde78981fd (patch)
tree30a7b83ef6e289dda3beede9d5d5a8a3aac197c2
parent2c9a14b7323749af884279a564dabd710e089dcc (diff)
downloadecgen-1834586a6850f3c93107271a0351accde78981fd.tar.gz
ecgen-1834586a6850f3c93107271a0351accde78981fd.tar.zst
ecgen-1834586a6850f3c93107271a0351accde78981fd.zip
-rw-r--r--CMakeLists.txt4
-rw-r--r--Makefile1
-rw-r--r--src/Makefile4
-rw-r--r--src/cm/cm.h6
-rw-r--r--src/exhaustive/exhaustive.c11
-rw-r--r--src/exhaustive/exhaustive.h10
-rw-r--r--src/exhaustive/seed.c29
-rw-r--r--src/exhaustive/seed.h30
-rw-r--r--src/invalid/invalid.c143
-rw-r--r--src/invalid/invalid.h6
-rw-r--r--src/invalid/invalid_thread.c106
-rw-r--r--src/invalid/invalid_thread.h38
-rw-r--r--src/io/cli.c61
-rw-r--r--src/io/config.h5
-rw-r--r--src/io/input.c12
-rw-r--r--src/io/input.h8
-rw-r--r--src/io/output.c22
-rw-r--r--src/io/output.h20
-rw-r--r--src/math/arg.c2
-rw-r--r--src/math/arg.h2
-rw-r--r--src/math/curve.c68
-rw-r--r--src/math/curve.h32
-rw-r--r--src/math/equation.c25
-rw-r--r--src/math/equation.h24
-rw-r--r--src/math/field.c13
-rw-r--r--src/math/field.h6
-rw-r--r--src/math/gens.c4
-rw-r--r--src/math/gens.h4
-rw-r--r--src/math/order.c13
-rw-r--r--src/math/order.h6
-rw-r--r--src/math/point.c57
-rw-r--r--src/math/point.h57
-rw-r--r--src/math/poly.c8
-rw-r--r--src/math/poly.h8
-rw-r--r--src/math/random.c4
-rw-r--r--src/math/random.h4
-rw-r--r--src/math/types.c2
-rw-r--r--src/math/types.h8
38 files changed, 659 insertions, 204 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 49aa27e..7d8f8dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.8.11)
project(ecgen)
set(CMAKE_LIBRARY_PATH ${CMAKE_SOURCE_DIR}/lib)
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -Wall -Werror -pedantic")
-SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Wall")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG -g -Wall -Werror -pedantic")
+SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG -O3 -Wall")
include_directories(src)
include_directories(lib)
diff --git a/Makefile b/Makefile
index b35ff7c..2f6e899 100644
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,7 @@ clean:
clean-all:
+$(MAKE) -C lib clean
+$(MAKE) -C src clean-all
+ rm -rf doc/*
docs:
doxygen Doxyfile
diff --git a/src/Makefile b/src/Makefile
index 427d17f..8073387 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -10,7 +10,7 @@ CC ?= gcc
CFLAGS = -Wall
DEBUG ?= 1
ifeq (DEBUG, 1)
- CFLAGS += -g -DDEBUG
+ CFLAGS += -g -DDEBUG -v
else
CFLAGS += -O3 -DNDEBUG
endif
@@ -26,7 +26,7 @@ VPATH = cm:invalid:io:exhaustive:math
ECGEN_SRC = ecgen.c $(wildcard */*.c)
ECGEN_OBJ = $(patsubst %.c,%.o, $(ECGEN_SRC))
-ECONVERT_SRC = econvert.c $(wildcard */*.c)
+ECONVERT_SRC = econvert.c
ECONVERT_OBJ = $(patsubst %.c,%.o, $(ECONVERT_SRC))
SRC = $(wildcard *.c) $(wildcard */*.c)
diff --git a/src/cm/cm.h b/src/cm/cm.h
index 29632fc..546c0d5 100644
--- a/src/cm/cm.h
+++ b/src/cm/cm.h
@@ -5,12 +5,12 @@
/**
* @file cm.h
*/
-#include "io/cli.h"
-#include "io/config.h"
-
#ifndef ECGEN_CM_H
#define ECGEN_CM_H
+#include "io/cli.h"
+#include "io/config.h"
+
/**
*
* @param cfg
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 7b3806e..e76b4a1 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -3,8 +3,6 @@
* Copyright (C) 2017 J08nY
*/
#include "exhaustive.h"
-#include <math/types.h>
-#include "io/config.h"
#include "io/output.h"
#include "math/arg.h"
#include "math/curve.h"
@@ -101,8 +99,9 @@ static void exhaustive_ainit(arg_t **argss, config_t *cfg) {
}
}
-int exhaustive_gen_retry(curve_t *curve, config_t *cfg, gen_t generators[],
- arg_t *argss[], int start_offset, int end_offset,
+int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
+ gen_t generators[], arg_t *argss[],
+ offset_e start_offset, offset_e end_offset,
int retry) {
if (start_offset == end_offset) {
return 1;
@@ -167,8 +166,8 @@ int exhaustive_gen_retry(curve_t *curve, config_t *cfg, gen_t generators[],
return 1;
}
-int exhaustive_gen(curve_t *curve, config_t *cfg, gen_t generators[],
- arg_t *argss[], int start_offset, int end_offset) {
+int exhaustive_gen(curve_t *curve, const config_t *cfg, gen_t generators[],
+ arg_t *argss[], offset_e start_offset, offset_e end_offset) {
return exhaustive_gen_retry(curve, cfg, generators, argss, start_offset,
end_offset, 0);
}
diff --git a/src/exhaustive/exhaustive.h b/src/exhaustive/exhaustive.h
index 76e8000..934133f 100644
--- a/src/exhaustive/exhaustive.h
+++ b/src/exhaustive/exhaustive.h
@@ -21,9 +21,9 @@
* @param retry
* @return
*/
-int exhaustive_gen_retry(curve_t *curve, config_t *cfg, gen_t generators[],
- arg_t *argss[], int start_offset, int end_offset,
- int retry);
+int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
+ gen_t generators[], arg_t *argss[],
+ offset_e start_offset, offset_e end_offset, int retry);
/**
*
@@ -35,8 +35,8 @@ int exhaustive_gen_retry(curve_t *curve, config_t *cfg, gen_t generators[],
* @param end_offset
* @return
*/
-int exhaustive_gen(curve_t *curve, config_t *cfg, gen_t generators[],
- arg_t *argss[], int start_offset, int end_offset);
+int exhaustive_gen(curve_t *curve, const config_t *cfg, gen_t generators[],
+ arg_t *argss[], offset_e start_offset, offset_e end_offset);
/**
*
diff --git a/src/exhaustive/seed.c b/src/exhaustive/seed.c
index 1a2a731..bd6f274 100644
--- a/src/exhaustive/seed.c
+++ b/src/exhaustive/seed.c
@@ -3,7 +3,6 @@
* Copyright (C) 2017 J08nY
*/
#include "seed.h"
-#include "io/config.h"
#include "io/input.h"
seed_t *seed_new(void) {
@@ -16,13 +15,31 @@ seed_t *seed_new(void) {
return seed;
}
-seed_t *seed_copy(seed_t *src, seed_t *dest) {
- dest->seed = gcopy(src->seed);
+seed_t *seed_copy(const seed_t *src, seed_t *dest) {
+ if (src->seed) dest->seed = gcopy(src->seed);
return dest;
}
+seed_t *seed_new_copy(const seed_t *src) {
+ seed_t *result = seed_new();
+ return seed_copy(src, result);
+}
+
+seed_t *seed_clone(const seed_t *src, seed_t *dest) {
+ if (src->seed) dest->seed = gclone(src->seed);
+ return dest;
+}
+
+seed_t *seed_new_clone(const seed_t *src) {
+ seed_t *result = seed_new();
+ return seed_clone(src, result);
+}
+
void seed_free(seed_t **seed) {
if (*seed) {
+ if ((*seed)->seed && isclone((*seed)->seed)) {
+ gunclone((*seed)->seed);
+ }
pari_free(*seed);
*seed = NULL;
}
@@ -44,19 +61,19 @@ static GEN seed_stoi(const char *cstr) {
return gerepilecopy(ltop, seed);
}
-int seed_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int seed_random(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->seed = seed_new();
curve->seed->seed = random_int(160);
return 1;
}
-int seed_argument(curve_t *curve, config_t *cfg, arg_t *args) {
+int seed_argument(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->seed = seed_new();
curve->seed->seed = seed_stoi(cfg->seed);
return 1;
}
-int seed_input(curve_t *curve, config_t *cfg, arg_t *args) {
+int seed_input(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN str = input_string("seed:");
diff --git a/src/exhaustive/seed.h b/src/exhaustive/seed.h
index 067ee9e..d4236ce 100644
--- a/src/exhaustive/seed.h
+++ b/src/exhaustive/seed.h
@@ -23,7 +23,29 @@ seed_t *seed_new(void);
* @param dest
* @return
*/
-seed_t *seed_copy(seed_t *src, seed_t *dest);
+seed_t *seed_copy(const seed_t *src, seed_t *dest);
+
+/**
+ *
+ * @param src
+ * @return
+ */
+seed_t *seed_new_copy(const seed_t *src);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+seed_t *seed_clone(const seed_t *src, seed_t *dest);
+
+/**
+ *
+ * @param src
+ * @return
+ */
+seed_t *seed_new_clone(const seed_t *src);
/**
*
@@ -38,7 +60,7 @@ void seed_free(seed_t **seed);
* @param args
* @return
*/
-int seed_random(curve_t *curve, config_t *cfg, arg_t *args);
+int seed_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
*
@@ -47,7 +69,7 @@ int seed_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int seed_argument(curve_t *curve, config_t *cfg, arg_t *args);
+int seed_argument(curve_t *curve, const config_t *cfg, arg_t *args);
/**
*
@@ -56,6 +78,6 @@ int seed_argument(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int seed_input(curve_t *curve, config_t *cfg, arg_t *args);
+int seed_input(curve_t *curve, const config_t *cfg, arg_t *args);
#endif // ECGEN_SEED_H
diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c
index b495958..1dd4fee 100644
--- a/src/invalid/invalid.c
+++ b/src/invalid/invalid.c
@@ -4,6 +4,7 @@
*/
#include "invalid.h"
#include "exhaustive/exhaustive.h"
+#include "invalid_thread.h"
#include "io/output.h"
#include "math/curve.h"
#include "math/equation.h"
@@ -12,7 +13,7 @@
#include "math/order.h"
#include "math/point.h"
-static void invalid_ginit(gen_t *generators, config_t *cfg) {
+static void invalid_original_ginit(gen_t *generators, const config_t *cfg) {
generators[OFFSET_SEED] = &gen_skip;
if (cfg->random) {
generators[OFFSET_FIELD] = &field_random;
@@ -28,6 +29,20 @@ static void invalid_ginit(gen_t *generators, config_t *cfg) {
generators[OFFSET_ORDER] = &order_any;
}
+static void invalid_invalid_ginit(gen_t *generators, const config_t *cfg) {
+ generators[OFFSET_FIELD] = &gen_skip;
+ generators[OFFSET_A] = &gen_skip;
+ generators[OFFSET_B] = &b_random;
+ generators[OFFSET_CURVE] = &curve_nonzero;
+ generators[OFFSET_ORDER] = &order_any;
+ if (cfg->unique) {
+ generators[OFFSET_GENERATORS] = &gens_one;
+ } else {
+ generators[OFFSET_GENERATORS] = &gens_any;
+ }
+ generators[OFFSET_POINTS] = &points_trial;
+}
+
static size_t invalid_primes(GEN order, pari_ulong **primes) {
pari_sp ltop = avma;
@@ -71,30 +86,10 @@ static size_t invalid_primes(GEN order, pari_ulong **primes) {
}
static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
- size_t nprimes, curve_t ***curves) {
- gen_t invalid_gen[OFFSET_END];
- invalid_gen[OFFSET_FIELD] = &gen_skip;
- invalid_gen[OFFSET_A] = &gen_skip;
- invalid_gen[OFFSET_B] = &b_random;
- invalid_gen[OFFSET_CURVE] = &curve_nonzero;
- invalid_gen[OFFSET_ORDER] = &order_any;
- if (cfg->unique) {
- invalid_gen[OFFSET_GENERATORS] = &gens_one;
- } else {
- invalid_gen[OFFSET_GENERATORS] = &gens_any;
- }
- invalid_gen[OFFSET_POINTS] = &points_trial;
-
+ size_t nprimes, curve_t **curves,
+ gen_t invalid_gen[OFFSET_END]) {
arg_t *invalid_argss[OFFSET_END];
- // We will have nprimes curves in the end
- *curves = pari_malloc(nprimes * sizeof(curve_t *));
- if (!(*curves)) {
- perror("Couldn't malloc.");
- return 0;
- }
- memset(*curves, 0, nprimes * sizeof(curve_t *));
-
// Alloc a curve, and only alloc a new one when this pointer is saved into
// **curves
curve_t *invalid = curve_new();
@@ -113,7 +108,7 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
// if so how many?
size_t total = 0;
for (size_t i = nprimes; i-- > 0;) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
// whoo we have a new invalid curve
if (!total && cfg->verbose) {
fprintf(
@@ -132,7 +127,7 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
size_t j = 0;
pari_ulong dprimes[total];
for (size_t i = 0; i < nprimes; ++i) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
if (cfg->verbose) {
fprintf(debug, "prime %lu divides curve order.\n",
primes[i]);
@@ -150,16 +145,15 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
size_t count = 0;
for (size_t i = nprimes; i-- > 0;) {
- if ((*curves)[i] == NULL && dvdis(invalid->order, primes[i])) {
+ if (curves[i] == NULL && dvdis(invalid->order, primes[i])) {
if (count == 0) {
// save a copy on first prime divisor from range
- (*curves)[i] = invalid;
+ curves[i] = invalid;
} else {
// copy if pointer already assigned
- (*curves)[i] = curve_new();
- (*curves)[i] = curve_copy(invalid, (*curves)[i]);
+ curves[i] = curve_new_copy(invalid);
}
- output_o((*curves)[i], cfg);
+ output_o(curves[i], cfg);
ncurves++;
count++;
}
@@ -194,14 +188,71 @@ static size_t invalid_curves(curve_t *curve, config_t *cfg, pari_ulong *primes,
return ncurves;
}
+static size_t invalid_curves_threaded(curve_t *curve, config_t *cfg,
+ pari_ulong *primes, size_t nprimes,
+ curve_t **curves,
+ gen_t invalid_gen[OFFSET_END]) {
+ pthread_t pthreads[cfg->threads];
+ thread_t threads[cfg->threads];
+ struct pari_thread pari_threads[cfg->threads];
+ pari_thread_sync();
+
+ size_t generated = 0;
+ state_e states[nprimes];
+ curve_t *local_curves[nprimes];
+ for (size_t i = 0; i < nprimes; ++i) {
+ states[i] = STATE_FREE;
+ }
+ pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_t curves_mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t generated_cond = PTHREAD_COND_INITIALIZER;
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ threads[i].original_curve = curve;
+ threads[i].nprimes = nprimes;
+ threads[i].primes = primes;
+ threads[i].states = states;
+ threads[i].curves = local_curves;
+ threads[i].generated = &generated;
+ threads[i].mutex_state = &state_mutex;
+ threads[i].mutex_curves = &curves_mutex;
+ threads[i].cond_generated = &generated_cond;
+ threads[i].cfg = cfg;
+ threads[i].gens = invalid_gen;
+
+ pari_thread_alloc(&pari_threads[i], cfg->thread_memory,
+ (GEN)&threads[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pthread_create(&pthreads[i], NULL, &invalid_thread,
+ (void *)&pari_threads[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pthread_join(pthreads[i], NULL);
+ }
+
+ for (size_t i = 0; i < nprimes; ++i) {
+ curves[i] = curve_new_copy(local_curves[i]);
+ curve_free(&local_curves[i]);
+ }
+
+ for (size_t i = 0; i < cfg->threads; ++i) {
+ pari_thread_free(&pari_threads[i]);
+ }
+
+ return generated;
+}
+
int invalid_do(config_t *cfg) {
- // create the curve to invalidate
- // Either from input or random with -r
- curve_t *curve = curve_new();
gen_t gen[OFFSET_END];
arg_t *argss[OFFSET_END];
- invalid_ginit(gen, cfg);
+ invalid_original_ginit(gen, cfg);
+ // create the curve to invalidate
+ // Either from input or random with -
+ curve_t *curve = curve_new();
// actually generate the curve
if (!exhaustive_gen_retry(curve, cfg, gen, argss, OFFSET_FIELD,
OFFSET_POINTS, 1)) {
@@ -213,14 +264,32 @@ int invalid_do(config_t *cfg) {
// now, generate primes upto order^2
pari_ulong *primes;
size_t nprimes = invalid_primes(curve->order, &primes);
-
if (cfg->verbose) {
fprintf(debug, "primes upto: p_max = %lu, n = %lu\n",
primes[nprimes - 1], nprimes);
}
- curve_t **curves;
- size_t ncurves = invalid_curves(curve, cfg, primes, nprimes, &curves);
+ // Alloc enough curves
+ curve_t **curves = pari_malloc(nprimes * sizeof(curve_t *));
+ if (!(curves)) {
+ perror("Couldn't malloc.");
+ return 0;
+ }
+ memset(curves, 0, nprimes * sizeof(curve_t *));
+
+ // init the invalid curve gen_t
+ gen_t invalid_gen[OFFSET_END];
+ invalid_invalid_ginit(invalid_gen, cfg);
+
+ // now, generate the invalid curves for all primes
+ size_t ncurves;
+ if (cfg->threads == 1) {
+ ncurves =
+ invalid_curves(curve, cfg, primes, nprimes, curves, invalid_gen);
+ } else {
+ ncurves = invalid_curves_threaded(curve, cfg, primes, nprimes, curves,
+ invalid_gen);
+ }
for (size_t i = 0; i < ncurves; ++i) {
curve_free(&curves[i]);
diff --git a/src/invalid/invalid.h b/src/invalid/invalid.h
index e98f6e4..43de25a 100644
--- a/src/invalid/invalid.h
+++ b/src/invalid/invalid.h
@@ -5,12 +5,12 @@
/**
* @file invalid.h
*/
-#include "io/cli.h"
-#include "io/config.h"
-
#ifndef ECGEN_INVALID_H
#define ECGEN_INVALID_H
+#include "io/cli.h"
+#include "io/config.h"
+
/**
*
* @param cfg
diff --git a/src/invalid/invalid_thread.c b/src/invalid/invalid_thread.c
new file mode 100644
index 0000000..40b52ec
--- /dev/null
+++ b/src/invalid/invalid_thread.c
@@ -0,0 +1,106 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+
+#include "invalid_thread.h"
+#include "exhaustive/exhaustive.h"
+#include "io/output.h"
+#include "math/curve.h"
+#include "math/random.h"
+
+void *invalid_thread(void *arg) {
+ struct pari_thread *pthread = (struct pari_thread *)arg;
+ // TODO: This is dodgy ... as its really a GEN (so a long*)
+ thread_t *thread = (thread_t *)pari_thread_start(pthread);
+ random_init();
+ arg_t *invalid_argss[OFFSET_END];
+
+ curve_t *invalid = curve_new();
+ invalid->field = gcopy(thread->original_curve->field);
+ invalid->a = gcopy(thread->original_curve->a);
+
+ while (*thread->generated < thread->nprimes) {
+ pari_sp btop = avma;
+ exhaustive_gen(invalid, thread->cfg, thread->gens, NULL, OFFSET_B,
+ OFFSET_GENERATORS);
+ size_t ndivides = 0;
+ for (size_t i = thread->nprimes; i-- > 0;) {
+ if (dvdis(invalid->order, thread->primes[i])) {
+ // whoo we have a new invalid curve
+ ndivides++;
+ }
+ }
+#ifdef DEBUG
+ printf("ndivides = %lu\n", ndivides);
+#endif
+ if (ndivides > 0) {
+ pthread_mutex_lock(thread->mutex_state);
+ size_t nfree = 0;
+ // can be up to ndivides, but also lower...
+ pari_ulong primes[ndivides];
+ size_t nprimes = 0;
+ for (size_t i = thread->nprimes; i-- > 0;) {
+ if (dvdis(invalid->order, thread->primes[i]) &&
+ thread->states[i] == STATE_FREE) {
+ thread->states[i] = STATE_GENERATING;
+ primes[nprimes++] = thread->primes[i];
+ nfree++;
+ }
+ }
+#ifdef DEBUG
+ printf("nfree = %lu\n", nfree);
+#endif
+ pthread_mutex_unlock(thread->mutex_state);
+
+ if (nfree > 0) {
+ arg_t prime_divisors = {primes, nprimes};
+ invalid_argss[OFFSET_POINTS] = &prime_divisors;
+ exhaustive_gen(invalid, thread->cfg, thread->gens,
+ invalid_argss, OFFSET_GENERATORS, OFFSET_END);
+
+ pthread_mutex_lock(thread->mutex_curves);
+ pthread_mutex_lock(thread->mutex_state);
+ size_t count = 0;
+ for (size_t i = thread->nprimes; i-- > 0;) {
+ if (count < nprimes && primes[count] == thread->primes[i]) {
+#ifdef DEBUG
+ printf("[i] = %lu, prime = %lu\n", i, primes[count]);
+ printf("state = %i\n", thread->states[i]);
+#endif
+ thread->states[i] = STATE_GENERATED;
+ thread->curves[i] = curve_new_copy(invalid);
+
+ output_o(thread->curves[i], thread->cfg);
+ count++;
+ }
+ }
+#ifdef DEBUG
+ printf("count = %lu, generated = %lu\n", count,
+ *(thread->generated));
+#endif
+ *(thread->generated) += count;
+#ifdef DEBUG
+ printf("generated = %lu\n", *(thread->generated));
+#endif
+ // pthread_cond_signal(thread->cond_generated);
+ pthread_mutex_unlock(thread->mutex_state);
+ pthread_mutex_unlock(thread->mutex_curves);
+
+ invalid = curve_new();
+ invalid->field = gcopy(thread->original_curve->field);
+ invalid->a = gcopy(thread->original_curve->a);
+ } else {
+ obj_free(invalid->curve); // necessary to free the ellinit
+ avma = btop;
+ }
+ } else {
+ obj_free(invalid->curve); // necessary to free the ellinit
+ avma = btop;
+ }
+ }
+ curve_free(&invalid);
+
+ pari_thread_close();
+ return NULL;
+} \ No newline at end of file
diff --git a/src/invalid/invalid_thread.h b/src/invalid/invalid_thread.h
new file mode 100644
index 0000000..1ee4cf7
--- /dev/null
+++ b/src/invalid/invalid_thread.h
@@ -0,0 +1,38 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+/**
+ * @file invalid_thread.h
+ */
+#ifndef ECGEN_INVALID_THREAD_H
+#define ECGEN_INVALID_THREAD_H
+
+#include <pari/pari.h>
+#include <pthread.h>
+#include "math/types.h"
+
+typedef enum { STATE_FREE, STATE_GENERATING, STATE_GENERATED } state_e;
+
+typedef struct {
+ curve_t *original_curve;
+ size_t nprimes;
+ pari_ulong *primes;
+ state_e *states;
+ curve_t **curves;
+ size_t *generated;
+ pthread_mutex_t *mutex_state;
+ pthread_mutex_t *mutex_curves;
+ pthread_cond_t *cond_generated;
+ config_t *cfg;
+ gen_t *gens;
+} thread_t;
+
+/**
+ *
+ * @param arg
+ * @return
+ */
+void *invalid_thread(void *arg);
+
+#endif // ECGEN_INVALID_THREAD_H
diff --git a/src/io/cli.c b/src/io/cli.c
index 3c74c1e..060bf20 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -4,6 +4,8 @@
*/
#include "cli.h"
#include <string.h>
+#include <unistd.h>
+#include "config.h"
#include "io/config.h"
char doc[] =
@@ -30,7 +32,9 @@ enum opt_keys {
OPT_MEMORY = 'm',
OPT_FP = 1,
OPT_F2M,
- OPT_POINTS
+ OPT_POINTS,
+ OPT_THREADS,
+ OPT_TSTACK
};
// clang-format off
@@ -58,10 +62,27 @@ struct argp_option options[] = {
{0, 0, 0, 0, "Other:", 4},
{"data-dir", OPT_DATADIR, "DIR", 0, "Set PARI/GP data directory (containing seadata package).", 4},
{"memory", OPT_MEMORY, "SIZE", 0, "Use PARI stack of SIZE (can have suffix k/m/g).", 4},
+ {"threads", OPT_THREADS, "NUM", 0, "Use NUM threads.", 4},
+ {"thread-stack",OPT_TSTACK,"SIZE", 0, "Use PARI stack of SIZE (per thread, can have suffix k/m/g).", 4},
{0}
};
// clang-format on
+static unsigned long cli_parse_memory(const char *str) {
+ char *suffix = NULL;
+ unsigned long read = strtoul(str, &suffix, 10);
+ if (suffix) {
+ if (*suffix == 'k' || *suffix == 'K') {
+ read *= 1000;
+ } else if (*suffix == 'm' || *suffix == 'M') {
+ read *= 1000000;
+ } else if (*suffix == 'g' || *suffix == 'G') {
+ read *= 1000000000;
+ }
+ }
+ return read;
+}
+
error_t cli_parse(int key, char *arg, struct argp_state *state) {
config_t *cfg = state->input;
@@ -71,18 +92,28 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
break;
case OPT_MEMORY:
if (arg) {
- char *suffix = NULL;
- unsigned long read = strtoul(arg, &suffix, 10);
- if (suffix) {
- if (*suffix == 'k' || *suffix == 'K') {
- read *= 1000;
- } else if (*suffix == 'm' || *suffix == 'M') {
- read *= 1000000;
- } else if (*suffix == 'g' || *suffix == 'G') {
- read *= 1000000000;
+ cfg->memory = cli_parse_memory(arg);
+ }
+ break;
+ case OPT_TSTACK:
+ if (arg) {
+ cfg->thread_memory = cli_parse_memory(arg);
+ }
+ break;
+ case OPT_THREADS:
+ if (arg) {
+ if (!strcmp(arg, "auto") || !strcmp(arg, "AUTO")) {
+ long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+ if (nprocs > 0) {
+ cfg->threads = (unsigned long)nprocs;
+ }
+ } else {
+ cfg->threads = strtoul(arg, NULL, 10);
+ if (!cfg->threads) {
+ argp_failure(state, 1, 0,
+ "Invalid number of threads specified.");
}
}
- cfg->memory = read;
}
case OPT_COUNT:
if (arg) {
@@ -191,7 +222,7 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
argp_usage(state);
}
- cfg->bits = strtol(arg, NULL, 10);
+ cfg->bits = strtoul(arg, NULL, 10);
break;
case ARGP_KEY_END:
// validate all option states here.
@@ -224,6 +255,12 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
if (!cfg->memory) {
cfg->memory = 1000000000;
}
+ if (!cfg->threads) {
+ cfg->threads = 1;
+ }
+ if (!cfg->thread_memory) {
+ cfg->thread_memory = cfg->bits * 2000000;
+ }
break;
case ARGP_KEY_NO_ARGS:
argp_usage(state);
diff --git a/src/io/config.h b/src/io/config.h
index 8e9dc02..77d59b7 100644
--- a/src/io/config.h
+++ b/src/io/config.h
@@ -40,6 +40,9 @@ typedef struct {
char *datadir;
unsigned long memory;
+ unsigned long threads;
+ unsigned long thread_memory;
+
enum format_e format;
char *output;
char *input;
@@ -48,7 +51,7 @@ typedef struct {
long verbose;
char *debug;
- long bits;
+ unsigned long bits;
} config_t;
diff --git a/src/io/input.c b/src/io/input.c
index 2d5a1e9..ead0bf2 100644
--- a/src/io/input.c
+++ b/src/io/input.c
@@ -10,7 +10,7 @@
FILE *in;
int delim;
-static GEN input_i(const char *prompt, long bits) {
+static GEN input_i(const char *prompt, unsigned long bits) {
if (prompt && in == stdin) {
fprintf(out, "%s ", prompt);
}
@@ -59,7 +59,7 @@ static GEN input_i(const char *prompt, long bits) {
}
}
-GEN input_prime(const char *prompt, long bits) {
+GEN input_prime(const char *prompt, unsigned long bits) {
GEN read = input_i(prompt, bits);
if (equalii(read, gen_m1)) {
return read;
@@ -73,7 +73,9 @@ GEN input_prime(const char *prompt, long bits) {
}
}
-GEN input_int(const char *prompt, long bits) { return input_i(prompt, bits); }
+GEN input_int(const char *prompt, unsigned long bits) {
+ return input_i(prompt, bits);
+}
GEN input_short(const char *prompt) { return input_i(prompt, 16); }
@@ -96,7 +98,7 @@ GEN input_string(const char *prompt) {
return result;
}
-GEN input_param(param_t param, const char *prompt, long bits) {
+GEN input_param(param_t param, const char *prompt, unsigned long bits) {
switch (param) {
case PARAM_PRIME:
return input_prime(prompt, bits);
@@ -110,7 +112,7 @@ GEN input_param(param_t param, const char *prompt, long bits) {
return gen_m1;
}
-void input_init(config_t *cfg) {
+void input_init(const config_t *cfg) {
json_set_allocation_functions(pari_malloc, pari_free);
if (cfg->input) {
diff --git a/src/io/input.h b/src/io/input.h
index 3be68fc..579af3c 100644
--- a/src/io/input.h
+++ b/src/io/input.h
@@ -24,7 +24,7 @@ typedef enum PARAM {
* @param bits
* @return
*/
-GEN input_prime(const char *prompt, long bits);
+GEN input_prime(const char *prompt, unsigned long bits);
/**
*
@@ -32,7 +32,7 @@ GEN input_prime(const char *prompt, long bits);
* @param bits
* @return
*/
-GEN input_int(const char *prompt, long bits);
+GEN input_int(const char *prompt, unsigned long bits);
/**
*
@@ -55,7 +55,7 @@ GEN input_string(const char *prompt);
* @param bits
* @return
*/
-GEN input_param(param_t param, const char *prompt, long bits);
+GEN input_param(param_t param, const char *prompt, unsigned long bits);
/**
*
@@ -66,7 +66,7 @@ extern FILE *in;
*
* @param cfg
*/
-void input_init(config_t *cfg);
+void input_init(const config_t *cfg);
/**
*
diff --git a/src/io/output.c b/src/io/output.c
index 023bc0f..1e1402d 100644
--- a/src/io/output.c
+++ b/src/io/output.c
@@ -11,7 +11,7 @@
FILE *out;
FILE *debug;
-char *output_scsv(curve_t *curve, config_t *cfg) {
+char *output_scsv(curve_t *curve, const config_t *cfg) {
pari_sp ltop = avma;
GEN vector = curve_params(curve);
@@ -48,15 +48,18 @@ char *output_scsv(curve_t *curve, config_t *cfg) {
return result;
}
-void output_fcsv(FILE *out, curve_t *curve, config_t *cfg) {
+void output_fcsv(FILE *out, curve_t *curve, const config_t *cfg) {
char *string = output_scsv(curve, cfg);
fprintf(out, "%s\n", string);
+ fflush(out);
free(string);
}
-void output_csv(curve_t *curve, config_t *cfg) { output_fcsv(out, curve, cfg); }
+void output_csv(curve_t *curve, const config_t *cfg) {
+ output_fcsv(out, curve, cfg);
+}
-static JSON_Value *output_jjson(curve_t *curve, config_t *cfg) {
+static JSON_Value *output_jjson(curve_t *curve, const config_t *cfg) {
pari_sp ltop = avma;
// root object/value is curve
JSON_Value *root_value = json_value_init_object();
@@ -99,7 +102,7 @@ static JSON_Value *output_jjson(curve_t *curve, config_t *cfg) {
char *order = pari_sprintf("%P#x", curve->order);
json_object_set_string(root_object, "order", order);
pari_free(order);
- if (curve->generators) {
+ if (curve->ngens) {
JSON_Value *gens_value = json_value_init_array();
JSON_Array *gens_array = json_value_get_array(gens_value);
@@ -166,7 +169,7 @@ static JSON_Value *output_jjson(curve_t *curve, config_t *cfg) {
return root_value;
}
-char *output_sjson(curve_t *curve, config_t *cfg) {
+char *output_sjson(curve_t *curve, const config_t *cfg) {
JSON_Value *root_value = output_jjson(curve, cfg);
char *result = json_serialize_to_string_pretty(root_value);
json_value_free(root_value);
@@ -174,17 +177,18 @@ char *output_sjson(curve_t *curve, config_t *cfg) {
return result;
}
-void output_fjson(FILE *out, curve_t *curve, config_t *cfg) {
+void output_fjson(FILE *out, curve_t *curve, const config_t *cfg) {
char *s = output_sjson(curve, cfg);
fprintf(out, "%s\n", s);
+ fflush(out);
json_free_serialized_string(s);
}
-void output_json(curve_t *curve, config_t *cfg) {
+void output_json(curve_t *curve, const config_t *cfg) {
output_fjson(out, curve, cfg);
}
-void output_init(config_t *cfg) {
+void output_init(const config_t *cfg) {
json_set_allocation_functions(pari_malloc, pari_free);
if (cfg->output) {
diff --git a/src/io/output.h b/src/io/output.h
index 283b701..604498a 100644
--- a/src/io/output.h
+++ b/src/io/output.h
@@ -18,7 +18,7 @@
* @param config
* @return
*/
-char *output_scsv(curve_t *curve, config_t *cfg);
+char *output_scsv(curve_t *curve, const config_t *cfg);
/**
*
@@ -26,14 +26,14 @@ char *output_scsv(curve_t *curve, config_t *cfg);
* @param curve
* @param config
*/
-void output_fcsv(FILE *out, curve_t *curve, config_t *cfg);
+void output_fcsv(FILE *out, curve_t *curve, const config_t *cfg);
/**
*
* @param curve
* @param config
*/
-void output_csv(curve_t *curve, config_t *cfg);
+void output_csv(curve_t *curve, const config_t *cfg);
/**
*
@@ -41,7 +41,7 @@ void output_csv(curve_t *curve, config_t *cfg);
* @param config
* @return
*/
-char *output_sjson(curve_t *curve, config_t *cfg);
+char *output_sjson(curve_t *curve, const config_t *cfg);
/**
*
@@ -49,14 +49,14 @@ char *output_sjson(curve_t *curve, config_t *cfg);
* @param curve
* @param config
*/
-void output_fjson(FILE *out, curve_t *curve, config_t *cfg);
+void output_fjson(FILE *out, curve_t *curve, const config_t *cfg);
/**
*
* @param curve
* @param config
*/
-void output_json(curve_t *curve, config_t *cfg);
+void output_json(curve_t *curve, const config_t *cfg);
/**
*
@@ -64,7 +64,7 @@ void output_json(curve_t *curve, config_t *cfg);
* @param config
* @return
*/
-char *(*output_s)(curve_t *curve, config_t *cfg);
+char *(*output_s)(curve_t *curve, const config_t *cfg);
/**
*
@@ -72,14 +72,14 @@ char *(*output_s)(curve_t *curve, config_t *cfg);
* @param curve
* @param config
*/
-void (*output_f)(FILE *out, curve_t *curve, config_t *cfg);
+void (*output_f)(FILE *out, curve_t *curve, const config_t *cfg);
/**
*
* @param curve
* @param config
*/
-void (*output_o)(curve_t *curve, config_t *cfg);
+void (*output_o)(curve_t *curve, const config_t *cfg);
/**
*
@@ -95,7 +95,7 @@ extern FILE *debug;
*
* @param cfg
*/
-void output_init(config_t *cfg);
+void output_init(const config_t *cfg);
/**
*
diff --git a/src/math/arg.c b/src/math/arg.c
index 991eebb..e313adb 100644
--- a/src/math/arg.c
+++ b/src/math/arg.c
@@ -4,7 +4,7 @@
*/
#include "arg.h"
-arg_t *arg_new() {
+arg_t *arg_new(void) {
arg_t *arg = pari_malloc(sizeof(arg_t));
if (!arg) {
perror("Couldn't malloc.");
diff --git a/src/math/arg.h b/src/math/arg.h
index a7859dd..c0f2f6f 100644
--- a/src/math/arg.h
+++ b/src/math/arg.h
@@ -14,7 +14,7 @@
* @brief
* @return
*/
-arg_t *arg_new();
+arg_t *arg_new(void);
/**
* @brief
diff --git a/src/math/curve.c b/src/math/curve.c
index 7b74556..0d4cd12 100644
--- a/src/math/curve.c
+++ b/src/math/curve.c
@@ -18,7 +18,7 @@ curve_t *curve_new(void) {
return curve;
}
-curve_t *curve_copy(curve_t *src, curve_t *dest) {
+curve_t *curve_copy(const curve_t *src, curve_t *dest) {
if (src->seed) dest->seed = seed_copy(src->seed, dest->seed);
if (src->field) dest->field = gcopy(src->field);
if (src->a) dest->a = gcopy(src->a);
@@ -26,25 +26,69 @@ curve_t *curve_copy(curve_t *src, curve_t *dest) {
if (src->curve) dest->curve = gcopy(src->curve);
if (src->order) dest->order = gcopy(src->order);
if (src->generators) {
- dest->generators = points_new(src->ngens);
- dest->generators =
- points_copy(src->generators, dest->generators, src->ngens);
+ dest->generators = points_new_copy(src->generators, src->ngens);
dest->ngens = src->ngens;
}
if (src->points) {
- dest->points = points_new(src->npoints);
- dest->points = points_copy(src->points, dest->points, src->npoints);
+ dest->points = points_new_copy(src->points, src->npoints);
dest->npoints = src->npoints;
}
return dest;
}
+curve_t *curve_new_copy(const curve_t *src) {
+ curve_t *result = curve_new();
+ return curve_copy(src, result);
+}
+
+curve_t *curve_clone(const curve_t *src, curve_t *dest) {
+ if (src->seed) dest->seed = seed_clone(src->seed, dest->seed);
+ if (src->field) dest->field = gclone(src->field);
+ if (src->a) dest->a = gclone(src->a);
+ if (src->b) dest->b = gclone(src->b);
+ if (src->curve) dest->curve = gclone(src->curve);
+ if (src->order) dest->order = gclone(src->order);
+ if (src->generators) {
+ dest->generators = points_new_clone(src->generators, src->ngens);
+ dest->ngens = src->ngens;
+ }
+ if (src->points) {
+ dest->points = points_new_clone(src->points, src->npoints);
+ dest->npoints = src->npoints;
+ }
+ return dest;
+}
+
+curve_t *curve_new_clone(const curve_t *src) {
+ curve_t *result = curve_new();
+ return curve_clone(src, result);
+}
+
void curve_free(curve_t **curve) {
if (*curve) {
seed_free(&(*curve)->seed);
+
if ((*curve)->curve) {
+ // TODO, this is possibly dangerous...
obj_free((*curve)->curve);
+ if (isclone((*curve)->curve)) {
+ gunclone((*curve)->curve);
+ }
+ }
+
+ if ((*curve)->field && isclone((*curve)->field)) {
+ gunclone((*curve)->field);
+ }
+ if ((*curve)->a && isclone((*curve)->a)) {
+ gunclone((*curve)->a);
+ }
+ if ((*curve)->b && isclone((*curve)->b)) {
+ gunclone((*curve)->b);
}
+ if ((*curve)->order && isclone((*curve)->order)) {
+ gunclone((*curve)->order);
+ }
+
points_free_deep(&(*curve)->generators, (*curve)->ngens);
points_free_deep(&(*curve)->points, (*curve)->npoints);
pari_free(*curve);
@@ -52,7 +96,7 @@ void curve_free(curve_t **curve) {
}
}
-int curve_any(curve_t *curve, config_t *cfg, arg_t *args) {
+int curve_any(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN v = gen_0;
switch (typ(curve->field)) {
@@ -75,7 +119,7 @@ int curve_any(curve_t *curve, config_t *cfg, arg_t *args) {
return 1;
}
-int curve_nonzero(curve_t *curve, config_t *cfg, arg_t *args) {
+int curve_nonzero(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
curve_any(curve, cfg, args);
if (gequal0(ell_get_disc(curve->curve))) {
@@ -86,17 +130,17 @@ int curve_nonzero(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-static int curve_seed_fp(curve_t *curve, config_t *cfg, arg_t *args) {
+static int curve_seed_fp(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
-static int curve_seed_f2m(curve_t *curve, config_t *cfg, arg_t *args) {
+static int curve_seed_f2m(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
-int curve_seed(curve_t *curve, config_t *cfg, arg_t *args) {
+int curve_seed(curve_t *curve, const config_t *cfg, arg_t *args) {
switch (typ(curve->field)) {
case t_INT:
return curve_seed_fp(curve, cfg, args);
@@ -108,7 +152,7 @@ int curve_seed(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-GEN curve_params(curve_t *curve) {
+GEN curve_params(const curve_t *curve) {
pari_sp ltop = avma;
GEN result = field_params(curve->field);
diff --git a/src/math/curve.h b/src/math/curve.h
index 25e4f51..65dc4b7 100644
--- a/src/math/curve.h
+++ b/src/math/curve.h
@@ -22,7 +22,7 @@
* @param args unused
* @return state diff
*/
-int curve_any(curve_t *curve, config_t *cfg, arg_t *args);
+int curve_any(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -34,7 +34,7 @@ int curve_any(curve_t *curve, config_t *cfg, arg_t *args);
* @param args unused
* @return state diff
*/
-int curve_nonzero(curve_t *curve, config_t *cfg, arg_t *args);
+int curve_nonzero(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -47,7 +47,7 @@ int curve_nonzero(curve_t *curve, config_t *cfg, arg_t *args);
* @param args unused
* @return state diff
*/
-int curve_seed(curve_t *curve, config_t *cfg, arg_t *args);
+int curve_seed(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* Serializes curve parameters into a t_VEC:
@@ -59,7 +59,7 @@ int curve_seed(curve_t *curve, config_t *cfg, arg_t *args);
* @param curve to serialize
* @return a t_VEC of curve parameters
*/
-GEN curve_params(curve_t *curve);
+GEN curve_params(const curve_t *curve);
/**
* Allocates and zeros out a new curve_t object.
@@ -75,7 +75,29 @@ curve_t *curve_new(void);
* @param dest destination curve
* @return destination curve
*/
-curve_t *curve_copy(curve_t *src, curve_t *dest);
+curve_t *curve_copy(const curve_t *src, curve_t *dest);
+
+/**
+ *
+ * @param src
+ * @return
+ */
+curve_t *curve_new_copy(const curve_t *src);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+curve_t *curve_clone(const curve_t *src, curve_t *dest);
+
+/**
+ *
+ * @param src
+ * @return
+ */
+curve_t *curve_new_clone(const curve_t *src);
/**
* Free a curve_t along with it's seed_t and point_ts.
diff --git a/src/math/equation.c b/src/math/equation.c
index d60a8cd..4e2e0ec 100644
--- a/src/math/equation.c
+++ b/src/math/equation.c
@@ -3,16 +3,15 @@
* Copyright (C) 2017 J08nY
*/
#include "equation.h"
-#include "io/cli.h"
#include "io/input.h"
#include "math/field.h"
-int a_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_random(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->a = genrand(curve->field);
return 1;
}
-int a_input(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_input(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN inp = input_int("a:", cfg->bits);
if (gequalm1(inp)) {
@@ -31,7 +30,7 @@ int a_input(curve_t *curve, config_t *cfg, arg_t *args) {
static GEN a = NULL;
static curve_t *curve_a = NULL;
-int a_once(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_once(curve_t *curve, const config_t *cfg, arg_t *args) {
if (a && curve_a == curve) {
curve->a = gcopy(a);
return 1;
@@ -47,27 +46,27 @@ int a_once(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-int a_zero(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_zero(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->a = gen_0;
return 1;
}
-int a_one(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_one(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->a = gen_1;
return 1;
}
-int a_seed(curve_t *curve, config_t *cfg, arg_t *args) {
+int a_seed(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
-int b_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_random(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->b = genrand(curve->field);
return 1;
}
-int b_input(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_input(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN inp = input_int("b:", cfg->bits);
if (gequalm1(inp)) {
@@ -86,7 +85,7 @@ int b_input(curve_t *curve, config_t *cfg, arg_t *args) {
static GEN b = NULL;
static curve_t *curve_b = NULL;
-int b_once(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_once(curve_t *curve, const config_t *cfg, arg_t *args) {
if (b && curve_b == curve) {
curve->b = gcopy(b);
return 1;
@@ -102,17 +101,17 @@ int b_once(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-int b_zero(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_zero(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->b = gen_0;
return 1;
}
-int b_one(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_one(curve_t *curve, const config_t *cfg, arg_t *args) {
curve->b = gen_1;
return 1;
}
-int b_seed(curve_t *curve, config_t *cfg, arg_t *args) {
+int b_seed(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO implement
return INT_MIN;
}
diff --git a/src/math/equation.h b/src/math/equation.h
index 03d87af..1f80f21 100644
--- a/src/math/equation.h
+++ b/src/math/equation.h
@@ -22,7 +22,7 @@
* @param args
* @return state diff
*/
-int a_random(curve_t *curve, config_t *cfg, arg_t *args);
+int a_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -33,7 +33,7 @@ int a_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int a_input(curve_t *curve, config_t *cfg, arg_t *args);
+int a_input(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -44,7 +44,7 @@ int a_input(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int a_once(curve_t *curve, config_t *cfg, arg_t *args);
+int a_once(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -55,7 +55,7 @@ int a_once(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int a_zero(curve_t *curve, config_t *cfg, arg_t *args);
+int a_zero(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -66,7 +66,7 @@ int a_zero(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int a_one(curve_t *curve, config_t *cfg, arg_t *args);
+int a_one(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* @brief
@@ -75,7 +75,7 @@ int a_one(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int a_seed(curve_t *curve, config_t *cfg, arg_t *args);
+int a_seed(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -87,7 +87,7 @@ int a_seed(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int b_random(curve_t *curve, config_t *cfg, arg_t *args);
+int b_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -98,7 +98,7 @@ int b_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int b_input(curve_t *curve, config_t *cfg, arg_t *args);
+int b_input(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -109,7 +109,7 @@ int b_input(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int b_once(curve_t *curve, config_t *cfg, arg_t *args);
+int b_once(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -120,7 +120,7 @@ int b_once(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int b_zero(curve_t *curve, config_t *cfg, arg_t *args);
+int b_zero(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -131,7 +131,7 @@ int b_zero(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int b_one(curve_t *curve, config_t *cfg, arg_t *args);
+int b_one(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* @brief
@@ -140,7 +140,7 @@ int b_one(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int b_seed(curve_t *curve, config_t *cfg, arg_t *args);
+int b_seed(curve_t *curve, const config_t *cfg, arg_t *args);
/**
*
diff --git a/src/math/field.c b/src/math/field.c
index 5f7bea3..b140f77 100644
--- a/src/math/field.c
+++ b/src/math/field.c
@@ -3,15 +3,12 @@
* Copyright (C) 2017 J08nY
*/
#include "field.h"
-#include <io/cli.h>
#include "io/input.h"
#include "poly.h"
-#include "random.h"
-#include "types.h"
-static GEN field_primer(long bits) { return random_prime(bits); }
+static GEN field_primer(unsigned long bits) { return random_prime(bits); }
-static GEN field_binaryr(long bits) {
+static GEN field_binaryr(unsigned long bits) {
if (poly_exists(bits)) {
return poly_find_gen(bits);
} else {
@@ -21,7 +18,7 @@ static GEN field_binaryr(long bits) {
}
}
-int field_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int field_random(curve_t *curve, const config_t *cfg, arg_t *args) {
switch (cfg->field) {
case FIELD_PRIME:
curve->field = field_primer(cfg->bits);
@@ -34,7 +31,7 @@ int field_random(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-int field_input(curve_t *curve, config_t *cfg, arg_t *args) {
+int field_input(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
switch (cfg->field) {
case FIELD_PRIME: {
@@ -100,7 +97,7 @@ int field_input(curve_t *curve, config_t *cfg, arg_t *args) {
static GEN field = NULL;
static curve_t *curve_field = NULL;
-int field_once(curve_t *curve, config_t *cfg, arg_t *args) {
+int field_once(curve_t *curve, const config_t *cfg, arg_t *args) {
if (field && curve_field == curve) {
curve->field = gcopy(field);
return 1;
diff --git a/src/math/field.h b/src/math/field.h
index 66c8920..b1dc4f3 100644
--- a/src/math/field.h
+++ b/src/math/field.h
@@ -21,7 +21,7 @@
* @param args unused
* @return state diff
*/
-int field_random(curve_t *curve, config_t *cfg, arg_t *args);
+int field_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -34,7 +34,7 @@ int field_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args unused
* @return state diff
*/
-int field_input(curve_t *curve, config_t *cfg, arg_t *args);
+int field_input(curve_t *curve, const config_t *cfg, arg_t *args);
/**
*
@@ -43,7 +43,7 @@ int field_input(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int field_once(curve_t *curve, config_t *cfg, arg_t *args);
+int field_once(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* Extract a field representation from a field.
diff --git a/src/math/gens.c b/src/math/gens.c
index 7b0f678..f224386 100644
--- a/src/math/gens.c
+++ b/src/math/gens.c
@@ -22,13 +22,13 @@ static int gens_put(curve_t *curve, GEN generators, long len) {
return 1;
}
-int gens_any(curve_t *curve, config_t *cfg, arg_t *args) {
+int gens_any(curve_t *curve, const config_t *cfg, arg_t *args) {
GEN generators = ellff_get_gens(curve->curve);
long len = glength(generators);
return gens_put(curve, generators, len);
}
-int gens_one(curve_t *curve, config_t *cfg, arg_t *args) {
+int gens_one(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN generators = ellff_get_gens(curve->curve);
long len = glength(generators);
diff --git a/src/math/gens.h b/src/math/gens.h
index ba22358..0160074 100644
--- a/src/math/gens.h
+++ b/src/math/gens.h
@@ -18,7 +18,7 @@
* @param args
* @return
*/
-int gens_any(curve_t *curve, config_t *cfg, arg_t *args);
+int gens_any(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* @brief
@@ -27,6 +27,6 @@ int gens_any(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int gens_one(curve_t *curve, config_t *cfg, arg_t *args);
+int gens_one(curve_t *curve, const config_t *cfg, arg_t *args);
#endif // ECGEN_GENS_H
diff --git a/src/math/order.c b/src/math/order.c
index 1bcbb3e..17b7bca 100644
--- a/src/math/order.c
+++ b/src/math/order.c
@@ -4,12 +4,17 @@
*/
#include "order.h"
-int order_any(curve_t *curve, config_t *cfg, arg_t *args) {
- curve->order = ellff_get_card(curve->curve);
+int order_any(curve_t *curve, const config_t *cfg, arg_t *args) {
+ GEN ord = ellff_get_card(curve->curve);
+ if (isclone(ord)) {
+ curve->order = gcopy(ord);
+ } else {
+ curve->order = ord;
+ }
return 1;
}
-int order_smallfact(curve_t *curve, config_t *cfg, arg_t *args) {
+int order_smallfact(curve_t *curve, const config_t *cfg, arg_t *args) {
if (!args) {
fprintf(stderr, "No args to an arged function. order_smallfact");
return INT_MIN;
@@ -34,7 +39,7 @@ int order_smallfact(curve_t *curve, config_t *cfg, arg_t *args) {
}
}
-int order_prime(curve_t *curve, config_t *cfg, arg_t *args) {
+int order_prime(curve_t *curve, const config_t *cfg, arg_t *args) {
pari_sp ltop = avma;
GEN order = ellsea(curve->curve, 1);
if (gequal0(order) || !(isprime(order))) {
diff --git a/src/math/order.h b/src/math/order.h
index 14adc79..b883fe6 100644
--- a/src/math/order.h
+++ b/src/math/order.h
@@ -20,7 +20,7 @@
* @param args
* @return state diff
*/
-int order_any(curve_t *curve, config_t *cfg, arg_t *args);
+int order_any(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -30,7 +30,7 @@ int order_any(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return
*/
-int order_smallfact(curve_t *curve, config_t *cfg, arg_t *args);
+int order_smallfact(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -43,6 +43,6 @@ int order_smallfact(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int order_prime(curve_t *curve, config_t *cfg, arg_t *args);
+int order_prime(curve_t *curve, const config_t *cfg, arg_t *args);
#endif // ECGEN_ORDER_H
diff --git a/src/math/point.c b/src/math/point.c
index 409bc48..dc9cd4a 100644
--- a/src/math/point.c
+++ b/src/math/point.c
@@ -3,6 +3,7 @@
* Copyright (C) 2017 J08nY
*/
#include "point.h"
+#include "types.h"
point_t *point_new(void) {
point_t *point = pari_malloc(sizeof(point_t));
@@ -21,8 +22,34 @@ point_t *point_copy(const point_t *src, point_t *dest) {
return dest;
}
+point_t *point_new_copy(const point_t *src) {
+ point_t *result = point_new();
+ return point_copy(src, result);
+}
+
+point_t *point_clone(const point_t *src, point_t *dest) {
+ if (src->point) dest->point = gclone(src->point);
+ if (src->order) dest->order = gclone(src->order);
+ if (src->cofactor) dest->cofactor = gclone(src->cofactor);
+ return dest;
+}
+
+point_t *point_new_clone(const point_t *src) {
+ point_t *result = point_new();
+ return point_clone(src, result);
+}
+
void point_free(point_t **point) {
if (*point) {
+ if ((*point)->point && isclone((*point)->point)) {
+ gunclone((*point)->point);
+ }
+ if ((*point)->order && isclone((*point)->order)) {
+ gunclone((*point)->order);
+ }
+ if ((*point)->cofactor && isclone((*point)->cofactor)) {
+ gunclone((*point)->cofactor);
+ }
pari_free(*point);
*point = NULL;
}
@@ -38,14 +65,30 @@ point_t **points_new(size_t num) {
return points;
}
-point_t **points_copy(point_t **src, point_t **dest, size_t num) {
+point_t **points_copy(point_t **const src, point_t **dest, size_t num) {
for (size_t i = 0; i < num; ++i) {
- dest[i] = point_new();
- dest[i] = point_copy(src[i], dest[i]);
+ dest[i] = point_new_copy(src[i]);
}
return dest;
}
+point_t **points_new_copy(point_t **const src, size_t num) {
+ point_t **result = points_new(num);
+ return points_copy(src, result, num);
+}
+
+point_t **points_clone(point_t **const src, point_t **dest, size_t num) {
+ for (size_t i = 0; i < num; ++i) {
+ dest[i] = point_new_clone(src[i]);
+ }
+ return dest;
+}
+
+point_t **points_new_clone(point_t **const src, size_t num) {
+ point_t **result = points_new(num);
+ return points_clone(src, result, num);
+}
+
void points_free(point_t ***points) {
if (*points) {
pari_free(*points);
@@ -62,7 +105,7 @@ void points_free_deep(point_t ***points, size_t npoints) {
}
}
-int point_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int point_random(curve_t *curve, const config_t *cfg, arg_t *args) {
points_free_deep(&curve->points, curve->npoints);
point_t *p = point_new();
@@ -75,7 +118,7 @@ int point_random(curve_t *curve, config_t *cfg, arg_t *args) {
return 1;
}
-int points_random(curve_t *curve, config_t *cfg, arg_t *args) {
+int points_random(curve_t *curve, const config_t *cfg, arg_t *args) {
if (!args) {
fprintf(stderr, "No args to an arged function. points_random");
return INT_MIN;
@@ -111,7 +154,7 @@ int points_random(curve_t *curve, config_t *cfg, arg_t *args) {
}
*/
-int points_trial(curve_t *curve, config_t *cfg, arg_t *args) {
+int points_trial(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO stack code!!!
if (!args) {
fprintf(stderr, "No args to an arged function. points_trial");
@@ -150,7 +193,7 @@ int points_trial(curve_t *curve, config_t *cfg, arg_t *args) {
return 1;
}
-int points_prime(curve_t *curve, config_t *cfg, arg_t *args) {
+int points_prime(curve_t *curve, const config_t *cfg, arg_t *args) {
// TODO stack code!!!
points_free_deep(&curve->points, curve->npoints);
diff --git a/src/math/point.h b/src/math/point.h
index 4ebea31..9eef8a4 100644
--- a/src/math/point.h
+++ b/src/math/point.h
@@ -27,6 +27,28 @@ point_t *point_copy(const point_t *src, point_t *dest);
/**
*
+ * @param src
+ * @return
+ */
+point_t *point_new_copy(const point_t *src);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+point_t *point_clone(const point_t *src, point_t *dest);
+
+/**
+ *
+ * @param src
+ * @return
+ */
+point_t *point_new_clone(const point_t *src);
+
+/**
+ *
* @param point
*/
void point_free(point_t **point);
@@ -45,7 +67,32 @@ point_t **points_new(size_t num);
* @param num
* @return
*/
-point_t **points_copy(point_t **src, point_t **dest, size_t num);
+point_t **points_copy(point_t **const src, point_t **dest, size_t num);
+
+/**
+ *
+ * @param src
+ * @param num
+ * @return
+ */
+point_t **points_new_copy(point_t **const src, size_t num);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @param num
+ * @return
+ */
+point_t **points_clone(point_t **const src, point_t **dest, size_t num);
+
+/**
+ *
+ * @param src
+ * @param num
+ * @return
+ */
+point_t **points_new_clone(point_t **const src, size_t num);
/**
*
@@ -68,7 +115,7 @@ void points_free_deep(point_t ***points, size_t npoints);
* @param args unused
* @return state diff
*/
-int point_random(curve_t *curve, config_t *cfg, arg_t *args);
+int point_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -78,7 +125,7 @@ int point_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args size_t number of points to generate
* @return state diff
*/
-int points_random(curve_t *curve, config_t *cfg, arg_t *args);
+int points_random(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -96,7 +143,7 @@ int points_random(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int points_trial(curve_t *curve, config_t *cfg, arg_t *args);
+int points_trial(curve_t *curve, const config_t *cfg, arg_t *args);
/**
* GENERATOR(gen_t)
@@ -110,6 +157,6 @@ int points_trial(curve_t *curve, config_t *cfg, arg_t *args);
* @param args
* @return state diff
*/
-int points_prime(curve_t *curve, config_t *cfg, arg_t *args);
+int points_prime(curve_t *curve, const config_t *cfg, arg_t *args);
#endif // ECGEN_POINT_H
diff --git a/src/math/poly.c b/src/math/poly.c
index 5398d76..50d0da0 100644
--- a/src/math/poly.c
+++ b/src/math/poly.c
@@ -2712,9 +2712,9 @@ static int compare_poly(const void *a, const void *b) {
return (one->m - other->m);
}
-bool poly_exists(long m) { return m >= 2 && m <= 10000; }
+bool poly_exists(unsigned long m) { return m >= 2 && m <= 10000; }
-polynomial_t *poly_find(long m) {
+polynomial_t *poly_find(unsigned long m) {
if (!poly_exists(m)) {
return NULL;
}
@@ -2740,9 +2740,9 @@ polynomial_t *poly_find(long m) {
}
}
-GEN poly_find_gen(long m) { return poly_gen(poly_find(m)); }
+GEN poly_find_gen(unsigned long m) { return poly_gen(poly_find(m)); }
-GEN poly_gen(polynomial_t *polynomial) {
+GEN poly_gen(const polynomial_t *polynomial) {
pari_sp ltop = avma;
GEN coeffs = gtovec0(gen_0, polynomial->m + 1);
diff --git a/src/math/poly.h b/src/math/poly.h
index f9793f4..664ca6b 100644
--- a/src/math/poly.h
+++ b/src/math/poly.h
@@ -23,26 +23,26 @@ typedef struct {
* @param m
* @return
*/
-bool poly_exists(long m);
+bool poly_exists(unsigned long m);
/**
*
* @param m
* @return
*/
-polynomial_t *poly_find(long m);
+polynomial_t *poly_find(unsigned long m);
/**
*
* @param m
* @return
*/
-GEN poly_find_gen(long m);
+GEN poly_find_gen(unsigned long m);
/**
*
* @param polynomial
* @return
*/
-GEN poly_gen(polynomial_t *polynomial);
+GEN poly_gen(const polynomial_t *polynomial);
#endif // ECGEN_POLY_H
diff --git a/src/math/random.c b/src/math/random.c
index 20098e1..da4bc2c 100644
--- a/src/math/random.c
+++ b/src/math/random.c
@@ -35,7 +35,7 @@ bool random_init(void) {
return true;
}
-GEN random_prime(long bits) {
+GEN random_prime(unsigned long bits) {
pari_sp ltop = avma;
GEN range = gtovec0(gen_0, 2);
@@ -54,7 +54,7 @@ GEN random_prime(long bits) {
return gerepilecopy(ltop, p);
}
-GEN random_int(long bits) {
+GEN random_int(unsigned long bits) {
pari_sp ltop = avma;
GEN range = gtovec0(gen_0, 2);
diff --git a/src/math/random.h b/src/math/random.h
index 34c5bd5..de03abb 100644
--- a/src/math/random.h
+++ b/src/math/random.h
@@ -13,8 +13,8 @@
bool random_init(void);
-GEN random_prime(long bits);
+GEN random_prime(unsigned long bits);
-GEN random_int(long bits);
+GEN random_int(unsigned long bits);
#endif // ECGEN_RANDOM_H
diff --git a/src/math/types.c b/src/math/types.c
index 431c9c2..49d8620 100644
--- a/src/math/types.c
+++ b/src/math/types.c
@@ -4,4 +4,4 @@
*/
#include "types.h"
-int gen_skip(curve_t *curve, config_t *cfg, arg_t *args) { return 1; }
+int gen_skip(curve_t *curve, const config_t *cfg, arg_t *args) { return 1; }
diff --git a/src/math/types.h b/src/math/types.h
index a726021..4dee9dd 100644
--- a/src/math/types.h
+++ b/src/math/types.h
@@ -33,7 +33,7 @@ typedef struct {
size_t npoints;
} curve_t;
-enum curve_offset {
+typedef enum {
OFFSET_SEED,
OFFSET_FIELD,
OFFSET_A,
@@ -43,14 +43,14 @@ enum curve_offset {
OFFSET_GENERATORS,
OFFSET_POINTS,
OFFSET_END
-};
+} offset_e;
typedef struct {
void *args;
size_t nargs;
} arg_t;
-typedef int (*gen_t)(curve_t *, config_t *, arg_t *);
+typedef int (*gen_t)(curve_t *, const config_t *, arg_t *);
/**
* @brief
@@ -59,6 +59,6 @@ typedef int (*gen_t)(curve_t *, config_t *, arg_t *);
* @param args
* @return
*/
-int gen_skip(curve_t *curve, config_t *cfg, arg_t *args);
+int gen_skip(curve_t *curve, const config_t *cfg, arg_t *args);
#endif // ECGEN_TYPES_H