X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/34e4f738bcba58e6d8c4cabbb0b3232a65b42a9d..92c494cebdce7068e6c9c0fe4363467719c8ed67:/g-prime.c diff --git a/g-prime.c b/g-prime.c index 03843be..aa17685 100644 --- a/g-prime.c +++ b/g-prime.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: g-prime.c,v 1.1 2004/04/01 12:50:09 mdw Exp $ + * $Id: g-prime.c,v 1.4 2004/04/08 01:36:15 mdw Exp $ * * Abstraction for prime groups * @@ -27,18 +27,6 @@ * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: g-prime.c,v $ - * 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 @@ -78,8 +66,10 @@ 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; return (g->mm.m == h->mm.m); } +static int gsamep(group *gg, group *hh) { + gctx *g = (gctx *)gg, *h = (gctx *)hh; + return (MP_EQ(g->mm.m, h->mm.m)); +} static int geq(group *gg, mp **x, mp **y) { return (MP_EQ(*x, *y)); } @@ -101,7 +91,7 @@ static void gsqr(group *gg, mp **d, mp **x) { 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); + 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) @@ -129,8 +119,8 @@ static mp *gtoint(group *gg, mp *d, mp **x) { gctx *g = (gctx *)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 *g = (gctx *)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) { @@ -140,7 +130,21 @@ static int gtobuf(group *gg, buf *b, mp **x) { static int gfrombuf(group *gg, buf *b, mp **d) { gctx * g = (gctx *)gg; mp *x; if ((x = buf_getmp(b)) == 0) return (-1); - mp_div(0, &x, x, g->mm.r2); mp_drop(*d); + 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 *g = (gctx *)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 * g = (gctx *)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); } @@ -148,7 +152,7 @@ static int gfrombuf(group *gg, buf *b, mp **d) { * * Arguments: @const gprime_param *gp@ = group parameters * - * Returns: A pointer to the group. + * Returns: A pointer to the group, or null. * * Use: Constructs an abstract group interface for a subgroup of a * prime field. Group elements are @mp *@ pointers. @@ -161,13 +165,17 @@ static const group_ops gops = { 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 = CREATE(gctx); + gctx *g; + if (!MP_ISPOS(gp->p) || !MP_ISODD(gp->p)) + return (0); + g = CREATE(gctx); g->g.ops = &gops; g->g.nbits = mp_bits(gp->p); g->g.noctets = (g->g.nbits + 7) >> 3;