aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2018-03-28 19:15:54 +0200
committerJ08nY2018-03-28 19:15:54 +0200
commitee5faa5ee336d90733d7ccb1e82497901b86637a (patch)
tree36d30b5caf5970dfbb8eaf4f3da3577a97d22ff0
parent72f2a5d4fb0aaa054fb73e30944c10a41c830727 (diff)
parentf75446e573fb7d06be668b1dcdeb418f89b81af1 (diff)
downloadecgen-ee5faa5ee336d90733d7ccb1e82497901b86637a.tar.gz
ecgen-ee5faa5ee336d90733d7ccb1e82497901b86637a.tar.zst
ecgen-ee5faa5ee336d90733d7ccb1e82497901b86637a.zip
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/exhaustive/brainpool.c4
-rw-r--r--src/exhaustive/exhaustive.c3
-rw-r--r--src/gen/curve.c74
-rw-r--r--src/gen/curve.h44
-rw-r--r--src/gen/gens.c3
-rw-r--r--src/gen/hex.c1
-rw-r--r--src/gen/point.c86
-rw-r--r--src/gen/point.h96
-rw-r--r--src/invalid/invalid.c1
-rw-r--r--src/invalid/invalid_thread.c1
-rw-r--r--src/math/subgroup.c95
-rw-r--r--src/math/subgroup.h102
-rw-r--r--src/math/twists.c2
-rw-r--r--src/obj/curve.c65
-rw-r--r--src/obj/curve.h36
-rw-r--r--src/obj/obj.h58
-rw-r--r--src/obj/point.c51
-rw-r--r--src/obj/point.h46
-rw-r--r--src/obj/subgroup.c57
-rw-r--r--src/obj/subgroup.h52
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/src/gen/test_curve.c1
-rw-r--r--test/src/gen/test_point.c3
24 files changed, 381 insertions, 504 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d93f5ba..5625a4a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ project(ecgen C)
add_subdirectory(lib)
-file(GLOB SRC "src/math/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/misc/*.c" "src/util/*.c")
+file(GLOB SRC "src/math/*.c" "src/obj/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/misc/*.c" "src/util/*.c")
set(ECGEN_SRC "src/ecgen.c" ${SRC})
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG -g -Wall -Werror")
diff --git a/src/exhaustive/brainpool.c b/src/exhaustive/brainpool.c
index 68d7966..56c095d 100644
--- a/src/exhaustive/brainpool.c
+++ b/src/exhaustive/brainpool.c
@@ -4,12 +4,12 @@
*/
#include "brainpool.h"
-#include <misc/types.h>
#include "gen/gens.h"
-#include "gen/point.h"
#include "gen/seed.h"
#include "io/output.h"
#include "math/subgroup.h"
+#include "obj/point.h"
+#include "obj/subgroup.h"
#include "util/bits.h"
#include "util/str.h"
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 53273bc..28d464a 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -3,7 +3,6 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "exhaustive.h"
-#include <misc/config.h>
#include "anomalous.h"
#include "ansi.h"
#include "brainpool.h"
@@ -18,6 +17,8 @@
#include "gen/point.h"
#include "gen/seed.h"
#include "io/output.h"
+#include "misc/config.h"
+#include "obj/curve.h"
#include "util/memory.h"
#include "util/timeout.h"
diff --git a/src/gen/curve.c b/src/gen/curve.c
index da4a630..7ea2fb5 100644
--- a/src/gen/curve.c
+++ b/src/gen/curve.c
@@ -3,81 +3,7 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "curve.h"
-#include "math/subgroup.h"
#include "math/twists.h"
-#include "seed.h"
-#include "util/memory.h"
-
-curve_t *curve_new(void) { return try_calloc(sizeof(curve_t)); }
-
-curve_t *curve_copy(const curve_t *src, curve_t *dest) {
- if (src->seed) dest->seed = seed_new_copy(src->seed);
- if (src->field) dest->field = gcopy(src->field);
- if (src->a) dest->a = gcopy(src->a);
- if (src->b) dest->b = gcopy(src->b);
- if (src->curve) dest->curve = gcopy(src->curve);
- if (src->order) dest->order = gcopy(src->order);
- if (src->generators) {
- dest->generators = subgroups_new_copy(src->generators, src->ngens);
- dest->ngens = src->ngens;
- }
- 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_new_clone(src->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 = subgroups_new_clone(src->generators, src->ngens);
- dest->ngens = src->ngens;
- }
- 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);
- subgroups_free_deep(&(*curve)->generators, (*curve)->ngens);
-
- 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);
- }
-
- try_free(*curve);
- *curve = NULL;
- }
-}
GENERATOR(curve_gen_any) {
pari_sp ltop = avma;
diff --git a/src/gen/curve.h b/src/gen/curve.h
index b2158eb..3a34781 100644
--- a/src/gen/curve.h
+++ b/src/gen/curve.h
@@ -52,48 +52,4 @@ CHECK(curve_check_nonzero);
*/
UNROLL(curve_unroll);
-/**
- * Allocates and zeros out a new curve_t object.
- * @return new curve
- */
-curve_t *curve_new(void);
-
-/**
- * Copies parameters from src curve to dest curve, allocates space for points.
- * Otherwise expects everything to be allocated.
- *
- * @param src source curve
- * @param dest destination curve
- * @return destination curve
- */
-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.
- * @param curve to free
- */
-void curve_free(curve_t **curve);
-
#endif // ECGEN_GEN_CURVE_H
diff --git a/src/gen/gens.c b/src/gen/gens.c
index 7947ccb..d106f7c 100644
--- a/src/gen/gens.c
+++ b/src/gen/gens.c
@@ -5,7 +5,8 @@
#include "gens.h"
#include "exhaustive/arg.h"
#include "math/subgroup.h"
-#include "point.h"
+#include "obj/point.h"
+#include "obj/subgroup.h"
static subgroup_t *gens_point(GEN point, const curve_t *curve) {
subgroup_t *sub = subgroup_new();
diff --git a/src/gen/hex.c b/src/gen/hex.c
index 4752b7e..c91f522 100644
--- a/src/gen/hex.c
+++ b/src/gen/hex.c
@@ -3,7 +3,6 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "hex.h"
-#include <misc/types.h>
#include "exhaustive/arg.h"
#include "field.h"
#include "util/bits.h"
diff --git a/src/gen/point.c b/src/gen/point.c
index 2d307f3..00e7c3c 100644
--- a/src/gen/point.c
+++ b/src/gen/point.c
@@ -5,93 +5,9 @@
#include "point.h"
#include "exhaustive/arg.h"
#include "math/subgroup.h"
-#include "util/memory.h"
+#include "obj/point.h"
#include "util/random.h"
-point_t *point_new(void) { return try_calloc(sizeof(point_t)); }
-
-point_t *point_copy(const point_t *src, point_t *dest) {
- if (src->point) dest->point = gcopy(src->point);
- if (src->order) dest->order = gcopy(src->order);
- if (src->cofactor) dest->cofactor = gcopy(src->cofactor);
- 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);
- }
- try_free(*point);
- *point = NULL;
- }
-}
-
-point_t **points_new(size_t num) { return try_calloc(num * sizeof(point_t *)); }
-
-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_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) {
- try_free(*points);
- *points = NULL;
- }
-}
-
-void points_free_deep(point_t ***points, size_t npoints) {
- if (*points) {
- for (size_t i = 0; i < npoints; ++i) {
- point_free(&(*points)[i]);
- }
- points_free(points);
- }
-}
-
GENERATOR(point_gen_random) {
long which_gen = itos(random_range(gen_0, stoi(curve->ngens)));
diff --git a/src/gen/point.h b/src/gen/point.h
index cc03326..c10b742 100644
--- a/src/gen/point.h
+++ b/src/gen/point.h
@@ -11,102 +11,6 @@
#include "misc/types.h"
/**
- *
- * @return
- */
-point_t *point_new(void);
-
-/**
- *
- * @param src
- * @param dest
- * @return
- */
-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);
-
-/**
- *
- * @param num
- * @return
- */
-point_t **points_new(size_t num);
-
-/**
- *
- * @param src
- * @param dest
- * @param num
- * @return
- */
-point_t **points_copy(point_t **src, point_t **dest, size_t num);
-
-/**
- *
- * @param src
- * @param num
- * @return
- */
-point_t **points_new_copy(point_t **src, size_t num);
-
-/**
- *
- * @param src
- * @param dest
- * @param num
- * @return
- */
-point_t **points_clone(point_t **src, point_t **dest, size_t num);
-
-/**
- *
- * @param src
- * @param num
- * @return
- */
-point_t **points_new_clone(point_t **src, size_t num);
-
-/**
- *
- * @param point
- */
-void points_free(point_t ***point);
-
-/**
- *
- * @param points
- * @param npoints
- */
-void points_free_deep(point_t ***points, size_t npoints);
-
-/**
* GENERATOR(gen_f)
*
* @param curve A curve_t being generated
diff --git a/src/invalid/invalid.c b/src/invalid/invalid.c
index aeda327..6a0f85a 100644
--- a/src/invalid/invalid.c
+++ b/src/invalid/invalid.c
@@ -13,6 +13,7 @@
#include "gen/order.h"
#include "gen/point.h"
#include "invalid_thread.h"
+#include "obj/curve.h"
#include "util/memory.h"
static void invalid_original_ginit(gen_f *generators) {
diff --git a/src/invalid/invalid_thread.c b/src/invalid/invalid_thread.c
index cf0f67c..74f247c 100644
--- a/src/invalid/invalid_thread.c
+++ b/src/invalid/invalid_thread.c
@@ -7,6 +7,7 @@
#include "gen/curve.h"
#include "gen/gens.h"
#include "gen/point.h"
+#include "obj/curve.h"
#include "util/random.h"
#include "util/timeout.h"
diff --git a/src/math/subgroup.c b/src/math/subgroup.c
index 90b795a..eb8ff27 100644
--- a/src/math/subgroup.c
+++ b/src/math/subgroup.c
@@ -3,101 +3,6 @@
* Copyright (C) 2017-2018 J08nY
*/
#include "subgroup.h"
-#include "gen/point.h"
-#include "util/memory.h"
-
-subgroup_t *subgroup_new(void) { return try_calloc(sizeof(subgroup_t)); }
-
-subgroup_t *subgroup_copy(const subgroup_t *src, subgroup_t *dst) {
- if (src->generator) dst->generator = point_new_copy(src->generator);
- if (src->points) {
- dst->points = points_new_copy(src->points, src->npoints);
- dst->npoints = src->npoints;
- }
- return dst;
-}
-
-subgroup_t *subgroup_new_copy(const subgroup_t *src) {
- subgroup_t *result = subgroup_new();
- return subgroup_copy(src, result);
-}
-
-subgroup_t *subgroup_clone(const subgroup_t *src, subgroup_t *dst) {
- if (src->generator) dst->generator = point_new_clone(src->generator);
- if (src->points) {
- dst->points = points_new_clone(src->points, src->npoints);
- dst->npoints = src->npoints;
- }
- return dst;
-}
-
-subgroup_t *subgroup_new_clone(const subgroup_t *src) {
- subgroup_t *result = subgroup_new();
- return subgroup_clone(src, result);
-}
-
-void subgroup_free(subgroup_t **subgroup) {
- if (*subgroup) {
- if ((*subgroup)->generator) {
- point_free(&(*subgroup)->generator);
- }
- try_free(*subgroup);
- *subgroup = NULL;
- }
-}
-
-void subgroup_free_deep(subgroup_t **subgroup) {
- if (*subgroup) {
- points_free_deep(&(*subgroup)->points, (*subgroup)->npoints);
- subgroup_free(subgroup);
- }
-}
-
-subgroup_t **subgroups_new(size_t num) {
- return try_calloc(num * sizeof(subgroup_t *));
-}
-
-subgroup_t **subgroups_copy(subgroup_t **const src, subgroup_t **dest,
- size_t num) {
- for (size_t i = 0; i < num; ++i) {
- dest[i] = subgroup_new_copy(src[i]);
- }
- return dest;
-}
-
-subgroup_t **subgroups_new_copy(subgroup_t **const src, size_t num) {
- subgroup_t **result = subgroups_new(num);
- return subgroups_copy(src, result, num);
-}
-
-subgroup_t **subgroups_clone(subgroup_t **const src, subgroup_t **dest,
- size_t num) {
- for (size_t i = 0; i < num; ++i) {
- dest[i] = subgroup_new_clone(src[i]);
- }
- return dest;
-}
-
-subgroup_t **subgroups_new_clone(subgroup_t **const src, size_t num) {
- subgroup_t **result = subgroups_new(num);
- return subgroups_clone(src, result, num);
-}
-
-void subgroups_free(subgroup_t ***subgroups) {
- if (*subgroups) {
- try_free(*subgroups);
- *subgroups = NULL;
- }
-}
-
-void subgroups_free_deep(subgroup_t ***subgroups, size_t num) {
- if (*subgroups) {
- for (size_t i = 0; i < num; ++i) {
- subgroup_free(&(*subgroups)[i]);
- }
- subgroups_free(subgroups);
- }
-}
/**
* @brief All prime divisors of a given integer with multiplicity.
diff --git a/src/math/subgroup.h b/src/math/subgroup.h
index 94df006..68657fb 100644
--- a/src/math/subgroup.h
+++ b/src/math/subgroup.h
@@ -12,108 +12,6 @@
#include "misc/types.h"
/**
- * @brief
- * @return
- */
-subgroup_t *subgroup_new(void);
-
-/**
- * @brief
- * @param src
- * @param dst
- * @return
- */
-subgroup_t *subgroup_copy(const subgroup_t *src, subgroup_t *dst);
-
-/**
- * @brief
- * @param src
- * @return
- */
-subgroup_t *subgroup_new_copy(const subgroup_t *src);
-
-/**
- * @brief
- * @param src
- * @param dst
- * @return
- */
-subgroup_t *subgroup_clone(const subgroup_t *src, subgroup_t *dst);
-
-/**
- * @brief
- * @param src
- * @return
- */
-subgroup_t *subgroup_new_clone(const subgroup_t *src);
-
-/**
- * @brief
- * @param subgroup
- */
-void subgroup_free(subgroup_t **subgroup);
-
-/**
- * @brief
- * @param subgroup
- */
-void subgroup_free_deep(subgroup_t **subgroup);
-
-/**
- * @brief
- * @param num
- * @return
- */
-subgroup_t **subgroups_new(size_t num);
-
-/**
- *
- * @param src
- * @param dest
- * @param num
- * @return
- */
-subgroup_t **subgroups_copy(subgroup_t **src, subgroup_t **dest, size_t num);
-
-/**
- *
- * @param src
- * @param num
- * @return
- */
-subgroup_t **subgroups_new_copy(subgroup_t **src, size_t num);
-
-/**
- *
- * @param src
- * @param dest
- * @param num
- * @return
- */
-subgroup_t **subgroups_clone(subgroup_t **src, subgroup_t **dest, size_t num);
-
-/**
- *
- * @param src
- * @param num
- * @return
- */
-subgroup_t **subgroups_new_clone(subgroup_t **src, size_t num);
-
-/**
- * @brief
- * @param subgroups
- */
-void subgroups_free(subgroup_t ***subgroups);
-
-/**
- * @brief
- * @param subgroups
- * @param num
- */
-void subgroups_free_deep(subgroup_t ***subgroups, size_t num);
-
-/**
* @brief All prime factors of a given integer, without multipliticity.
*
* subgroups_factors(27) = [3]
diff --git a/src/math/twists.c b/src/math/twists.c
index 992b7cf..0d4b14c 100644
--- a/src/math/twists.c
+++ b/src/math/twists.c
@@ -4,7 +4,7 @@
*/
#include "twists.h"
#include "gen/seed.h"
-#include "math/subgroup.h"
+#include "obj/subgroup.h"
void twist_rand_to(curve_t *to, const curve_t *of) {
to->field = gcopy(of->field);
diff --git a/src/obj/curve.c b/src/obj/curve.c
new file mode 100644
index 0000000..4821442
--- /dev/null
+++ b/src/obj/curve.c
@@ -0,0 +1,65 @@
+
+#include "curve.h"
+#include "gen/seed.h"
+#include "obj/subgroup.h"
+
+OBJ(curve, curve_t, curve_copy, curve_clone)
+
+curve_t *curve_copy(const curve_t *src, curve_t *dest) {
+ if (src->seed) dest->seed = seed_new_copy(src->seed);
+ if (src->field) dest->field = gcopy(src->field);
+ if (src->a) dest->a = gcopy(src->a);
+ if (src->b) dest->b = gcopy(src->b);
+ if (src->curve) dest->curve = gcopy(src->curve);
+ if (src->order) dest->order = gcopy(src->order);
+ if (src->generators) {
+ dest->generators = subgroups_new_copy(src->generators, src->ngens);
+ dest->ngens = src->ngens;
+ }
+ return dest;
+}
+
+curve_t *curve_clone(const curve_t *src, curve_t *dest) {
+ if (src->seed) dest->seed = seed_new_clone(src->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 = subgroups_new_clone(src->generators, src->ngens);
+ dest->ngens = src->ngens;
+ }
+ return dest;
+}
+
+void curve_free(curve_t **curve) {
+ if (*curve) {
+ seed_free(&(*curve)->seed);
+ subgroups_free_deep(&(*curve)->generators, (*curve)->ngens);
+
+ 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);
+ }
+
+ try_free(*curve);
+ *curve = NULL;
+ }
+} \ No newline at end of file
diff --git a/src/obj/curve.h b/src/obj/curve.h
new file mode 100644
index 0000000..99284f4
--- /dev/null
+++ b/src/obj/curve.h
@@ -0,0 +1,36 @@
+
+#ifndef ECGEN_OBJ_CURVE_H
+#define ECGEN_OBJ_CURVE_H
+
+#include "misc/types.h"
+#include "obj.h"
+
+OBJ_H(curve, curve_t)
+
+/**
+ * Copies parameters from src curve to dest curve, allocates space for points.
+ * Otherwise expects everything to be allocated.
+ *
+ * @param src source curve
+ * @param dest destination curve
+ * @return destination curve
+ */
+curve_t *curve_copy(const curve_t *src, curve_t *dest);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+curve_t *curve_clone(const curve_t *src, curve_t *dest);
+
+/**
+ * Free a curve_t along with it's seed_t and point_ts.
+ * @param curve to free
+ */
+void curve_free(curve_t **curve);
+
+#include "misc/types.h"
+
+#endif // ECGEN_OBJ_CURVE_H
diff --git a/src/obj/obj.h b/src/obj/obj.h
new file mode 100644
index 0000000..5a7f9ab
--- /dev/null
+++ b/src/obj/obj.h
@@ -0,0 +1,58 @@
+
+#ifndef ECGEN_OBJ_H
+#define ECGEN_OBJ_H
+
+#include "misc/types.h"
+#include "util/memory.h"
+
+#define OBJ(obj_name, obj_type, copy_func, clone_func) \
+ obj_type *obj_name##_new() { return try_calloc(sizeof(obj_type)); } \
+ obj_type *obj_name##_new_copy(const obj_type *src) { \
+ obj_type *result = obj_name##_new(); \
+ return copy_func(src, result); \
+ } \
+ obj_type *obj_name##_new_clone(const obj_type *src) { \
+ obj_type *result = obj_name##_new(); \
+ return clone_func(src, result); \
+ }
+
+#define OBJS(obj_name, obj_type, copy_func, clone_func) \
+ obj_type **obj_name##s_new(size_t num) { \
+ return try_calloc(num * sizeof(obj_type)); \
+ } \
+ obj_type **obj_name##s_copy(obj_type **const src, obj_type **dest, \
+ size_t num) { \
+ for (size_t i = 0; i < num; ++i) { \
+ dest[i] = obj_name##_new_copy(src[i]); \
+ } \
+ return dest; \
+ } \
+ obj_type **obj_name##s_clone(obj_type **const src, obj_type **dest, \
+ size_t num) { \
+ for (size_t i = 0; i < num; ++i) { \
+ dest[i] = obj_name##_new_clone(src[i]); \
+ } \
+ return dest; \
+ } \
+ obj_type **obj_name##s_new_copy(obj_type **const src, size_t num) { \
+ obj_type **result = obj_name##s_new(num); \
+ return obj_name##s_copy(src, result, num); \
+ } \
+ obj_type **obj_name##s_new_clone(obj_type **const src, size_t num) { \
+ obj_type **result = obj_name##s_new(num); \
+ return obj_name##s_clone(src, result, num); \
+ }
+
+#define OBJ_H(obj_name, obj_type) \
+ obj_type *obj_name##_new(); \
+ obj_type *obj_name##_new_copy(const obj_type *src); \
+ obj_type *obj_name##_new_clone(const obj_type *src);
+
+#define OBJS_H(obj_name, obj_type) \
+ obj_type **obj_name##s_new(size_t num); \
+ obj_type **obj_name##s_copy(obj_type **src, obj_type **dest, size_t num); \
+ obj_type **obj_name##s_clone(obj_type **src, obj_type **dest, size_t num); \
+ obj_type **obj_name##s_new_copy(obj_type **src, size_t num); \
+ obj_type **obj_name##s_new_clone(obj_type **src, size_t num);
+
+#endif // ECGEN_OBJ_H
diff --git a/src/obj/point.c b/src/obj/point.c
new file mode 100644
index 0000000..2b709dd
--- /dev/null
+++ b/src/obj/point.c
@@ -0,0 +1,51 @@
+
+#include "point.h"
+
+OBJ(point, point_t, point_copy, point_clone)
+OBJS(point, point_t, point_copy, point_clone)
+
+point_t *point_copy(const point_t *src, point_t *dest) {
+ if (src->point) dest->point = gcopy(src->point);
+ if (src->order) dest->order = gcopy(src->order);
+ if (src->cofactor) dest->cofactor = gcopy(src->cofactor);
+ return dest;
+}
+
+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;
+}
+
+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);
+ }
+ try_free(*point);
+ *point = NULL;
+ }
+}
+
+void points_free(point_t ***points) {
+ if (*points) {
+ try_free(*points);
+ *points = NULL;
+ }
+}
+
+void points_free_deep(point_t ***points, unsigned long npoints) {
+ if (*points) {
+ for (unsigned long i = 0; i < npoints; ++i) {
+ point_free(&(*points)[i]);
+ }
+ points_free(points);
+ }
+} \ No newline at end of file
diff --git a/src/obj/point.h b/src/obj/point.h
new file mode 100644
index 0000000..619f0e2
--- /dev/null
+++ b/src/obj/point.h
@@ -0,0 +1,46 @@
+
+#ifndef ECGEN_OBJ_POINT_H
+#define ECGEN_OBJ_POINT_H
+
+#include "misc/types.h"
+#include "obj.h"
+
+OBJ_H(point, point_t)
+OBJS_H(point, point_t)
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+point_t *point_copy(const point_t *src, point_t *dest);
+
+/**
+ *
+ * @param src
+ * @param dest
+ * @return
+ */
+point_t *point_clone(const point_t *src, point_t *dest);
+
+/**
+ *
+ * @param point
+ */
+void point_free(point_t **point);
+
+/**
+ *
+ * @param point
+ */
+void points_free(point_t ***point);
+
+/**
+ *
+ * @param points
+ * @param npoints
+ */
+void points_free_deep(point_t ***points, unsigned long npoints);
+
+#endif // ECGEN_OBJ_POINT_H
diff --git a/src/obj/subgroup.c b/src/obj/subgroup.c
new file mode 100644
index 0000000..5e6d6e6
--- /dev/null
+++ b/src/obj/subgroup.c
@@ -0,0 +1,57 @@
+
+#include "subgroup.h"
+#include "point.h"
+
+OBJ(subgroup, subgroup_t, subgroup_copy, subgroup_clone)
+OBJS(subgroup, subgroup_t, subgroup_copy, subgroup_clone)
+
+subgroup_t *subgroup_copy(const subgroup_t *src, subgroup_t *dst) {
+ if (src->generator) dst->generator = point_new_copy(src->generator);
+ if (src->points) {
+ dst->points = points_new_copy(src->points, src->npoints);
+ dst->npoints = src->npoints;
+ }
+ return dst;
+}
+
+subgroup_t *subgroup_clone(const subgroup_t *src, subgroup_t *dst) {
+ if (src->generator) dst->generator = point_new_clone(src->generator);
+ if (src->points) {
+ dst->points = points_new_clone(src->points, src->npoints);
+ dst->npoints = src->npoints;
+ }
+ return dst;
+}
+
+void subgroup_free(subgroup_t **subgroup) {
+ if (*subgroup) {
+ if ((*subgroup)->generator) {
+ point_free(&(*subgroup)->generator);
+ }
+ try_free(*subgroup);
+ *subgroup = NULL;
+ }
+}
+
+void subgroup_free_deep(subgroup_t **subgroup) {
+ if (*subgroup) {
+ points_free_deep(&(*subgroup)->points, (*subgroup)->npoints);
+ subgroup_free(subgroup);
+ }
+}
+
+void subgroups_free(subgroup_t ***subgroups) {
+ if (*subgroups) {
+ try_free(*subgroups);
+ *subgroups = NULL;
+ }
+}
+
+void subgroups_free_deep(subgroup_t ***subgroups, size_t num) {
+ if (*subgroups) {
+ for (size_t i = 0; i < num; ++i) {
+ subgroup_free_deep(&(*subgroups)[i]);
+ }
+ subgroups_free(subgroups);
+ }
+}
diff --git a/src/obj/subgroup.h b/src/obj/subgroup.h
new file mode 100644
index 0000000..fd1a117
--- /dev/null
+++ b/src/obj/subgroup.h
@@ -0,0 +1,52 @@
+
+#ifndef ECGEN_OBJ_SUBGROUP_H
+#define ECGEN_OBJ_SUBGROUP_H
+
+#include "misc/types.h"
+#include "obj.h"
+
+OBJ_H(subgroup, subgroup_t)
+OBJS_H(subgroup, subgroup_t)
+
+/**
+ * @brief
+ * @param src
+ * @param dst
+ * @return
+ */
+subgroup_t *subgroup_copy(const subgroup_t *src, subgroup_t *dst);
+
+/**
+ * @brief
+ * @param src
+ * @param dst
+ * @return
+ */
+subgroup_t *subgroup_clone(const subgroup_t *src, subgroup_t *dst);
+
+/**
+ * @brief
+ * @param subgroup
+ */
+void subgroup_free(subgroup_t **subgroup);
+
+/**
+ * @brief
+ * @param subgroup
+ */
+void subgroup_free_deep(subgroup_t **subgroup);
+
+/**
+ * @brief
+ * @param subgroups
+ */
+void subgroups_free(subgroup_t ***subgroups);
+
+/**
+ * @brief
+ * @param subgroups
+ * @param num
+ */
+void subgroups_free_deep(subgroup_t ***subgroups, size_t num);
+
+#endif // ECGEN_OBJ_SUBGROUP_H
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index fabbcc9..ff528cd 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,7 +11,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib/criterion/include)
find_library(criterion NAMES criterion PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib/criterion/build)
-file(GLOB TEST_SRC "src/math/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/util/*.c")
+file(GLOB TEST_SRC "src/math/*.c" "src/obj/*.c" "src/gen/*.c" "src/cm/*.c" "src/invalid/*.c" "src/io/*.c" "src/exhaustive/*.c" "src/util/*.c")
file(GLOB TESTING_SRC "src/test/*.c")
add_executable(test_ecgen ${TEST_SRC} ${TESTING_SRC} ${SRC})
diff --git a/test/src/gen/test_curve.c b/test/src/gen/test_curve.c
index 3fe4801..cd4bb5a 100644
--- a/test/src/gen/test_curve.c
+++ b/test/src/gen/test_curve.c
@@ -4,6 +4,7 @@
*/
#include <criterion/criterion.h>
#include "gen/curve.h"
+#include "obj/curve.h"
#include "test/default.h"
TestSuite(curve, .init = default_setup, .fini = default_teardown);
diff --git a/test/src/gen/test_point.c b/test/src/gen/test_point.c
index 736492b..3a76c84 100644
--- a/test/src/gen/test_point.c
+++ b/test/src/gen/test_point.c
@@ -7,6 +7,9 @@
#include "gen/curve.h"
#include "gen/point.h"
#include "math/subgroup.h"
+#include "obj/curve.h"
+#include "obj/point.h"
+#include "obj/subgroup.h"
#include "test/io.h"
TestSuite(point, .init = io_setup, .fini = io_teardown);