+/*----- 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);
+}
+