chiark / gitweb /
Various changes. Kinda in the middle of it here, but it seems to work.
[catacomb-perl] / utils.c
diff --git a/utils.c b/utils.c
index e23e7abbf929c0285eddc4759648bd83a4039799..e5b49f07a114229f413144e46468f7d9dd0841bc 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -29,6 +29,9 @@
 /*----- Header files ------------------------------------------------------*/
 
 #include "catacomb-perl.h"
+#include <catacomb/ec-guts.h>
+#include <catacomb/group-guts.h>
+#include <catacomb/field-guts.h>
 
 /*----- Main code ---------------------------------------------------------*/
 
@@ -65,4 +68,74 @@ void *ptrfromsv(SV *sv, const char *type, const char *what, ...)
   return (void *)SvIV((SV *)SvRV(sv));
 }
 
+/*----- Reconstructing various objects ------------------------------------*/
+
+/* --- Somewhat unpleasant, really --- */
+
+field *copy_field(field *f)
+{
+  if (strcmp(F_NAME(f), "prime") == 0)
+    f = field_prime(f->m);
+  else if (strcmp(F_NAME(f), "niceprime") == 0)
+    f = field_niceprime(f->m);
+  else if (strcmp(F_NAME(f), "binpoly") == 0)
+    f = field_binpoly(f->m);
+  else if (strcmp(F_NAME(f), "binnorm") == 0) {
+    fctx_binnorm *fc = (fctx_binnorm *)f;
+    f = field_binnorm(f->m, fc->ntop.r[fc->ntop.n - 1]);
+  } else
+    f = 0;
+  return (f);
+}
+
+ec_curve *copy_curve(ec_curve *c)
+{
+  field *f;
+  mp *a, *b;
+
+  if ((f = copy_field(c->f)) == 0)
+    return (0);
+  a = F_OUT(f, MP_NEW, c->a);
+  b = F_OUT(f, MP_NEW, c->b);
+  if (strcmp(EC_NAME(c), "prime") == 0)
+    c = ec_prime(f, a, b);
+  else if (strcmp(EC_NAME(c), "primeproj") == 0)
+    c = ec_primeproj(f, a, b);
+  if (strcmp(EC_NAME(c), "bin") == 0)
+    c = ec_bin(f, a, b);
+  else if (strcmp(EC_NAME(c), "binproj") == 0)
+    c = ec_binproj(f, a, b);
+  else
+    c = 0;
+  MP_DROP(a);
+  MP_DROP(b);
+  if (!c) F_DESTROY(f);
+  return (c);
+}
+
+group *copy_group(group *g)
+{
+  if (strcmp(G_NAME(g), "prime") == 0) {
+    gctx_prime *gc = (gctx_prime *)g;
+    gprime_param gp;
+    gp.g = G_TOINT(g, MP_NEW, g->g);
+    gp.p = gc->mm.m;
+    gp.q = gc->g.r;
+    g = group_prime(&gp);
+    MP_DROP(gp.g);
+  } else if (strcmp(G_NAME(g), "ec") == 0) {
+    gctx_ec *gc = (gctx_ec *)g;
+    ec_info ei;
+    if ((ei.c = copy_curve(gc->ei.c)) == 0)
+      return (0);
+    EC_CREATE(&ei.g);
+    EC_COPY(&ei.g, &gc->ei.g);
+    ei.r = MP_COPY(gc->ei.r);
+    ei.h = MP_COPY(gc->ei.h);
+    g = group_ec(&ei);
+  } else
+    g = 0;
+  return (g);
+}
+
 /*----- That's all, folks -------------------------------------------------*/