X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/1ba83484ee5bb486da9aa958576de4bc29ef0c1d..34e4f738bcba58e6d8c4cabbb0b3232a65b42a9d:/ec-info.c diff --git a/ec-info.c b/ec-info.c index 8270c2e..a99cba5 100644 --- a/ec-info.c +++ b/ec-info.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: ec-info.c,v 1.1 2004/03/27 17:54:11 mdw Exp $ + * $Id: ec-info.c,v 1.2 2004/04/01 12:50:09 mdw Exp $ * * Elliptic curve information management * @@ -30,6 +30,13 @@ /*----- Revision history --------------------------------------------------* * * $Log: ec-info.c,v $ + * 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. * @@ -167,6 +174,42 @@ fail: return (0); } +/* --- @getinfo@ --- * + * + * Arguments: @ec_info *ei@ = where to write the information + * @ecdata *ed@ = raw data + * + * Returns: --- + * + * Use: Loads elliptic curve information about one of the standard + * curves. + */ + +static void getinfo(ec_info *ei, ecdata *ed) +{ + field *f; + + switch (ed->ftag) { + case FTAG_PRIME: + f = field_prime(&ed->p); + ei->c = ec_primeproj(f, &ed->a, &ed->b); + break; + case FTAG_NICEPRIME: + f = field_niceprime(&ed->p); + ei->c = ec_primeproj(f, &ed->a, &ed->b); + break; + case FTAG_BINPOLY: + f = field_binpoly(&ed->p); + ei->c = ec_binproj(f, &ed->a, &ed->b); + break; + default: + abort(); + } + + 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; +} + /* --- @ec_infoparse@ --- * * * Arguments: @qd_parse *qd@ = parser context @@ -176,7 +219,8 @@ fail: * Returns: Zero on success, nonzero on failure. * * Use: Parses an elliptic curve information string, and stores the - * information in @ei@. This has the form + * information in @ei@. This is either the name of a standard + * curve, or it has the form * * * elliptic curve description * * optional `/' @@ -192,14 +236,22 @@ int ec_infoparse(qd_parse *qd, ec_info *ei) ec_curve *c = 0; field *f; ec g = EC_INIT; + 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; + } + } 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; qd_delim(qd, '*'); if ((h = qd_getmp(qd)) == 0) goto fail; - ei->c = c; ei->g = g; ei->r = r; ei->h = h; + +found: return (0); fail: @@ -210,64 +262,6 @@ fail: return (-1); } -/* --- @getinfo@ --- * - * - * Arguments: @ec_info *ei@ = where to write the information - * @const ecdata *ed@ = raw data - * - * Returns: --- - * - * Use: Loads elliptic curve information about one of the standard - * curves. - */ - -static mp *getmp(const mpw *v, size_t n) -{ - mp *x = mp_new(n, 0); - memcpy(x->v, v, MPWS(n)); - return (x); -} - -static void getinfo(ec_info *ei, const ecdata *ed) -{ - field *f; - mp *p = 0, *a = 0, *b = 0; - - switch (ed->ftag) { - case FTAG_PRIME: - p = getmp(ed->p, ed->psz); - f = field_prime(p); - a = getmp(ed->a, ed->asz); b = getmp(ed->b, ed->bsz); - ei->c = ec_primeproj(f, a, b); - break; - case FTAG_NICEPRIME: - p = getmp(ed->p, ed->psz); - f = field_niceprime(p); - a = getmp(ed->a, ed->asz); b = getmp(ed->b, ed->bsz); - ei->c = ec_primeproj(f, a, b); - break; - case FTAG_BINPOLY: - p = getmp(ed->p, ed->psz); - f = field_binpoly(p); - a = getmp(ed->a, ed->asz); b = getmp(ed->b, ed->bsz); - ei->c = ec_binproj(f, a, b); - break; - default: - abort(); - } - - EC_CREATE(&ei->g); - ei->g.x = getmp(ed->gx, ed->gxsz); - ei->g.y = getmp(ed->gy, ed->gysz); - ei->g.z = 0; - ei->r = getmp(ed->r, ed->rsz); - ei->h = getmp(ed->h, ed->hsz); - - MP_DROP(p); - MP_DROP(a); - MP_DROP(b); -} - /* --- @ec_getinfo@ --- * * * Arguments: @ec_info *ei@ = where to write the information @@ -282,19 +276,11 @@ static void getinfo(ec_info *ei, const ecdata *ed) const char *ec_getinfo(ec_info *ei, const char *p) { qd_parse qd; - const ecentry *ee; qd.p = p; qd.e = 0; - for (ee = ectab; ee->name; ee++) { - if (qd_enum(&qd, ee->name) >= 0) { - getinfo(ei, ee->data); - goto found; - } - } if (ec_infoparse(&qd, ei)) return (qd.e); -found: if (!qd_eofp(&qd)) { ec_freeinfo(ei); return ("junk found at end of string"); @@ -302,6 +288,22 @@ found: return (0); } +/* --- @ec_sameinfop@ --- * + * + * Arguments: @ec_info *ei, *ej@ = two elliptic curve parameter sets + * + * Returns: Nonzero if the curves are identical (not just isomorphic). + * + * Use: Checks for sameness of curve parameters. + */ + +int ec_sameinfop(ec_info *ei, ec_info *ej) +{ + return (ec_samep(ei->c, ej->c) && + MP_EQ(ei->r, ej->r) && MP_EQ(ei->h, ej->h) && + EC_EQ(&ei->g, &ej->g)); +} + /* --- @ec_freeinfo@ --- * * * Arguments: @ec_info *ei@ = elliptic curve information block to free @@ -330,28 +332,6 @@ void ec_freeinfo(ec_info *ei) * Use: Checks an elliptic curve according to the rules in SEC1. */ -static int primep(mp *p, grand *gr) -{ - int i = rabin_iters(mp_bits(p)); - rabin r; - mp *x = MP_NEW; - - switch (pfilt_smallfactor(p)) { - case PGEN_DONE: return (1); - case PGEN_FAIL: return (0); - } - rabin_create(&r, p); - while (i) { - x = mprand_range(x, p, gr, 0); - if (rabin_rtest(&r, x) == PGEN_FAIL) - break; - i--; - } - MP_DROP(x); - rabin_destroy(&r); - return (!i); -} - static int primeeltp(mp *x, field *f) { return (!MP_ISNEG(x) && MP_CMP(x, <, f->m)); @@ -368,7 +348,7 @@ static const char *primecheck(const ec_info *ei, grand *gr) /* --- Check %$p$% is an odd prime --- */ - if (!primep(f->m, gr)) return ("p not prime"); + if (!pgen_primep(f->m, gr)) return ("p not prime"); /* --- Check %$a$%, %$b$%, %$G_x$% and %$G_y$% are in %$[0, p)$% --- */ @@ -399,7 +379,7 @@ static const char *primecheck(const ec_info *ei, grand *gr) /* --- Check %$r$% is prime --- */ - if (!primep(ei->r, gr)) return ("generator order not prime"); + if (!pgen_primep(ei->r, gr)) return ("generator order not prime"); /* --- Check %$0 < h \le 4$% --- */ @@ -486,7 +466,7 @@ static const char *bincheck(const ec_info *ei, grand *gr) /* --- Check %$r$% is prime --- */ - if (!primep(ei->r, gr)) return ("generator order not prime"); + if (!pgen_primep(ei->r, gr)) return ("generator order not prime"); /* --- Check %$0 < h \le 4$% --- */