X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/4edc47b89bc56cd4041fdb0f4e8e892acd589ed8..389d822217b802003674d2085b3b902cbe13cf25:/ec-info.c diff --git a/ec-info.c b/ec-info.c index bcc0ab8..bf9607c 100644 --- a/ec-info.c +++ b/ec-info.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: ec-info.c,v 1.3 2004/04/01 21:28:41 mdw Exp $ + * $Id$ * * Elliptic curve information management * @@ -27,26 +27,6 @@ * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: ec-info.c,v $ - * Revision 1.3 2004/04/01 21:28:41 mdw - * Normal basis support (translates to poly basis internally). Rewrite - * EC and prime group table generators in awk, so that they can reuse data - * for repeated constants. - * - * Revision 1.2 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.) - * - * Revision 1.1 2004/03/27 17:54:11 mdw - * Standard curves and curve checking. - * - */ - /*----- Header files ------------------------------------------------------*/ #include "ec.h" @@ -54,6 +34,7 @@ #include "gf.h" #include "pgen.h" #include "mprand.h" +#include "mpint.h" #include "rabin.h" /*----- Main code ---------------------------------------------------------*/ @@ -131,6 +112,10 @@ ec_curve *ec_curveparse(qd_parse *qd) default: goto fail; } + if (!c) { + qd->e = "bad curve parameters"; + goto fail; + } if (a) MP_DROP(a); if (b) MP_DROP(b); return (c); @@ -215,6 +200,7 @@ static void getinfo(ec_info *ei, ecdata *ed) abort(); } + assert(f); assert(ei->c); EC_CREATE(&ei->g); ei->g.x = &ed->gx; ei->g.y = &ed->gy; ei->g.z = 0; ei->r = &ed->r; ei->h = &ed->h; } @@ -248,12 +234,9 @@ int ec_infoparse(qd_parse *qd, ec_info *ei) const ecentry *ee; mp *r = MP_NEW, *h = MP_NEW; - for (ee = ectab; ee->name; ee++) { - if (qd_enum(qd, ee->name) >= 0) { - getinfo(ei, ee->data); - goto found; - } - } + for (ee = ectab; ee->name; ee++) + if (qd_enum(qd, ee->name) >= 0) { getinfo(ei, ee->data); goto found; } + if ((c = ec_curveparse(qd)) == 0) goto fail; qd_delim(qd, '/'); if (!ec_ptparse(qd, &g)) goto fail; qd_delim(qd, ':'); if ((r = qd_getmp(qd)) == 0) goto fail; @@ -343,7 +326,7 @@ void ec_freeinfo(ec_info *ei) static int primeeltp(mp *x, field *f) { - return (!MP_ISNEG(x) && MP_CMP(x, <, f->m)); + return (!MP_NEGP(x) && MP_CMP(x, <, f->m)); } static const char *primecheck(const ec_info *ei, grand *gr) @@ -390,11 +373,6 @@ static const char *primecheck(const ec_info *ei, grand *gr) if (!pgen_primep(ei->r, gr)) return ("generator order not prime"); - /* --- Check %$0 < h \le 4$% --- */ - - if (MP_CMP(ei->h, <, MP_ONE) || MP_CMP(ei->h, >, MP_FOUR)) - return ("cofactor out of range"); - /* --- Check %$h = \lfloor (\sqrt{p} + 1)^2/r \rlfoor$% --- * * * This seems to work with the approximate-sqrt in the library, but might @@ -439,6 +417,11 @@ static const char *primecheck(const ec_info *ei, grand *gr) MP_DROP(x); if (i) return ("curve is weak"); + /* --- Check %$0 < h \le 4$% --- */ + + if (MP_CMP(ei->h, <, MP_ONE) || MP_CMP(ei->h, >, MP_FOUR)) + return ("cofactor out of range"); + /* --- Done --- */ return (0); @@ -453,6 +436,13 @@ static const char *bincheck(const ec_info *ei, grand *gr) ec p; int rc; + /* --- Check that %$m$% is prime --- */ + + x = mp_fromuint(MP_NEW, f->nbits); + rc = pfilt_smallfactor(x); + mp_drop(x); + if (rc != PGEN_DONE) return ("degree not prime"); + /* --- Check that %$p$% is irreducible --- */ if (!gf_irreduciblep(f->m)) return ("p not irreducible"); @@ -477,11 +467,6 @@ static const char *bincheck(const ec_info *ei, grand *gr) if (!pgen_primep(ei->r, gr)) return ("generator order not prime"); - /* --- Check %$0 < h \le 4$% --- */ - - if (MP_CMP(ei->h, <, MP_ONE) || MP_CMP(ei->h, >, MP_FOUR)) - return ("cofactor out of range"); - /* --- Check %$h = \lfloor (\sqrt{2^m} + 1)^2/r \rlfoor$% --- * * * This seems to work with the approximate-sqrt in the library, but might @@ -523,6 +508,11 @@ static const char *bincheck(const ec_info *ei, grand *gr) MP_DROP(x); if (i) return ("curve is weak"); + /* --- Check %$0 < h \le 4$% --- */ + + if (MP_CMP(ei->h, <, MP_ONE) || MP_CMP(ei->h, >, MP_FOUR)) + return ("cofactor out of range"); + /* --- Done --- */ return (0); @@ -543,29 +533,51 @@ const char *ec_checkinfo(const ec_info *ei, grand *gr) #include "fibrand.h" -int main(void) +int main(int argc, char *argv[]) { const ecentry *ee; const char *e; int ok = 1; + int i; grand *gr; gr = fibrand_create(0); - fputs("checking standard curves: ", stdout); - for (ee = ectab; ee->name; ee++) { - ec_info ei; - 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); - ok = 0; + if (argc > 1) { + for (i = 1; i < argc; i++) { + ec_info ei; + if ((e = ec_getinfo(&ei, argv[i])) != 0) + fprintf(stderr, "bad curve spec `%s': %s", argv[i], e); + else { + e = ec_checkinfo(&ei, gr); + ec_freeinfo(&ei); + if (!e) + printf("OK %s\n", argv[i]); + else { + printf("BAD %s: %s\n", argv[i], e); + ok = 0; + } + } + } + } else { + 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) { + printf("fails: %s\n", e); + ok = 0; + } else + fputs("ok\n", stdout); + fflush(stdout); } - putchar('.'); - fflush(stdout); + if (ok) + fputs("all ok\n", stdout); } gr->ops->destroy(gr); - fputs(ok ? " ok\n" : " failed\n", stdout); return (!ok); }