X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/46e6ad89d596d0987f00440c77e42c36f7d347f7..8fc76cc0e1dea41218fca11b3405183252e7f57f:/ec.c diff --git a/ec.c b/ec.c index 1666504..184dc9e 100644 --- a/ec.c +++ b/ec.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id$ - * * Elliptic curves * * (c) 2004 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the Python interface to Catacomb. * @@ -15,12 +13,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * Catacomb/Python 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 General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Catacomb/Python; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -190,34 +188,31 @@ static PyObject *ecpt_pymul(PyObject *x, PyObject *y) if (ECPT_PYCHECK(x)) { PyObject *t; t = x; x = y; y = t; } if (!ECPT_PYCHECK(y) || (xx = tomp(x)) == 0) RETURN_NOTIMPL; ec_imul(ECPT_C(y), &zz, ECPT_P(y), xx); + MP_DROP(xx); return (ecpt_pywrap(ECPT_COBJ(y), &zz)); } static long ecpt_pyhash(PyObject *me) { - long i; + uint32 h; ec p = EC_INIT; - EC_OUT(ECPT_C(me), &p, ECPT_P(me)); - i = 0xe0fdd039; /* random perturbance */ - if (p.x) i ^= mp_tolong(p.x); - if (p.y) i ^= mp_tolong(p.y); - if (i == -1) i = -2; + getecptout(&p, me); + if (EC_ATINF(&p)) h = 0x81d81a94; + else h = 0xe0fdd039 ^ (2*mphash(p.x)) ^ (3*mphash(p.y)); EC_DESTROY(&p); - return (i); + return (h%LONG_MAX); } static PyObject *ecpt_pyrichcompare(PyObject *x, PyObject *y, int op) { - ec_curve *c; - PyObject *cobj; ec p = EC_INIT, q = EC_INIT; int b; PyObject *rc = 0; - if (ecbinop(x, y, &c, &cobj, &p, &q)) RETURN_NOTIMPL; - EC_OUT(c, &p, &p); - EC_OUT(c, &q, &q); + if (!ECPT_PYCHECK(y)) RETURN_NOTIMPL; + getecptout(&p, x); + getecptout(&q, y); switch (op) { case Py_EQ: b = EC_EQ(&p, &q); break; case Py_NE: b = !EC_EQ(&p, &q); break; @@ -233,7 +228,8 @@ end: static PyObject *epmeth_oncurvep(PyObject *me, PyObject *arg) { if (!PyArg_ParseTuple(arg, ":oncurvep")) return (0); - return (getbool(!ec_check(ECPT_C(me), ECPT_P(me)))); + return (getbool(EC_ATINF(ECPT_P(me)) || + !EC_CHECK(ECPT_C(me), ECPT_P(me)))); } static PyObject *epmeth_dbl(PyObject *me, PyObject *arg) @@ -256,7 +252,7 @@ static PyObject *epmeth_tobuf(PyObject *me, PyObject *arg) if (EC_ATINF(&p)) n = 2; else - n = mp_octets(p.x) + mp_octets(p.y) + 4; + n = mp_octets(p.x) + mp_octets(p.y) + 6; rc = bytestring_pywrap(0, n); buf_init(&b, PyString_AS_STRING(rc), n); buf_putec(&b, &p); @@ -287,6 +283,35 @@ static PyObject *epmeth_toraw(PyObject *me, PyObject *arg) return (rc); } +static PyObject *epmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw) +{ + buf b; + PyObject *rc; + char *p; + ec_curve *c = ECPT_C(me); + ec pp = EC_INIT; + unsigned f = EC_EXPLY; + int len; + static const char *const kwlist[] = { "flags", 0 }; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:ec2osp", KWLIST, + convuint, &f)) + return (0); + len = c->f->noctets * 2 + 1; + rc = bytestring_pywrap(0, len); + p = PyString_AS_STRING(rc); + buf_init(&b, p, len); + EC_OUT(c, &pp, ECPT_P(me)); + if (ec_ec2osp(c, f, &b, &pp)) { + Py_DECREF(rc); rc = 0; + VALERR("invalid flags"); + } + EC_DESTROY(&pp); + _PyString_Resize(&rc, BLEN(&b)); +end: + return (rc); +} + static PyObject *epget_curve(PyObject *me, void *hunoz) { RETURN_OBJ(ECPT_COBJ(me)); } @@ -388,9 +413,9 @@ static int ecptxl_3(ec_curve *c, ec *p, if (!x || !y || !z) TYERR("missing argument"); if (!c) VALERR("internal form with no curve!"); - if ((p->x == coord_in(c->f, x)) == 0 || - (p->y == coord_in(c->f, y)) == 0 || - (z != Py_None && (p->z = coord_in(c->f, z))) == 0) + if ((p->x = coord_in(c->f, x)) == 0 || + (p->y = coord_in(c->f, y)) == 0 || + (z != Py_None && (p->z = coord_in(c->f, z)) == 0)) goto end; if (!p->z) p->z = MP_COPY(c->f->one); /* just in case */ rc = 0; @@ -428,19 +453,19 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x) getecptout(p, x); goto fix; } else if (PyString_Check(x)) { - if (PyObject_AsReadBuffer(x, &q, 0)) + if (PyObject_AsReadBuffer(x, &q, &n)) goto end; qd.p = q; qd.e = 0; if (!ec_ptparse(&qd, p)) - SYNERR(qd.e); + VALERR(qd.e); goto fix; } else if (c && (xx = tomp(x)) != 0) { xx = F_IN(c->f, xx, xx); if (!EC_FIND(c, p, xx)) VALERR("not on the curve"); } else if (PySequence_Check(x)) { t = x; x = 0; - n = PySequence_Size(t); + n = PySequence_Size(t); if (n < 0) goto end; if (n != 2 && (n != 3 || !c)) TYERR("want sequence of two or three items"); if ((x = PySequence_GetItem(t, 0)) == 0 || @@ -448,6 +473,7 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x) (n == 3 && (z = PySequence_GetItem(t, 2)) == 0)) goto end; rc = (n == 2) ? ecptxl_2(c, p, x, y) : ecptxl_3(c, p, x, y, z); + goto end; } else TYERR("can't convert to curve point"); goto ok; @@ -476,14 +502,14 @@ static PyObject *ecptnc_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { PyObject *x = 0, *y = 0, *z = 0; ec p = EC_INIT; - char *kwlist[] = { "x", "y", 0 }; + static const char *const kwlist[] = { "x", "y", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OO:new", kwlist, &x, &y) || + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OO:new", KWLIST, &x, &y) || ecptxl(0, &p, x, y, z)) goto end; return (ecpt_pywrapout(ty, &p)); end: - EC_DESTROY(&p); + mp_drop(p.x); mp_drop(p.y); mp_drop(p.z); return (0); } @@ -494,8 +520,8 @@ static PyObject *ecpt_pyint(PyObject *me) PyObject *rc = 0; if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity"); getecptout(&p, me); - if (mp_tolong_checked(p.x, &l)) goto end; - rc = PyInt_FromLong(l); + if (!mp_tolong_checked(p.x, &l, 0)) rc = PyInt_FromLong(l); + else rc = mp_topylong(p.x); end: EC_DESTROY(&p); return (rc); @@ -507,7 +533,7 @@ static PyObject *ecpt_pylong(PyObject *me) PyObject *rc = 0; if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity"); getecptout(&p, me); - rc = (PyObject *)mp_topylong(p.x); + rc = mp_topylong(p.x); end: EC_DESTROY(&p); return (rc); @@ -517,15 +543,15 @@ static PyObject *ecpt_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { PyObject *x = 0, *y = 0, *z = 0; ec p = EC_INIT; - char *kwlist[] = { "x", "y", "z", 0 }; + static const char *const kwlist[] = { "x", "y", "z", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OOO:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OOO:new", KWLIST, &x, &y, &z) || ecptxl(ECCURVE_C(ty), &p, x, y, z)) goto end; return (ecpt_pywrap((PyObject *)ty, &p)); end: - EC_DESTROY(&p); + mp_drop(p.x); mp_drop(p.y); mp_drop(p.z); return (0); } @@ -590,7 +616,7 @@ static PyNumberMethods ecpt_pynumber = { static PyTypeObject ecpt_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECPt", /* @tp_name@ */ + "ECPt", /* @tp_name@ */ sizeof(ecpt_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -614,14 +640,16 @@ static PyTypeObject ecpt_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Elliptic curve points, not associated with any curve.", +"ECPt([X, [Y]]): elliptic curve points, not associated with any curve.\n\ + X alone may be None, an existing point, a string 'X, Y', an\n\ + x-coordinate, or a pair (X, Y); X and Y should be a coordinate pair.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ ecpt_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ ecptnc_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ ecptnc_pygetset, /* @tp_getset@ */ @@ -653,6 +681,7 @@ static PyGetSetDef ecpt_pygetset[] = { static PyMethodDef ecpt_pymethods[] = { #define METHNAME(func) epmeth_##func METH (toraw, "X.toraw() -> BIN") + KWMETH(ec2osp, "X.ec2osp([flags = EC_EXPLY]) -> BIN") METH (dbl, "X.dbl() -> X + X") METH (oncurvep, "X.oncurvep() -> BOOL") #undef METHNAME @@ -704,7 +733,7 @@ static PyNumberMethods ecptcurve_pynumber = { static PyTypeObject ecptcurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECPtCurve", /* @tp_name@ */ + "ECPtCurve", /* @tp_name@ */ sizeof(ecpt_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -735,7 +764,7 @@ static PyTypeObject ecptcurve_pytype_skel = { 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ ecpt_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ ecpt_pygetset, /* @tp_getset@ */ @@ -755,10 +784,14 @@ static PyTypeObject ecptcurve_pytype_skel = { static PyObject *eccurve_pyrichcompare(PyObject *x, PyObject *y, int op) { - int b = ec_samep(ECCURVE_C(x), ECCURVE_C(y)); + int b; + + assert(ECCURVE_PYCHECK(x)); + if (!ECCURVE_PYCHECK(y)) RETURN_NOTIMPL; + b = ec_samep(ECCURVE_C(x), ECCURVE_C(y)); switch (op) { case Py_EQ: break; - case Py_NE: b = !b; + case Py_NE: b = !b; break; default: TYERR("can't order elliptic curves"); } return (getbool(b)); @@ -773,10 +806,10 @@ static int ecmmul_fill(void *pp, PyObject *me, PyObject *x, PyObject *m) { ec_mulfactor *f = pp; + EC_CREATE(&f->base); if (getecpt(ECCURVE_C(me), &f->base, x) || (f->exp = getmp(m)) == 0) return (-1); - f->base = *ECPT_P(x); return (0); } @@ -803,7 +836,7 @@ static PyObject *ecmeth_mmul(PyObject *me, PyObject *arg) static PyObject *meth__ECPtCurve_fromraw(PyObject *me, PyObject *arg) { char *p; - int len; + Py_ssize_t len; buf b; PyObject *rc = 0; ec_curve *cc; @@ -814,7 +847,31 @@ static PyObject *meth__ECPtCurve_fromraw(PyObject *me, PyObject *arg) buf_init(&b, p, len); cc = ECCURVE_C(me); if (ec_getraw(cc, &b, &pp)) - SYNERR("bad point"); + VALERR("bad point"); + EC_IN(cc, &pp, &pp); + rc = Py_BuildValue("(NN)", ecpt_pywrap(me, &pp), bytestring_pywrapbuf(&b)); +end: + return (rc); +} + +static PyObject *meth__ECPtCurve_os2ecp(PyObject *me, + PyObject *arg, PyObject *kw) +{ + char *p; + Py_ssize_t len; + buf b; + PyObject *rc = 0; + ec_curve *cc; + unsigned f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY; + ec pp = EC_INIT; + static const char *const kwlist[] = { "class", "buf", "flags", 0 }; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|O&:os2ecp", KWLIST, + &me, &p, &len, convuint, &f)) + return (0); + buf_init(&b, p, len); + cc = ECCURVE_C(me); + if (ec_os2ecp(cc, f, &b, &pp)) VALERR("bad point"); EC_IN(cc, &pp, &pp); rc = Py_BuildValue("(NN)", ecpt_pywrap(me, &pp), bytestring_pywrapbuf(&b)); end: @@ -825,7 +882,7 @@ static PyObject *meth__ECPt_frombuf(PyObject *me, PyObject *arg) { buf b; char *p; - int sz; + Py_ssize_t sz; PyObject *rc = 0; ec pp = EC_INIT; @@ -848,7 +905,7 @@ static PyObject *meth__ECPt_parse(PyObject *me, PyObject *arg) if (!PyArg_ParseTuple(arg, "Os:parse", &me, &p)) goto end; qd.p = p; qd.e = 0; - if (!ec_ptparse(&qd, &pp)) SYNERR(qd.e); + if (!ec_ptparse(&qd, &pp)) VALERR(qd.e); rc = Py_BuildValue("(Ns)", ecpt_pywrapout(me, &pp), qd.p); end: return (rc); @@ -885,11 +942,11 @@ end: static PyObject *ecmeth_rand(PyObject *me, PyObject *arg, PyObject *kw) { - char *kwlist[] = { "rng", 0 }; + static const char *const kwlist[] = { "rng", 0 }; grand *r = &rand_global; ec p = EC_INIT; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:rand", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:rand", KWLIST, convgrand, &r)) return (0); ec_rand(ECCURVE_C(me), &p, r); @@ -903,17 +960,17 @@ static PyObject *eccurve_dopywrap(PyTypeObject *ty, eccurve_pyobj *cobj = newtype(ty, 0, c->ops->name); cobj->c = c; cobj->fobj = fobj; - cobj->ty.type.tp_basicsize = sizeof(ecpt_pyobj); - cobj->ty.type.tp_base = ecptcurve_pytype; + cobj->ty.ht_type.tp_basicsize = sizeof(ecpt_pyobj); + cobj->ty.ht_type.tp_base = ecptcurve_pytype; Py_INCREF(ecptcurve_pytype); - cobj->ty.type.tp_flags = (Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_CHECKTYPES | - Py_TPFLAGS_HEAPTYPE); - cobj->ty.type.tp_alloc = PyType_GenericAlloc; - cobj->ty.type.tp_free = 0; - cobj->ty.type.tp_new = ecpt_pynew; - PyType_Ready(&cobj->ty.type); + cobj->ty.ht_type.tp_flags = (Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_CHECKTYPES | + Py_TPFLAGS_HEAPTYPE); + cobj->ty.ht_type.tp_alloc = PyType_GenericAlloc; + cobj->ty.ht_type.tp_free = 0; + cobj->ty.ht_type.tp_new = ecpt_pynew; + typeready(&cobj->ty.ht_type); return ((PyObject *)cobj); } @@ -945,10 +1002,10 @@ static PyObject *eccurve_pynew(PyTypeObject *ty, { PyObject *fobj; PyObject *cobj = 0; - char *kwlist[] = { "field", "a", "b", 0 }; + static const char *const kwlist[] = { "field", "a", "b", 0 }; mp *aa = 0, *bb = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!OO", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O&O&", KWLIST, field_pytype, &fobj, convmp, &aa, convmp, &bb)) goto end; @@ -972,7 +1029,7 @@ static PyObject *meth__ECCurve_parse(PyObject *me, PyObject *arg) qd.p = p; qd.e = 0; if ((c = ec_curveparse(&qd)) == 0) - SYNERR(qd.e); + VALERR(qd.e); rc = eccurve_pywrap(0, c); end: return (rc); @@ -984,7 +1041,7 @@ static PyObject *ecget_name(PyObject *me, void *hunoz) static PyObject *ecget_a(PyObject *me, void *hunoz) { return (fe_pywrap(ECCURVE_FOBJ(me), MP_COPY(ECCURVE_C(me)->a))); } -static PyObject *ecget_b(PyObject *me, void *hunoz) +static PyObject *ecget_b(PyObject *me, void *hunoz) { return (fe_pywrap(ECCURVE_FOBJ(me), MP_COPY(ECCURVE_C(me)->b))); } static PyObject *ecget_field(PyObject *me, void *hunoz) @@ -1002,21 +1059,21 @@ static PyGetSetDef eccurve_pygetset[] = { GET (inf, "E.inf -> point at infinity of this curve") #undef GETSETNAME { 0 } -}; +}; static PyMethodDef eccurve_pymethods[] = { #define METHNAME(name) ecmeth_##name METH (mmul, "\ E.mmul([(P0, N0), (P1, N1), ...]) = N0 P0 + N1 P1 + ...") METH (find, "E.find(X) -> P") - KWMETH(rand, "E.rand(rng = rand) ->P") + KWMETH(rand, "E.rand([rng = rand]) -> P") #undef METHNAME { 0 } }; static PyTypeObject eccurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECCurve", /* @tp_name@ */ + "ECCurve", /* @tp_name@ */ sizeof(eccurve_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1039,14 +1096,14 @@ static PyTypeObject eccurve_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "An elliptic curve. Abstract class.", +"An elliptic curve. Abstract class.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ eccurve_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ eccurve_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ eccurve_pygetset, /* @tp_getset@ */ @@ -1070,7 +1127,7 @@ static PyObject *ecprimecurve_pynew(PyTypeObject *ty, static PyTypeObject ecprimecurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECPrimeCurve", /* @tp_name@ */ + "ECPrimeCurve", /* @tp_name@ */ sizeof(eccurve_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1093,14 +1150,15 @@ static PyTypeObject ecprimecurve_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "An elliptic curve over a prime field. Use ecprimeprojcurve.", +"ECPrimeCurve(FIELD, A, B): an elliptic curve over a prime field.\n\ + Use ECPrimeProjCurve instead.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ eccurve_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -1124,7 +1182,7 @@ static PyObject *ecprimeprojcurve_pynew(PyTypeObject *ty, static PyTypeObject ecprimeprojcurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECPrimeProjCurve", /* @tp_name@ */ + "ECPrimeProjCurve", /* @tp_name@ */ sizeof(eccurve_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1147,14 +1205,15 @@ static PyTypeObject ecprimeprojcurve_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "An elliptic curve over a prime field, using projective coordinates.", +"ECPrimeProjCurve(FIELD, A, B): an elliptic curve over a prime field\n\ + using projective coordinates.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ eccurve_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -1178,7 +1237,7 @@ static PyObject *ecbincurve_pynew(PyTypeObject *ty, static PyTypeObject ecbincurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECBinCurve", /* @tp_name@ */ + "ECBinCurve", /* @tp_name@ */ sizeof(eccurve_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1201,14 +1260,15 @@ static PyTypeObject ecbincurve_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "An elliptic curve over a binary field. Use ecbinprojcurve.", +"ECBinCurve(FIELD, A, B): an elliptic curve over a binary field.\n\ + Use ECBinProjCurve instead.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ eccurve_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -1232,7 +1292,7 @@ static PyObject *ecbinprojcurve_pynew(PyTypeObject *ty, static PyTypeObject ecbinprojcurve_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECBinProjCurve", /* @tp_name@ */ + "ECBinProjCurve", /* @tp_name@ */ sizeof(eccurve_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1255,14 +1315,15 @@ static PyTypeObject ecbinprojcurve_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "An elliptic curve over a binary field, using projective coordinates.", +"ECBinProjCurve(FIELD, A, B): an elliptic curve over a binary field,\n\ + using projective coordinates.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ eccurve_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -1316,10 +1377,10 @@ static PyObject *ecinfo_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { ec_info ei = { 0 }; PyObject *e, *g; - char *kwlist[] = { "curve", "G", "r", "h", 0 }; + static const char *const kwlist[] = { "curve", "G", "r", "h", 0 }; ecinfo_pyobj *rc = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!O&O&:new", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!O!O&O&:new", KWLIST, eccurve_pytype, &e, ecpt_pytype, &g, convmp, &ei.r, convmp, &ei.h)) goto end; @@ -1327,7 +1388,7 @@ static PyObject *ecinfo_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) TYERR("point not from this curve"); ei.c = ECCURVE_C(e); EC_CREATE(&ei.g); - EC_COPY(&ei.g, ECPT_P(g)); + EC_OUT(ei.c, &ei.g, ECPT_P(g)); rc = (ecinfo_pyobj *)ty->tp_alloc(ty, 0); rc->ei = ei; rc->cobj = e; @@ -1352,7 +1413,7 @@ static PyObject *meth__ECInfo_parse(PyObject *me, PyObject *arg) qd.p = p; qd.e = 0; if (ec_infoparse(&qd, &ei)) - SYNERR(qd.e); + VALERR(qd.e); rc = Py_BuildValue("(Ns)", ecinfo_pywrap(&ei), qd.p); end: return (rc); @@ -1387,11 +1448,11 @@ end: static PyObject *eimeth_check(PyObject *me, PyObject *arg, PyObject *kw) { - char *kwlist[] = { "rng", 0 }; + static const char *const kwlist[] = { "rng", 0 }; grand *r = &rand_global; const char *p; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:check", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:check", KWLIST, convgrand, &r)) goto end; if ((p = ec_checkinfo(ECINFO_EI(me), r)) != 0) @@ -1430,14 +1491,14 @@ static PyGetSetDef ecinfo_pygetset[] = { static PyMethodDef ecinfo_pymethods[] = { #define METHNAME(name) eimeth_##name - KWMETH(check, "I.check() -> None") + KWMETH(check, "I.check([rng = rand]) -> None") #undef METHNAME { 0 } }; static PyTypeObject ecinfo_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ECInfo", /* @tp_name@ */ + "ECInfo", /* @tp_name@ */ sizeof(ecinfo_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1460,14 +1521,14 @@ static PyTypeObject ecinfo_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "Elliptic curve domain parameters.", +"ECInfo(CURVE, G, R, H): elliptic curve domain parameters.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ ecinfo_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ ecinfo_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ ecinfo_pygetset, /* @tp_getset@ */ @@ -1487,12 +1548,13 @@ static PyTypeObject ecinfo_pytype_skel = { static PyMethodDef methods[] = { #define METHNAME(func) meth_##func - METH (_ECPt_frombuf, "frombuf(E, STR) -> (P, REST)") - METH (_ECPtCurve_fromraw, "fromraw(E, STR) -> (P, REST)") - METH (_ECPt_parse, "parse(E, STR) -> (P, REST)") - METH (_ECCurve_parse, "parse(STR) -> (E, REST)") - METH (_ECInfo_parse, "parse(STR) -> (I, REST)") - METH (_ECInfo__curven, "_curven(N) -> I") + METH (_ECPt_frombuf, "frombuf(E, STR) -> (P, REST)") + METH (_ECPtCurve_fromraw, "fromraw(E, STR) -> (P, REST)") + KWMETH(_ECPtCurve_os2ecp, "os2ecp(E, STR, [flags = ...]) -> (P, REST)") + METH (_ECPt_parse, "parse(E, STR) -> (P, REST)") + METH (_ECCurve_parse, "parse(STR) -> (E, REST)") + METH (_ECInfo_parse, "parse(STR) -> (I, REST)") + METH (_ECInfo__curven, "_curven(N) -> I") #undef METHNAME { 0 } }; @@ -1528,7 +1590,7 @@ static PyObject *namedcurves(void) } c = PyInt_FromLong(i); found: - PyDict_SetItemString(d, (/*unconst*/ char *)ectab[i].name, c); + PyDict_SetItemString(d, (/*unconst*/ char *)p, c); Py_DECREF(c); } ncurves = i;