X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/50bff227f550cbc564d7e2ec479351175a4643b1..1c6b925f0cf913ce3100c2ae3bcaed26a3f34bc1:/ec.c diff --git a/ec.c b/ec.c index 9946205..7fd369d 100644 --- a/ec.c +++ b/ec.c @@ -1,7 +1,5 @@ /* -*-c-*- * - * $Id$ - * * Elliptic curves * * (c) 2004 Straylight/Edgeware @@ -190,21 +188,26 @@ 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; + buf b; ec p = EC_INIT; + size_t sz = 2*ECPT_C(me)->f->noctets + 1; + octet *q = xmalloc(sz); + h = 0xe0fdd039 + ECPT_C(me)->f->ops->ty; + buf_init(&b, q, sz); 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; + ec_putraw(ECPT_C(me), &b, &p); EC_DESTROY(&p); - return (i); + h = unihash_hash(&unihash_global, h, BBASE(&b), BLEN(&b)); + xfree(q); + return (h % LONG_MAX); } static PyObject *ecpt_pyrichcompare(PyObject *x, PyObject *y, int op) @@ -288,6 +291,34 @@ 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; + int f = EC_EXPLY; + int len; + char *kwlist[] = { "flags", 0 }; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:ec2osp", kwlist, &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)); } @@ -389,9 +420,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; @@ -434,7 +465,7 @@ static int ecptxl_1(ec_curve *c, ec *p, PyObject *x) 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); @@ -495,8 +526,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); @@ -591,7 +622,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@ */ @@ -654,6 +685,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 @@ -705,7 +737,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@ */ @@ -756,10 +788,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)); @@ -804,7 +840,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; @@ -815,7 +851,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; + int f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY; + ec pp = EC_INIT; + char *kwlist[] = { "class", "buf", "flags", 0 }; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|f:os2ecp", kwlist, + &me, &p, &len, &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: @@ -826,7 +886,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; @@ -849,7 +909,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); @@ -914,7 +974,7 @@ static PyObject *eccurve_dopywrap(PyTypeObject *ty, cobj->ty.ht_type.tp_alloc = PyType_GenericAlloc; cobj->ty.ht_type.tp_free = 0; cobj->ty.ht_type.tp_new = ecpt_pynew; - PyType_Ready(&cobj->ty.ht_type); + typeready(&cobj->ty.ht_type); return ((PyObject *)cobj); } @@ -973,7 +1033,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); @@ -1017,7 +1077,7 @@ E.mmul([(P0, N0), (P1, N1), ...]) = N0 P0 + N1 P1 + ...") 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@ */ @@ -1071,7 +1131,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@ */ @@ -1125,7 +1185,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@ */ @@ -1179,7 +1239,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@ */ @@ -1233,7 +1293,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@ */ @@ -1353,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); @@ -1438,7 +1498,7 @@ static PyMethodDef ecinfo_pymethods[] = { 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@ */ @@ -1490,6 +1550,7 @@ static PyMethodDef methods[] = { #define METHNAME(func) meth_##func 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)") @@ -1529,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;