X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/02d7884df1f33c9c7dc3a14c4b1a5f520ebe090a..a1e745ad3b306d1e5173588e39d71b132466365e:/g-prime.c diff --git a/g-prime.c b/g-prime.c index 03cce55..5230111 100644 --- a/g-prime.c +++ b/g-prime.c @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: g-prime.c,v 1.2 2004/04/03 03:32:05 mdw Exp $ + * $Id$ * * Abstraction for prime groups * * (c) 2004 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,33 +15,18 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: g-prime.c,v $ - * Revision 1.2 2004/04/03 03:32:05 mdw - * General robustification. - * - * Revision 1.1 2004/04/01 12:50:09 mdw - * Add cyclic group abstraction, with test code. Separate off exponentation - * functions for better static linking. Fix a buttload of bugs on the way. - * Generally ensure that negative exponents do inversion correctly. Add - * table of standard prime-field subgroups. (Binary field subgroups are - * currently unimplemented but easy to add if anyone ever finds a good one.) - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -51,21 +36,14 @@ #define ge mp * #include "group.h" - -/*----- Data structures ---------------------------------------------------*/ - -typedef struct gctx { - group g; - mp *gen; - mpmont mm; -} gctx; +#include "group-guts.h" /*----- Main code ---------------------------------------------------------*/ /* --- Group operations --- */ static void gdestroygroup(group *gg) { - gctx *g = (gctx *)gg; + gctx_prime *g = (gctx_prime *)gg; mp_drop(g->gen); mp_drop(g->g.r); mp_drop(g->g.h); mpmont_destroy(&g->mm); DESTROY(g); @@ -82,14 +60,14 @@ static void gburn(group *gg, mp **x) { (*x)->f |= MP_BURN; } static void gdestroy(group *gg, mp **x) { MP_DROP(*x); DESTROY(x); } static int gsamep(group *gg, group *hh) { - gctx *g = (gctx *)gg, *h = (gctx *)hh; + gctx_prime *g = (gctx_prime *)gg, *h = (gctx_prime *)hh; return (MP_EQ(g->mm.m, h->mm.m)); } static int geq(group *gg, mp **x, mp **y) { return (MP_EQ(*x, *y)); } static const char *gcheck(group *gg, grand *gr) { - gctx *g = (gctx *)gg; int rc; mp *t; + gctx_prime *g = (gctx_prime *)gg; int rc; mp *t; if (!pgen_primep(g->mm.m, gr)) return ("p is not prime"); t = mp_mul(MP_NEW, g->g.r, g->g.h); t = mp_add(t, t, MP_ONE); rc = MP_EQ(t, g->mm.m); MP_DROP(t); if (!rc) return ("not a subgroup"); @@ -97,54 +75,74 @@ static const char *gcheck(group *gg, grand *gr) { } static void gmul(group *gg, mp **d, mp **x, mp **y) - { gctx *g = (gctx *)gg; *d = mpmont_mul(&g->mm, *d, *x, *y); } + { gctx_prime *g = (gctx_prime *)gg; *d = mpmont_mul(&g->mm, *d, *x, *y); } static void gsqr(group *gg, mp **d, mp **x) { - gctx *g = (gctx *)gg; mp *r = mp_sqr(*d, *x); + gctx_prime *g = (gctx_prime *)gg; mp *r = mp_sqr(*d, *x); *d = mpmont_reduce(&g->mm, r, r); } static void ginv(group *gg, mp **d, mp **x) { - gctx *g = (gctx *)gg; mp *r = mpmont_reduce(&g->mm, *d, *x); - mp_gcd(0, 0, &r, g->mm.m, r); *d = mpmont_mul(&g->mm, r, r, g->mm.r2); + gctx_prime *g = (gctx_prime *)gg; mp *r = mpmont_reduce(&g->mm, *d, *x); + r = mp_modinv(r, r, g->mm.m); *d = mpmont_mul(&g->mm, r, r, g->mm.r2); } static void gexp(group *gg, mp **d, mp **x, mp *n) - { gctx *g = (gctx *)gg; *d = mpmont_expr(&g->mm, *d, *x, n); } + { gctx_prime *g = (gctx_prime *)gg; *d = mpmont_expr(&g->mm, *d, *x, n); } static void gmexp(group *gg, mp **d, const group_expfactor *f, size_t n) { - gctx *g = (gctx *)gg; size_t i; + gctx_prime *g = (gctx_prime *)gg; size_t i; mp_expfactor *ff = xmalloc(n * sizeof(mp_expfactor)); for (i = 0; i < n; i++) { ff[i].base = *f[i].base; ff[i].exp = f[i].exp; } *d = mpmont_mexpr(&g->mm, *d, ff, n); xfree(ff); } static int gread(group *gg, mp **d, const mptext_ops *ops, void *p) { - gctx *g = (gctx *)gg; mp *t; + gctx_prime *g = (gctx_prime *)gg; mp *t; if ((t = mp_read(MP_NEW, 0, ops, p)) == 0) return (-1); mp_drop(*d); *d = mpmont_mul(&g->mm, t, t, g->mm.r2); return (0); } static int gwrite(group *gg, mp **x, const mptext_ops *ops, void *p) { - gctx *g = (gctx *)gg; mp *t = mpmont_reduce(&g->mm, MP_NEW, *x); + gctx_prime *g = (gctx_prime *)gg; + mp *t = mpmont_reduce(&g->mm, MP_NEW, *x); int rc = mp_write(t, 10, ops, p); MP_DROP(t); return (rc); } -static mp *gtoint(group *gg, mp *d, mp **x) - { gctx *g = (gctx *)gg; return (mpmont_reduce(&g->mm, d, *x)); } +static mp *gtoint(group *gg, mp *d, mp **x) { + gctx_prime *g = (gctx_prime *)gg; + return (mpmont_reduce(&g->mm, d, *x)); +} static int gfromint(group *gg, mp **d, mp *x) { - gctx *g = (gctx *)gg; mp_div(0, &x, x, g->mm.m); mp_drop(*d); - *d = mpmont_mul(&g->mm, x, x, g->mm.r2); return (0); + gctx_prime *g = (gctx_prime *)gg; mp_div(0, d, x, g->mm.m); + *d = mpmont_mul(&g->mm, *d, *d, g->mm.r2); return (0); } static int gtobuf(group *gg, buf *b, mp **x) { - gctx *g = (gctx *)gg; mp *t = mpmont_reduce(&g->mm, MP_NEW, *x); + gctx_prime *g = (gctx_prime *)gg; + mp *t = mpmont_reduce(&g->mm, MP_NEW, *x); int rc = buf_putmp(b, t); MP_DROP(t); return (rc); } static int gfrombuf(group *gg, buf *b, mp **d) { - gctx * g = (gctx *)gg; mp *x; if ((x = buf_getmp(b)) == 0) return (-1); + gctx_prime * g = (gctx_prime *)gg; mp *x; + if ((x = buf_getmp(b)) == 0) return (-1); + mp_div(0, &x, x, g->mm.m); mp_drop(*d); + *d = mpmont_mul(&g->mm, x, x, g->mm.r2); return(0); +} + +static int gtoraw(group *gg, buf *b, mp **x) { + gctx_prime *g = (gctx_prime *)gg; octet *q; + mp *t = mpmont_reduce(&g->mm, MP_NEW, *x); + if ((q = buf_get(b, g->g.noctets)) == 0) { MP_DROP(t); return (-1); } + mp_storeb(t, q, g->g.noctets); MP_DROP(t); return (0); +} + +static int gfromraw(group *gg, buf *b, mp **d) { + gctx_prime * g = (gctx_prime *)gg; mp *x; octet *q; + if ((q = buf_get(b, g->g.noctets)) == 0) return (-1); + x = mp_loadb(MP_NEW, q, g->g.noctets); mp_div(0, &x, x, g->mm.m); mp_drop(*d); *d = mpmont_mul(&g->mm, x, x, g->mm.r2); return(0); } @@ -160,22 +158,23 @@ static int gfrombuf(group *gg, buf *b, mp **d) { */ static const group_ops gops = { - GTY_PRIME, + GTY_PRIME, "prime", gdestroygroup, gcreate, gcopy, gburn, gdestroy, gsamep, geq, group_stdidentp, gcheck, gmul, gsqr, ginv, group_stddiv, gexp, gmexp, gread, gwrite, - gtoint, gfromint, group_stdtoec, group_stdfromec, gtobuf, gfrombuf + gtoint, gfromint, group_stdtoec, group_stdfromec, gtobuf, gfrombuf, + gtoraw, gfromraw }; group *group_prime(const gprime_param *gp) { - gctx *g; + gctx_prime *g; - if (!MP_ISPOS(gp->p) || !MP_ISODD(gp->p)) + if (!MP_POSP(gp->p) || !MP_ODDP(gp->p)) return (0); - g = CREATE(gctx); + g = CREATE(gctx_prime); g->g.ops = &gops; g->g.nbits = mp_bits(gp->p); g->g.noctets = (g->g.nbits + 7) >> 3;