tlsprf.h sslprf.h \
gfshare.h share.h \
rho.h \
- field.h ec.h ec-exp.h ec-test.h ectab.h ec-keys.h ec-raw.h \
- ptab.h group.h \
+ field.h field-guts.h \
+ ec.h ec-guts.h ec-exp.h ec-test.h ectab.h ec-keys.h ec-raw.h \
+ ptab.h group.h group-guts.h \
allwithsuffix(`ciphers', `cipher_modes', `.h') \
allwithsuffix(`hashes', `hash_modes', `.h') \
addsuffix(`cipher_modes', `-def.h') \
/* -*-c-*-
*
- * $Id: blkc.h,v 1.8 2004/04/17 09:58:36 mdw Exp $
+ * $Id$
*
* Common definitions for block ciphers
*
#ifdef TEST_RIG
+#include <string.h>
+
#include <mLib/quis.h>
#include <mLib/testrig.h>
/* -*-c-*-
*
- * $Id: dh-param.c,v 1.2 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
*
* Reading Diffie-Hellman parameters
*
#include "fibrand.h"
-int main(void)
+int main(int argc, char *argv[])
{
const pentry *pe;
const char *e;
grand *gr;
gr = fibrand_create(0);
- fputs("checking standard prime fields: ", stdout);
+ fputs("checking standard prime fields...\n", stdout);
for (pe = ptab; pe->name; pe++) {
dh_param dp;
group *g;
getinfo(&dp, pe->data);
+ printf(" %s: ", pe->name);
g = group_prime(&dp);
+ if (mp_bits(dp.q) > 2048 &&
+ (!argv[1] || strcmp(argv[1], "keen") != 0)) {
+ fputs("skipping\n", stdout);
+ continue;
+ }
+ fflush(stdout);
e = G_CHECK(g, gr);
G_DESTROYGROUP(g);
dh_paramfree(&dp);
if (e) {
- fprintf(stderr, "\n*** group %s fails: %s\n", pe->name, e);
+ printf("fails: %s\n", e);
ok = 0;
- }
- putchar('.');
- fflush(stdout);
+ } else
+ fputs("ok\n", stdout);
}
gr->ops->destroy(gr);
- fputs(ok ? " ok\n" : " failed\n", stdout);
+ if (ok)
+ fputs("all ok\n", stdout);
return (!ok);
}
/* -*-c-*-
*
- * $Id: ec-bin.c,v 1.9 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
*
* Arithmetic for elliptic curves over binary fields
*
#include <mLib/sub.h>
#include "ec.h"
-
-/*----- Data structures ---------------------------------------------------*/
-
-typedef struct ecctx {
- ec_curve c;
- mp *bb;
-} ecctx;
+#include "ec-guts.h"
/*----- Main code ---------------------------------------------------------*/
EC_SETINF(d);
else {
field *f = c->f;
- ecctx *cc = (ecctx *)c;
+ ecctx_bin *cc = (ecctx_bin *)c;
mp *dx, *dy, *dz, *u, *v;
dy = F_SQR(f, MP_NEW, a->z); /* %$z^2$% */
static void ecdestroy(ec_curve *c)
{
- ecctx *cc = (ecctx *)c;
+ ecctx_bin *cc = (ecctx_bin *)c;
MP_DROP(cc->c.a);
MP_DROP(cc->c.b);
if (cc->bb) MP_DROP(cc->bb);
ec_curve *ec_bin(field *f, mp *a, mp *b)
{
- ecctx *cc = CREATE(ecctx);
+ ecctx_bin *cc = CREATE(ecctx_bin);
cc->c.ops = &ec_binops;
cc->c.f = f;
cc->c.a = F_IN(f, MP_NEW, a);
ec_curve *ec_binproj(field *f, mp *a, mp *b)
{
- ecctx *cc = CREATE(ecctx);
+ ecctx_bin *cc = CREATE(ecctx_bin);
cc->c.ops = &ec_binprojops;
cc->c.f = f;
cc->c.a = F_IN(f, MP_NEW, a);
}
static const ec_ops ec_binops = {
+ "bin",
ecdestroy, ec_stdsamep, ec_idin, ec_idout, ec_idfix,
ecfind, ecneg, ecadd, ec_stdsub, ecdbl, eccheck
};
static const ec_ops ec_binprojops = {
+ "binproj",
ecdestroy, ec_stdsamep, ec_projin, ec_projout, ec_projfix,
ecfind, ecprojneg, ecprojadd, ec_stdsub, ecprojdbl, ecprojcheck
};
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Internal structures for built-in elliptic curve types
+ *
+ * (c) 2004 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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.
+ */
+
+#ifndef CATACOMB_EC_GUTS_H
+#define CATACOMB_EC_GUTS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef CATACOMB_MP_H
+# include "mp.h"
+#endif
+
+#ifndef CATACOMB_EC_H
+# include "ec.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct ecctx_bin {
+ ec_curve c;
+ mp *bb;
+} ecctx_bin;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
}
}
} else {
- fputs("checking standard curves: ", stdout);
+ fputs("checking standard curves...\n", stdout);
for (ee = ectab; ee->name; ee++) {
ec_info ei;
+ printf(" %s: ", ee->name);
+ fflush(stdout);
getinfo(&ei, ee->data);
e = ec_checkinfo(&ei, gr);
ec_freeinfo(&ei);
if (e) {
- fprintf(stderr, "\n*** curve %s fails: %s\n", ee->name, e);
+ printf("fails: %s\n", e);
ok = 0;
- }
- putchar('.');
+ } else
+ fputs("ok\n", stdout);
fflush(stdout);
}
- fputs(ok ? " ok\n" : " failed\n", stdout);
+ if (ok)
+ fputs("all ok\n", stdout);
}
gr->ops->destroy(gr);
return (!ok);
/* -*-c-*-
*
- * $Id: ec-prime.c,v 1.11 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
*
* Elliptic curves over prime fields
*
}
static const ec_ops ec_primeops = {
+ "prime",
ecdestroy, ec_stdsamep, ec_idin, ec_idout, ec_idfix,
ecfind, ecneg, ecadd, ec_stdsub, ecdbl, eccheck
};
static const ec_ops ec_primeprojops = {
+ "primeproj",
ecdestroy, ec_stdsamep, ec_projin, ec_projout, ec_projfix,
ecfind, ecneg, ecprojadd, ec_stdsub, ecprojdbl, ecprojcheck
};
static const ec_ops ec_primeprojxops = {
+ "primeproj",
ecdestroy, ec_stdsamep, ec_projin, ec_projout, ec_projfix,
ecfind, ecneg, ecprojadd, ec_stdsub, ecprojxdbl, ecprojcheck
};
}
static const ec_ops ecops = {
+ "cardboard",
ecDESTROY, ecSAMEP, ecIN, ecOUT, ecFIX,
ecFIND, ecNEG, ecADD, ecSUB, ecDBL, ecCHECK
};
/* -*-c-*-
*
- * $Id: ec.h,v 1.11 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
*
* Elliptic curve definitions
*
*/
typedef struct ec_ops {
+ const char *name;
void (*destroy)(ec_curve */*c*/);
int (*samep)(ec_curve */*c*/, ec_curve */*d*/);
ec *(*in)(ec_curve */*c*/, ec */*d*/, const ec */*p*/);
int (*check)(ec_curve */*c*/, const ec */*p*/);
} ec_ops;
+#define EC_NAME(c) (c)->ops->name
+
#define EC_SAMEP(c, d) (c)->ops->samep((c), (d))
#define EC_IN(c, d, p) (c)->ops->in((c), (d), (p))
#define EC_OUT(c, d, p) (c)->ops->out((c), (d), (p))
#include <mLib/sub.h>
#include "field.h"
-#include "gf.h"
-#include "gfreduce.h"
+#include "field-guts.h"
#include "mprand.h"
-#include "gfn.h"
/*----- Polynomial basis --------------------------------------------------*/
-typedef struct fctx {
- field f;
- gfreduce r;
-} fctx;
-
/* --- Field operations --- */
-static void fdestroy(field *ff)
- { fctx *f = (fctx *)ff; gfreduce_destroy(&f->r); DESTROY(f); }
+static void fdestroy(field *ff) {
+ fctx_binpoly *f = (fctx_binpoly *)ff;
+ gfreduce_destroy(&f->r);
+ DESTROY(f);
+}
-static mp *frand(field *f, mp *d, grand *r)
- { return (mprand(d, f->nbits, r, 0)); }
+static mp *frand(field *f, mp *d, grand *r) {
+ return (mprand(d, f->nbits, r, 0));
+}
static int fzerop(field *ff, mp *x) { return (MP_ZEROP(x)); }
static mp *fadd(field *ff, mp *d, mp *x, mp *y) { return (gf_add(d, x, y)); }
static mp *fmul(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = gf_mul(d, x, y);
+ fctx_binpoly *f = (fctx_binpoly *)ff; d = gf_mul(d, x, y);
return (gfreduce_do(&f->r, d, d));
}
static mp *fsqr(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = gf_sqr(d, x);
+ fctx_binpoly *f = (fctx_binpoly *)ff; d = gf_sqr(d, x);
return (gfreduce_do(&f->r, d, d));
}
-static mp *finv(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; d = gf_modinv(d, x, f->r.p); return (d); }
+static mp *finv(field *ff, mp *d, mp *x) {
+ fctx_binpoly *f = (fctx_binpoly *)ff;
+ d = gf_modinv(d, x, f->r.p);
+ return (d);
+}
-static mp *freduce(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (gfreduce_do(&f->r, d, x)); }
+static mp *freduce(field *ff, mp *d, mp *x) {
+ fctx_binpoly *f = (fctx_binpoly *)ff;
+ return (gfreduce_do(&f->r, d, x));
+}
-static mp *fsqrt(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (gfreduce_sqrt(&f->r, d, x)); }
+static mp *fsqrt(field *ff, mp *d, mp *x) {
+ fctx_binpoly *f = (fctx_binpoly *)ff;
+ return (gfreduce_sqrt(&f->r, d, x));
+}
-static mp *fquadsolve(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (gfreduce_quadsolve(&f->r, d, x)); }
+static mp *fquadsolve(field *ff, mp *d, mp *x) {
+ fctx_binpoly *f = (fctx_binpoly *)ff;
+ return (gfreduce_quadsolve(&f->r, d, x));
+}
/* --- Field operations table --- */
field *field_binpoly(mp *p)
{
- fctx *f = CREATE(fctx);
+ fctx_binpoly *f = CREATE(fctx_binpoly);
f->f.ops = &fops;
f->f.zero = MP_ZERO;
f->f.one = MP_ONE;
/*----- Normal basis ------------------------------------------------------*/
-typedef struct fnctx {
- fctx f;
- gfn ntop, pton;
-} fnctx;
-
/* --- Field operations --- */
static void fndestroy(field *ff) {
- fnctx *f = (fnctx *)ff; gfreduce_destroy(&f->f.r);
+ fctx_binnorm *f = (fctx_binnorm *)ff; gfreduce_destroy(&f->f.r);
gfn_destroy(&f->ntop); gfn_destroy(&f->pton);
DESTROY(f);
}
static int fnsamep(field *ff, field *gg) {
- fnctx *f = (fnctx *)ff, *g = (fnctx *)gg;
+ fctx_binnorm *f = (fctx_binnorm *)ff, *g = (fctx_binnorm *)gg;
return (MP_EQ(f->ntop.r[0], g->ntop.r[0]) && field_stdsamep(ff, gg));
}
-static mp *fnin(field *ff, mp *d, mp *x)
- { fnctx *f = (fnctx *)ff; return (gfn_transform(&f->ntop, d, x)); }
+static mp *fnin(field *ff, mp *d, mp *x) {
+ fctx_binnorm *f = (fctx_binnorm *)ff;
+ return (gfn_transform(&f->ntop, d, x));
+}
-static mp *fnout(field *ff, mp *d, mp *x)
- { fnctx *f = (fnctx *)ff; return (gfn_transform(&f->pton, d, x)); }
+static mp *fnout(field *ff, mp *d, mp *x) {
+ fctx_binnorm *f = (fctx_binnorm *)ff;
+ return (gfn_transform(&f->pton, d, x));
+}
/* --- Field operations table --- */
field *field_binnorm(mp *p, mp *beta)
{
- fnctx *f = CREATE(fnctx);
+ fctx_binnorm *f = CREATE(fctx_binnorm);
f->f.f.ops = &fnops;
f->f.f.zero = MP_ZERO;
f->f.f.one = MP_ONE;
#include <mLib/sub.h>
#include "field.h"
-#include "mpreduce.h"
+#include "field-guts.h"
#include "mprand.h"
/*----- Main code ---------------------------------------------------------*/
-typedef struct fctx {
- field f;
- mpreduce r;
-} fctx;
-
/* --- Field operations --- */
-static void fdestroy(field *ff)
- { fctx *f = (fctx *)ff; mpreduce_destroy(&f->r); DESTROY(f); }
+static void fdestroy(field *ff) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ mpreduce_destroy(&f->r);
+ DESTROY(f);
+}
-static mp *frand(field *ff, mp *d, grand *r)
- { fctx *f = (fctx *)ff; return (mprand_range(d, f->r.p, r, 0)); }
+static mp *frand(field *ff, mp *d, grand *r) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ return (mprand_range(d, f->r.p, r, 0));
+}
static int fzerop(field *ff, mp *x) { return (MP_ZEROP(x)); }
-static mp *fneg(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (mp_sub(d, f->r.p, x)); }
+static mp *fneg(field *ff, mp *d, mp *x) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ return (mp_sub(d, f->r.p, x));
+}
static mp *fadd(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = mp_add(d, x, y);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_add(d, x, y);
if (MP_NEGP(d)) d = mp_add(d, d, f->r.p);
else if (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
return (d);
}
static mp *fsub(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = mp_sub(d, x, y);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_sub(d, x, y);
if (MP_NEGP(d)) d = mp_add(d, d, f->r.p);
else if (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
return (d);
}
static mp *fmul(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = mp_mul(d, x, y);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_mul(d, x, y);
return (mpreduce_do(&f->r, d, d));
}
static mp *fsqr(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_sqr(d, x);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_sqr(d, x);
return (mpreduce_do(&f->r, d, d));
}
-static mp *finv(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; d = mp_modinv(d, x, f->r.p); return (d); }
+static mp *finv(field *ff, mp *d, mp *x) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ d = mp_modinv(d, x, f->r.p);
+ return (d);
+}
-static mp *freduce(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (mpreduce_do(&f->r, d, x)); }
+static mp *freduce(field *ff, mp *d, mp *x) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ return (mpreduce_do(&f->r, d, x));
+}
-static mp *fsqrt(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (mp_modsqrt(d, x, f->r.p)); }
+static mp *fsqrt(field *ff, mp *d, mp *x) {
+ fctx_niceprime *f = (fctx_niceprime *)ff;
+ return (mp_modsqrt(d, x, f->r.p));
+}
static mp *fdbl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_lsl(d, x, 1);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_lsl(d, x, 1);
if (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
return (d);
}
static mp *ftpl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; MP_DEST(d, MP_LEN(x) + 1, x->f);
+ fctx_niceprime *f = (fctx_niceprime *)ff; MP_DEST(d, MP_LEN(x) + 1, x->f);
MPX_UMULN(d->v, d->vl, x->v, x->vl, 3);
while (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
return (d);
}
static mp *fqdl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_lsl(d, x, 2);
+ fctx_niceprime *f = (fctx_niceprime *)ff; d = mp_lsl(d, x, 2);
while (MP_CMP(d, >, f->r.p)) d = mp_sub(d, d, f->r.p);
return (d);
}
static mp *fhlv(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff;
+ fctx_niceprime *f = (fctx_niceprime *)ff;
if (MP_ZEROP(x)) { MP_COPY(x); MP_DROP(d); return (x); }
if (x->v[0] & 1) { d = mp_add(d, x, f->r.p); x = d; }
return (mp_lsr(d, x, 1));
field *field_niceprime(mp *p)
{
- fctx *f = CREATE(fctx);
+ fctx_niceprime *f = CREATE(fctx_niceprime);
f->f.ops = &fops;
f->f.zero = MP_ZERO;
f->f.one = MP_ONE;
#include <mLib/sub.h>
#include "field.h"
-#include "mpmont.h"
#include "mprand.h"
+#include "field-guts.h"
/*----- Main code ---------------------------------------------------------*/
-typedef struct fctx {
- field f;
- mpmont mm;
-} fctx;
-
/* --- Field operations --- */
-static void fdestroy(field *ff)
- { fctx *f = (fctx *)ff; mpmont_destroy(&f->mm); DESTROY(f); }
+static void fdestroy(field *ff) {
+ fctx_prime *f = (fctx_prime *)ff;
+ mpmont_destroy(&f->mm);
+ DESTROY(f);
+}
-static mp *frand(field *ff, mp *d, grand *r)
- { fctx *f = (fctx *)ff; return (mprand_range(d, f->mm.m, r, 0)); }
+static mp *frand(field *ff, mp *d, grand *r) {
+ fctx_prime *f = (fctx_prime *)ff;
+ return (mprand_range(d, f->mm.m, r, 0));
+}
static mp *fin(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff;
+ fctx_prime *f = (fctx_prime *)ff;
mp_div(0, &d, x, f->mm.m);
return (mpmont_mul(&f->mm, d, d, f->mm.r2));
}
-static mp *fout(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (mpmont_reduce(&f->mm, d, x)); }
+static mp *fout(field *ff, mp *d, mp *x) {
+ fctx_prime *f = (fctx_prime *)ff;
+ return (mpmont_reduce(&f->mm, d, x));
+}
static int fzerop(field *ff, mp *x) { return (MP_ZEROP(x)); }
-static mp *fneg(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; return (mp_sub(d, f->mm.m, x)); }
+static mp *fneg(field *ff, mp *d, mp *x) {
+ fctx_prime *f = (fctx_prime *)ff;
+ return (mp_sub(d, f->mm.m, x));
+}
static mp *fadd(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = mp_add(d, x, y);
+ fctx_prime *f = (fctx_prime *)ff; d = mp_add(d, x, y);
if (MP_NEGP(d)) d = mp_add(d, d, f->mm.m);
else if (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
return (d);
}
static mp *fsub(field *ff, mp *d, mp *x, mp *y) {
- fctx *f = (fctx *)ff; d = mp_sub(d, x, y);
+ fctx_prime *f = (fctx_prime *)ff; d = mp_sub(d, x, y);
if (MP_NEGP(d)) d = mp_add(d, d, f->mm.m);
else if (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
return (d);
}
-static mp *fmul(field *ff, mp *d, mp *x, mp *y)
- { fctx *f = (fctx *)ff; return (mpmont_mul(&f->mm, d, x, y)); }
+static mp *fmul(field *ff, mp *d, mp *x, mp *y) {
+ fctx_prime *f = (fctx_prime *)ff;
+ return (mpmont_mul(&f->mm, d, x, y));
+}
static mp *fsqr(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_sqr(d, x);
+ fctx_prime *f = (fctx_prime *)ff; d = mp_sqr(d, x);
return (mpmont_reduce(&f->mm, d, d));
}
static mp *finv(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mpmont_reduce(&f->mm, d, x);
+ fctx_prime *f = (fctx_prime *)ff; d = mpmont_reduce(&f->mm, d, x);
d = mp_modinv(d, d, f->mm.m); return (mpmont_mul(&f->mm, d, d, f->mm.r2));
}
-static mp *freduce(field *ff, mp *d, mp *x)
- { fctx *f = (fctx *)ff; mp_div(0, &d, x, f->mm.m); return (d); }
+static mp *freduce(field *ff, mp *d, mp *x) {
+ fctx_prime *f = (fctx_prime *)ff;
+ mp_div(0, &d, x, f->mm.m);
+ return (d);
+}
static mp *fsqrt(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mpmont_reduce(&f->mm, d, x);
+ fctx_prime *f = (fctx_prime *)ff; d = mpmont_reduce(&f->mm, d, x);
d = mp_modsqrt(d, d, f->mm.m); if (!d) return (d);
return (mpmont_mul(&f->mm, d, d, f->mm.r2));
}
static mp *fdbl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_lsl(d, x, 1);
+ fctx_prime *f = (fctx_prime *)ff; d = mp_lsl(d, x, 1);
if (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
return (d);
}
static mp *ftpl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; MP_DEST(d, MP_LEN(x) + 1, x->f);
+ fctx_prime *f = (fctx_prime *)ff; MP_DEST(d, MP_LEN(x) + 1, x->f);
MPX_UMULN(d->v, d->vl, x->v, x->vl, 3);
while (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
return (d);
}
static mp *fqdl(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff; d = mp_lsl(d, x, 2);
+ fctx_prime *f = (fctx_prime *)ff; d = mp_lsl(d, x, 2);
while (MP_CMP(d, >, f->mm.m)) d = mp_sub(d, d, f->mm.m);
return (d);
}
static mp *fhlv(field *ff, mp *d, mp *x) {
- fctx *f = (fctx *)ff;
+ fctx_prime *f = (fctx_prime *)ff;
if (MP_ZEROP(x)) { MP_COPY(x); MP_DROP(d); return (x); }
if (x->v[0] & 1) { d = mp_add(d, x, f->mm.m); x = d; }
return (mp_lsr(d, x, 1));
field *field_prime(mp *p)
{
- fctx *f;
+ fctx_prime *f;
if (!MP_POSP(p) || !MP_ODDP(p))
return (0);
- f = CREATE(fctx);
+ f = CREATE(fctx_prime);
f->f.ops = &fops;
mpmont_create(&f->mm, p);
f->f.zero = MP_ZERO;
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Internal structures for built-in fields
+ *
+ * (c) 2004 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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.
+ */
+
+#ifndef CATACOMB_FIELD_GUTS_H
+#define CATACOMB_FIELD_GUTS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef CATACOMB_MP_H
+# include "mp.h"
+#endif
+
+#ifndef CATACOMB_EC_H
+# include "ec.h"
+#endif
+
+#ifndef CATACOMB_MPMONT_H
+# include "mpmont.h"
+#endif
+
+#ifndef CATACOMB_MPREDUCE_H
+# include "mpreduce.h"
+#endif
+
+#ifndef CATACOMB_GF_H
+# include "gf.h"
+#endif
+
+#ifndef CATACOMB_GFN_H
+# include "gfn.h"
+#endif
+
+#ifndef CATACOMB_GFREDUCE_H
+# include "gfreduce.h"
+#endif
+
+#ifndef CATACOMB_FIELD_H
+# include "field.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct fctx_prime {
+ field f;
+ mpmont mm;
+} fctx_prime;
+
+typedef struct fctx_niceprime {
+ field f;
+ mpreduce r;
+} fctx_niceprime;
+
+typedef struct fctx_binpoly {
+ field f;
+ gfreduce r;
+} fctx_binpoly;
+
+typedef struct fctx_binnorm {
+ fctx_binpoly f;
+ gfn ntop, pton;
+} fctx_binnorm;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
/* -*-c-*-
*
- * $Id: g-ec.c,v 1.5 2004/04/17 09:58:37 mdw Exp $
+ * $Id$
*
* Abstraction for elliptic curve groups
*
#define ge ec
#include "group.h"
#include "ec-raw.h"
-
-/*----- Data structures ---------------------------------------------------*/
-
-typedef struct gctx {
- group g;
- ec id, gen;
- ec_info ei;
-} gctx;
+#include "group-guts.h"
/*----- Main code ---------------------------------------------------------*/
/* --- Group operations --- */
static void gdestroygroup(group *gg) {
- gctx *g = (gctx *)gg;
+ gctx_ec *g = (gctx_ec *)gg;
EC_DESTROY(&g->gen);
ec_freeinfo(&g->ei);
DESTROY(g);
static void gdestroy(group *gg, ec *x) { EC_DESTROY(x); DESTROY(x); }
static int gsamep(group *gg, group *hh) {
- gctx *g = (gctx *)gg, *h = (gctx *)hh;
+ gctx_ec *g = (gctx_ec *)gg, *h = (gctx_ec *)hh;
return (ec_sameinfop(&g->ei, &h->ei));
}
static int geq(group *gg, ec *x, ec *y) {
- gctx *g = (gctx *)gg; EC_FIX(g->ei.c, x, x); EC_FIX(g->ei.c, y, y);
+ gctx_ec *g = (gctx_ec *)gg; EC_FIX(g->ei.c, x, x); EC_FIX(g->ei.c, y, y);
return (EC_EQ(x, y));
}
static int gidentp(group *gg, ec *x) { return (EC_ATINF(x)); }
static const char *gcheck(group *gg, grand *gr)
- { gctx *g = (gctx *)gg; return (ec_checkinfo(&g->ei, gr)); }
+ { gctx_ec *g = (gctx_ec *)gg; return (ec_checkinfo(&g->ei, gr)); }
static void gmul(group *gg, ec *d, ec *x, ec *y)
- { gctx *g = (gctx *)gg; EC_ADD(g->ei.c, d, x, y); }
+ { gctx_ec *g = (gctx_ec *)gg; EC_ADD(g->ei.c, d, x, y); }
static void gsqr(group *gg, ec *d, ec *x)
- { gctx *g = (gctx *)gg; EC_DBL(g->ei.c, d, x); }
+ { gctx_ec *g = (gctx_ec *)gg; EC_DBL(g->ei.c, d, x); }
static void ginv(group *gg, ec *d, ec *x)
- { gctx *g = (gctx *)gg; EC_NEG(g->ei.c, d, x); }
+ { gctx_ec *g = (gctx_ec *)gg; EC_NEG(g->ei.c, d, x); }
static void gdiv(group *gg, ec *d, ec *x, ec *y)
- { gctx *g = (gctx *)gg; EC_SUB(g->ei.c, d, x, y); }
+ { gctx_ec *g = (gctx_ec *)gg; EC_SUB(g->ei.c, d, x, y); }
static void gexp(group *gg, ec *d, ec *x, mp *n)
- { gctx *g = (gctx *)gg; ec_imul(g->ei.c, d, x, n); }
+ { gctx_ec *g = (gctx_ec *)gg; ec_imul(g->ei.c, d, x, n); }
static void gmexp(group *gg, ec *d, const group_expfactor *f, size_t n) {
- gctx *g = (gctx *)gg; size_t i;
+ gctx_ec *g = (gctx_ec *)gg; size_t i;
ec_mulfactor *ff = xmalloc(n * sizeof(ec_mulfactor));
for (i = 0; i < n; i++) { ff[i].base = *f[i].base; ff[i].exp = f[i].exp; }
ec_immul(g->ei.c, d, ff, n); xfree(ff);
}
static int gread(group *gg, ec *d, const mptext_ops *ops, void *p) {
- gctx *g = (gctx *)gg;
+ gctx_ec *g = (gctx_ec *)gg;
ec t = EC_INIT;
int rc = -1;
int ch;
}
static int gwrite(group *gg, ec *x, const mptext_ops *ops, void *p) {
- gctx *g = (gctx *)gg; int rc = -1; ec t = EC_INIT; EC_OUT(g->ei.c, &t, x);
- if (EC_ATINF(&t)) rc = ops->put("inf", 3, p);
+ gctx_ec *g = (gctx_ec *)gg; int rc = -1; ec t = EC_INIT;
+ EC_OUT(g->ei.c, &t, x); if (EC_ATINF(&t)) rc = ops->put("inf", 3, p);
else if (!ops->put("0x", 2, p) && !mp_write(t.x, 16, ops, p) &&
!ops->put(", 0x", 4, p) && !mp_write(t.y, 16, ops, p)) rc = 0;
EC_DESTROY(&t); return (rc);
}
static mp *gtoint(group *gg, mp *d, ec *x) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; mp *i; if (EC_ATINF(x)) i = 0;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; mp *i; if (EC_ATINF(x)) i = 0;
else { EC_OUT(g->ei.c, &t, x); i = MP_COPY(t.x); EC_DESTROY(&t); }
mp_drop(d); return (i);
}
static int gfromint(group *gg, ec *d, mp *x) {
- gctx *g = (gctx *)gg; ec t = EC_INIT;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT;
if (!ec_find(g->ei.c, &t, x)) return (-1);
EC_IN(g->ei.c, d, &t); EC_DESTROY(&t); return (0);
}
static int gtoec(group *gg, ec *d, ec *x)
- { gctx *g = (gctx *)gg; EC_OUT(g->ei.c, d, x); return (0); }
+ { gctx_ec *g = (gctx_ec *)gg; EC_OUT(g->ei.c, d, x); return (0); }
static int gfromec(group *gg, ec *d, const ec *x) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; int rc; EC_IN(g->ei.c, &t, x);
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; int rc; EC_IN(g->ei.c, &t, x);
rc = EC_CHECK(g->ei.c, &t); if (!rc) EC_COPY(d, &t); EC_DESTROY(&t);
return (rc);
}
static int gtobuf(group *gg, buf *b, ec *x) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; int rc;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; int rc;
EC_OUT(g->ei.c, &t, x); rc = buf_putec(b, &t); EC_DESTROY(&t); return (rc);
}
static int gfrombuf(group *gg, buf *b, ec *d) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; int rc;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; int rc;
if (buf_getec(b, &t)) return (-1);
EC_IN(g->ei.c, &t, &t); rc = EC_CHECK(g->ei.c, &t);
if (!rc) EC_COPY(d, &t); EC_DESTROY(&t); return (rc);
}
static int gtoraw(group *gg, buf *b, ec *x) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; int rc;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; int rc;
EC_OUT(g->ei.c, &t, x); rc = ec_putraw(g->ei.c, b, &t);
EC_DESTROY(&t); return (rc);
}
static int gfromraw(group *gg, buf *b, ec *d) {
- gctx *g = (gctx *)gg; ec t = EC_INIT; int rc;
+ gctx_ec *g = (gctx_ec *)gg; ec t = EC_INIT; int rc;
if (ec_getraw(g->ei.c, b, &t)) return (-1);
EC_IN(g->ei.c, &t, &t); rc = EC_CHECK(g->ei.c, &t);
if (!rc) EC_COPY(d, &t); EC_DESTROY(&t); return (rc);
*/
static const group_ops gops = {
- GTY_EC,
+ GTY_EC, "ec",
gdestroygroup, gcreate, gcopy, gburn, gdestroy,
gsamep, geq, gidentp,
gcheck,
group *group_ec(const ec_info *ei)
{
- gctx *g = CREATE(gctx);
+ gctx_ec *g = CREATE(gctx_ec);
g->g.ops = &gops;
g->g.nbits = ei->c->f->nbits * 2;
#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);
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");
}
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);
+ 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, d, x, g->mm.m);
+ 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 *g = (gctx *)gg; octet *q; mp *t = mpmont_reduce(&g->mm, MP_NEW, *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 * g = (gctx *)gg; mp *x; octet *q;
+ 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);
*/
static const group_ops gops = {
- GTY_PRIME,
+ GTY_PRIME, "prime",
gdestroygroup, gcreate, gcopy, gburn, gdestroy,
gsamep, geq, group_stdidentp,
gcheck,
group *group_prime(const gprime_param *gp)
{
- gctx *g;
+ gctx_prime *g;
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;
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id$
+ *
+ * Internal structures for built-in groups
+ *
+ * (c) 2004 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software; you can redistribute it and/or modify
+ * 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.
+ */
+
+#ifndef CATACOMB_GROUP_GUTS_H
+#define CATACOMB_GROUP_GUTS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#ifndef CATACOMB_MP_H
+# include "mp.h"
+#endif
+
+#ifndef CATACOMB_EC_H
+# include "ec.h"
+#endif
+
+#ifndef CATACOMB_MPMONT_H
+# include "mpmont.h"
+#endif
+
+#ifndef CATACOMB_GROUP_H
+# include "group.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+typedef struct gctx_prime {
+ group g;
+ mp *gen;
+ mpmont mm;
+} gctx_prime;
+
+typedef struct gctx_ec {
+ group g;
+ ec id, gen;
+ ec_info ei;
+} gctx_ec;
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
/* -*-c-*-
*
- * $Id: group.h,v 1.5 2004/04/17 09:58:37 mdw Exp $
+ * $Id$
*
* General cyclic group abstraction
*
} group_expfactor;
typedef struct group_ops {
+
+ /* --- General information --- */
+
unsigned ty; /* Type of this group */
+ const char *name; /* Textual name string */
/* --- Memory management --- */
GTY_EC /* Elliptic curve group */
};
+#define G_NAME(g) (g)->ops->name
+#define G_TYPE(g) (g)->ops->ty
+
#define G_DESTROYGROUP(g) (g)->ops->destroygroup((g))
#define G_CREATE(g) (g)->ops->create((g))
#define G_COPY(g, d, x) (g)->ops->copy((g), (d), (x))
-# $Id: ptab.in,v 1.1 2004/04/01 12:50:09 mdw Exp $
+# $Id$
#
# Standard prime groups
#----- Groups from Oakley (RFC2412) -----------------------------------------
group oakley768
- p 1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919
- q 776259046150354467565459065629240877815667024717257156601175597451483119974551053629334726938295821221455003840144432114575401859459023171316363806515641491872190410445098144254585345658296587683734775881559921685818610503605288959
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31d1b107fffffffffffffff
g 2
group oakley1024
- p 179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194467627007
- q 89884656743115795385419578396893726598930148024378005853222211842098590108079259684473916897932462770751090282742990251823220274099619550025396438501677908319614776568119538254367879957411287431287503712651038723856294775478968889212221213308667363814649693834354602803025135405421453846466009564097233813503
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f67329c0ffffffffffffffff
g 2
group oakley1536
- p 2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919
- q 1205156213460516294276038011098783037428475274251229971327058470979054415841306114445046929130670807336613570738952006098251824478525291315971365353402504611531367372670536703348123007294680829887020513584624726600189364717085162921889329599071881596888429934762044470097788673059921772650773521873603874984881875042154463169647779984441228936206496905064565147296499973963182632029642323604865192473605840717232357219244260470063729922144429668263448160459816959
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba36046511b993ffffffffffffffff
+ g 2
+
+#----- Groups from RFC3526 --------------------------------------------------
+
+group oakley2048
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba36046511b993ffffffffffffffff
+ g 2
+
+group oakley3072
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba3604650c10be19482f23171b671df1cf3b960c074301cd93c1d17603d147dae2aef837a62964ef15e5fb4aac0b8c1ccaa4be754ab5728ae9130c4c7d02880ab9472d45556216d6998b8682283d19d42a90d5ef8e5d32767dc2822c6df785457538abae83063ed9cb87c2d370f263d5fad7466d8499eb8f464a702512b0cee771e9130d697735f897fd036cc504326c3b01399f643532290f958c0bbd90065df08babbd30aeb63b84c4605d6ca371047127d03a72d598a1edadfe707e884725c16890549d69657fffffffffffffff
+ g 2
+
+group oakley4096
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba3604650c10be19482f23171b671df1cf3b960c074301cd93c1d17603d147dae2aef837a62964ef15e5fb4aac0b8c1ccaa4be754ab5728ae9130c4c7d02880ab9472d45556216d6998b8682283d19d42a90d5ef8e5d32767dc2822c6df785457538abae83063ed9cb87c2d370f263d5fad7466d8499eb8f464a702512b0cee771e9130d697735f897fd036cc504326c3b01399f643532290f958c0bbd90065df08babbd30aeb63b84c4605d6ca371047127d03a72d598a1edadfe707e884725c16890549084008d391e0953c3f36bc438cd085edd2d934ce1938c357a711e0d4a341a5b0a85ed12c1f4e5156a26746ddde16d826f477c97477e0a0fdf6553143e2ca3a735e02eccd94b27d04861d1119dd0c328adf3f68fb094b867716bd7dc0deebb10b8240e68034893ead82d54c9da754c46c7eee0c37fdbee48536047a6fa1ae49a0318ccffffffffffffffff
+ g 2
+
+group oakley6144
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba3604650c10be19482f23171b671df1cf3b960c074301cd93c1d17603d147dae2aef837a62964ef15e5fb4aac0b8c1ccaa4be754ab5728ae9130c4c7d02880ab9472d45556216d6998b8682283d19d42a90d5ef8e5d32767dc2822c6df785457538abae83063ed9cb87c2d370f263d5fad7466d8499eb8f464a702512b0cee771e9130d697735f897fd036cc504326c3b01399f643532290f958c0bbd90065df08babbd30aeb63b84c4605d6ca371047127d03a72d598a1edadfe707e884725c16890549084008d391e0953c3f36bc438cd085edd2d934ce1938c357a711e0d4a341a5b0a85ed12c1f4e5156a26746ddde16d826f477c97477e0a0fdf6553143e2ca3a735e02eccd94b27d04861d1119dd0c328adf3f68fb094b867716bd7dc0deebb10b8240e68034893ead82d54c9da754c46c7eee0c37fdbee48536047a6fa1ae49a0142491b61fd5a693e381360ea6e593013236f64ba8f3b1edd1bdefc7fca0356cf298772ed9c17a09800d7583529f6c813ec188bcb93d8432d448c6d1f6df5e7cd8a76a267365d676a5d8dedbf8a23f36612a5999028a895ebd7a137dc7a009bc6695facc1e500e325c9767819750ae8b90e81fa416be7373a7f7b6aaf3817a34c06415ad42018c8058e4f2cf3e4bfdf63f47991d4bd3f1b66445f078ea2dbffac2d62a5ea03d915a0aa556647b6bf5fa470ec0a662f6907c01bf053cb8af7794df1940350eac5dbe2ed3b7aa8551ec50fdff8758ce658d189eaae6d2b64f617794b191c3ff46bb71e0234021f47b31fa43077095f96ad85ba3a6b734a7c8f36e620127fffffffffffffff
+ g 2
+
+group oakley8192
+ p 0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff
+ q 0x7fffffffffffffffe487ed5110b4611a62633145c06e0e68948127044533e63a0105df531d89cd9128a5043cc71a026ef7ca8cd9e69d218d98158536f92f8a1ba7f09ab6b6a8e122f242dabb312f3f637a262174d31bf6b585ffae5b7a035bf6f71c35fdad44cfd2d74f9208be258ff324943328f6722d9ee1003e5c50b1df82cc6d241b0e2ae9cd348b1fd47e9267afc1b2ae91ee51d6cb0e3179ab1042a95dcf6a9483b84b4b36b3861aa7255e4c0278ba3604650c10be19482f23171b671df1cf3b960c074301cd93c1d17603d147dae2aef837a62964ef15e5fb4aac0b8c1ccaa4be754ab5728ae9130c4c7d02880ab9472d45556216d6998b8682283d19d42a90d5ef8e5d32767dc2822c6df785457538abae83063ed9cb87c2d370f263d5fad7466d8499eb8f464a702512b0cee771e9130d697735f897fd036cc504326c3b01399f643532290f958c0bbd90065df08babbd30aeb63b84c4605d6ca371047127d03a72d598a1edadfe707e884725c16890549084008d391e0953c3f36bc438cd085edd2d934ce1938c357a711e0d4a341a5b0a85ed12c1f4e5156a26746ddde16d826f477c97477e0a0fdf6553143e2ca3a735e02eccd94b27d04861d1119dd0c328adf3f68fb094b867716bd7dc0deebb10b8240e68034893ead82d54c9da754c46c7eee0c37fdbee48536047a6fa1ae49a0142491b61fd5a693e381360ea6e593013236f64ba8f3b1edd1bdefc7fca0356cf298772ed9c17a09800d7583529f6c813ec188bcb93d8432d448c6d1f6df5e7cd8a76a267365d676a5d8dedbf8a23f36612a5999028a895ebd7a137dc7a009bc6695facc1e500e325c9767819750ae8b90e81fa416be7373a7f7b6aaf3817a34c06415ad42018c8058e4f2cf3e4bfdf63f47991d4bd3f1b66445f078ea2dbffac2d62a5ea03d915a0aa556647b6bf5fa470ec0a662f6907c01bf053cb8af7794df1940350eac5dbe2ed3b7aa8551ec50fdff8758ce658d189eaae6d2b64f617794b191c3ff46bb71e0234021f47b31fa43077095f96ad85ba3a6b734a7c8f36df08acba51c937897f72f21c3bbe5b54996fc66c5f626839dc98dd1de4195b46cee9803a0fd3dfc57e23f692bb7b49b5d212331d55b1ce2d727ab41a11da3a15f8e4bc11c78b65f1ceb296f1fedc5f7e42456c911117025201be0389f5abd40d11f8639a39fe3236751835a5e5e44317c1c2eefd4ea5bfd16043f43cb41981f6adee9d03159e7ad9d13c53369509fc1fa27c16ef9887703a55b51b22cbf44cd012aee0b2798e628423428efcd5a40caef6bf50d8ea885ebf73a6b9fd79b5e18f67d1341ac8237a75c3cfc92004a1c5a40e366bc44d00176af71c15e48c86d37e013723caac7223ab3bf4d54f1828713b2b4a6fe40fab74405cb738b064c06ecc76e9efffffffffffffffff
g 2
#----- Lim-Lee groups generated by hand -------------------------------------