X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/blobdiff_plain/80f7cd89bbb143dfa794e54be04994f55e851f7b..183e9cd31b1ac2f14b86c5de6ac2643b8a4364a2:/ec.c diff --git a/ec.c b/ec.c index 13b7798..da4cc34 100644 --- a/ec.c +++ b/ec.c @@ -204,8 +204,8 @@ static long ecpt_pyhash(PyObject *me) EC_OUT(ECPT_C(me), &p, ECPT_P(me)); ec_putraw(ECPT_C(me), &b, &p); EC_DESTROY(&p); - xfree(q); h = unihash_hash(&unihash_global, h, BBASE(&b), BLEN(&b)); + xfree(q); return (h % LONG_MAX); } @@ -290,6 +290,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:ectosp", 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)); } @@ -497,8 +525,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); @@ -617,7 +645,9 @@ 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@ */ @@ -656,6 +686,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 @@ -806,7 +837,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; @@ -824,11 +855,35 @@ 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[] = { "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: + return (rc); +} + 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; @@ -1042,7 +1097,7 @@ 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@ */ @@ -1096,7 +1151,8 @@ 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@ */ @@ -1150,7 +1206,8 @@ 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@ */ @@ -1204,7 +1261,8 @@ 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@ */ @@ -1258,7 +1316,8 @@ 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@ */ @@ -1463,7 +1522,7 @@ 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@ */ @@ -1492,6 +1551,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)")