* Fix setting functions to check for null value (interpreted as property
deletion) and raise an exception or do something else useful.
* Fix conversion of read buffer to string so it returns the remainder
rather than the whole thing.
* Make conversions between MP and Python long work on PyObjects rather
than PyLongObjects, to eliminate pointless type casts.
* Fix primefield constructor argument parsing so that it doesn't crash!
* Fix radix checking in MP conversions to exclude +/-1, and 0 for output.
This turns into a little function now.
* Do argument checking on Jacobi function.
{ if (nn) *nn = BSZ(BUF_B(me)); return (1); }
static int rbuf_pyreadbuf(PyObject *me, int seg, void **q)
{ if (nn) *nn = BSZ(BUF_B(me)); return (1); }
static int rbuf_pyreadbuf(PyObject *me, int seg, void **q)
- { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BSZ(BUF_B(me))); }
+ { assert(seg == 0); *q = BCUR(BUF_B(me)); return (BLEFT(BUF_B(me))); }
static PyObject *rbmeth_skip(PyObject *me, PyObject *arg)
{
static PyObject *rbmeth_skip(PyObject *me, PyObject *arg)
{
static int rbset_offset(PyObject *me, PyObject *x, void *hunoz)
{
size_t n;
static int rbset_offset(PyObject *me, PyObject *x, void *hunoz)
{
size_t n;
+ if (!x) NIERR("__del__");
if (!convszt(x, &n)) goto end;
if (n > BSZ(BUF_B(me))) VALERR("out of range");
BCUR(BUF_B(me)) = BBASE(BUF_B(me)) + n;
if (!convszt(x, &n)) goto end;
if (n > BSZ(BUF_B(me))) VALERR("out of range");
BCUR(BUF_B(me)) = BBASE(BUF_B(me)) + n;
#define MP_PYCHECK(o) PyObject_TypeCheck((o), mp_pytype)
#define GF_PYCHECK(o) PyObject_TypeCheck((o), gf_pytype)
#define MP_PYCHECK(o) PyObject_TypeCheck((o), mp_pytype)
#define GF_PYCHECK(o) PyObject_TypeCheck((o), gf_pytype)
-extern mp *mp_frompylong(PyLongObject *);
-extern PyLongObject *mp_topylong(mp *);
+extern mp *mp_frompylong(PyObject *);
+extern PyObject *mp_topylong(mp *);
extern mp *tomp(PyObject *);
extern mp *getmp(PyObject *);
extern int convmp(PyObject *, void *);
extern mp *tomp(PyObject *);
extern mp *getmp(PyObject *);
extern int convmp(PyObject *, void *);
PyObject *rc = 0;
if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity");
getecptout(&p, me);
PyObject *rc = 0;
if (EC_ATINF(ECPT_P(me))) VALERR("point at infinity");
getecptout(&p, me);
- rc = (PyObject *)mp_topylong(p.x);
end:
EC_DESTROY(&p);
return (rc);
end:
EC_DESTROY(&p);
return (rc);
static PyObject *fe_pylong(PyObject *x)
{
mp *xx = F_OUT(FE_F(x), MP_NEW, FE_X(x));
static PyObject *fe_pylong(PyObject *x)
{
mp *xx = F_OUT(FE_F(x), MP_NEW, FE_X(x));
- PyObject *rc = (PyObject *)mp_topylong(xx);
+ PyObject *rc = mp_topylong(xx);
MP_DROP(xx);
return (rc);
}
MP_DROP(xx);
return (rc);
}
field *f;
char *kwlist[] = { "p", 0 };
field *f;
char *kwlist[] = { "p", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:primefield", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:primefield", kwlist,
convmp, &xx))
goto end;
if ((f = field_prime(xx)) == 0)
convmp, &xx))
goto end;
if ((f = field_prime(xx)) == 0)
{ "class", "pbits", "qbits", "seed", "event", "nsteps", 0 };
PyObject *rc = 0;
{ "class", "pbits", "qbits", "seed", "event", "nsteps", 0 };
PyObject *rc = 0;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:generate", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:gendsa", kwlist,
&me, convuint, &pl, convuint, &ql,
&k, &ksz, convpgev, &evt,
convuint, &steps))
&me, convuint, &pl, convuint, &ql,
&k, &ksz, convpgev, &evt,
convuint, &steps))
if ((x = G_TOINT(GE_G(me), MP_NEW, GE_X(me))) == 0)
TYERR("can't convert to integer");
if ((x = G_TOINT(GE_G(me), MP_NEW, GE_X(me))) == 0)
TYERR("can't convert to integer");
- rc = (PyObject *)mp_topylong(x);
end:
mp_drop(x);
return (rc);
end:
mp_drop(x);
return (rc);
PyTypeObject *mp_pytype = 0;
PyTypeObject *gf_pytype = 0;
PyTypeObject *mp_pytype = 0;
PyTypeObject *gf_pytype = 0;
-mp *mp_frompylong(PyLongObject *l)
+mp *mp_frompylong(PyObject *obj)
+ PyLongObject *l = (PyLongObject *)obj;
int sz;
size_t w;
mpd r = 0;
int sz;
size_t w;
mpd r = 0;
-PyLongObject *mp_topylong(mp *x)
+PyObject *mp_topylong(mp *x)
{
unsigned long bits = mp_bits(x);
int sz = (bits + SHIFT - 1)/SHIFT;
{
unsigned long bits = mp_bits(x);
int sz = (bits + SHIFT - 1)/SHIFT;
assert(MPW_BITS >= SHIFT);
while (i < sz && p < x->vl) {
assert(MPW_BITS >= SHIFT);
while (i < sz && p < x->vl) {
b += MPW_BITS;
while (i < sz && b >= SHIFT) {
l->ob_digit[i++] = r & MASK;
b += MPW_BITS;
while (i < sz && b >= SHIFT) {
l->ob_digit[i++] = r & MASK;
r >>= SHIFT;
}
l->ob_size = (x->f & MP_NEG) ? -sz : sz;
r >>= SHIFT;
}
l->ob_size = (x->f & MP_NEG) ? -sz : sz;
+ return ((PyObject *)l);
}
mp *mp_frompyobject(PyObject *o, int radix)
{
mp *x;
}
mp *mp_frompyobject(PyObject *o, int radix)
{
mp *x;
- if ((x = tomp(o)) != 0)
- return (x);
if (PyString_Check(o)) {
mptext_stringctx sc;
mp *x;
if (PyString_Check(o)) {
mptext_stringctx sc;
mp *x;
if (sc.buf < sc.lim) { MP_DROP(x); return (0); }
return (x);
}
if (sc.buf < sc.lim) { MP_DROP(x); return (0); }
return (x);
}
+ if ((x = tomp(o)) != 0)
+ return (x);
+static int good_radix_p(int r, int readp)
+{
+ return ((r >= -255 && r <= -2) ||
+ (readp && r == 0) ||
+ (r >= 2 && r <= 62));
+}
+
PyObject *mp_pywrap(mp *x)
{
mp_pyobj *z = PyObject_New(mp_pyobj, mp_pytype);
PyObject *mp_pywrap(mp *x)
{
mp_pyobj *z = PyObject_New(mp_pyobj, mp_pytype);
} else if (PyInt_Check(o))
return (mp_fromlong(MP_NEW, PyInt_AS_LONG(o)));
else if ((l = PyNumber_Long(o)) != 0) {
} else if (PyInt_Check(o))
return (mp_fromlong(MP_NEW, PyInt_AS_LONG(o)));
else if ((l = PyNumber_Long(o)) != 0) {
- x = mp_frompylong((PyLongObject *)l);
Py_DECREF(l);
return (x);
} else {
Py_DECREF(l);
return (x);
} else {
return (PyInt_FromLong(l));
}
static PyObject *mp_pylong(PyObject *x)
return (PyInt_FromLong(l));
}
static PyObject *mp_pylong(PyObject *x)
- { return (PyObject *)mp_topylong(MP_X(x)); }
+ { return (mp_topylong(MP_X(x))); }
static PyObject *mp_pyfloat(PyObject *x)
{
static PyObject *mp_pyfloat(PyObject *x)
{
- PyObject *l = (PyObject *)mp_topylong(MP_X(x));
+ PyObject *l = mp_topylong(MP_X(x));
double f = PyLong_AsDouble(l);
Py_DECREF(l);
return (PyFloat_FromDouble(f));
double f = PyLong_AsDouble(l);
Py_DECREF(l);
return (PyFloat_FromDouble(f));
int radix = 0;
char *kwlist[] = { "x", "radix", 0 };
int radix = 0;
char *kwlist[] = { "x", "radix", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:mp", kwlist, &x, &radix))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:new", kwlist, &x, &radix))
goto end;
if (MP_PYCHECK(x)) RETURN_OBJ(x);
goto end;
if (MP_PYCHECK(x)) RETURN_OBJ(x);
- if (radix < -255 || radix > 62) VALERR("radix out of range");
+ if (!good_radix_p(radix, 1)) VALERR("bad radix");
if ((z = mp_frompyobject(x, radix)) == 0) {
PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp",
x->ob_type->tp_name);
if ((z = mp_frompyobject(x, radix)) == 0) {
PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp",
x->ob_type->tp_name);
static long mp_pyhash(PyObject *me)
{
static long mp_pyhash(PyObject *me)
{
- long i = mp_tolong(MP_X(me));
- if (i == -1)
- i = -2;
- return (i);
+ long h;
+ PyObject *l = mp_topylong(MP_X(me)); h = PyObject_Hash(l);
+ Py_DECREF(l); return (h);
}
static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
}
static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
PyObject *z = 0;
if (!PyArg_ParseTuple(arg, "O&:jacobi", convmp, &y)) goto end;
PyObject *z = 0;
if (!PyArg_ParseTuple(arg, "O&:jacobi", convmp, &y)) goto end;
+ if (MP_NEGP(MP_X(me)) || MP_EVENP(MP_X(me)))
+ VALERR("must be positive and odd");
z = PyInt_FromLong(mp_jacobi(y, MP_X(me)));
end:
if (y) MP_DROP(y);
z = PyInt_FromLong(mp_jacobi(y, MP_X(me)));
end:
if (y) MP_DROP(y);
char *kwlist[] = { "radix", 0 };
if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:tostring", kwlist, &radix))
goto end;
char *kwlist[] = { "radix", 0 };
if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:tostring", kwlist, &radix))
goto end;
- if (radix < -255 || radix > 62 || radix == -1 || radix == 0 || radix == 1)
- VALERR("bad radix");
+ if (!good_radix_p(radix, 0)) VALERR("bad radix");
return (mp_topystring(MP_X(me), radix, 0, 0, 0));
end:
return (0);
return (mp_topystring(MP_X(me), radix, 0, 0, 0));
end:
return (0);
if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
kwlist, &me, &p, &len, &r))
goto end;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
kwlist, &me, &p, &len, &r))
goto end;
- if (r < -255 || r > 62) VALERR("radix out of range");
+ if (!good_radix_p(r, 1)) VALERR("bad radix");
sc.buf = p; sc.lim = p + len;
if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0)
SYNERR("bad integer");
sc.buf = p; sc.lim = p + len;
if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0)
SYNERR("bad integer");
if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:gf", kwlist, &x, &radix))
goto end;
if (GF_PYCHECK(x)) RETURN_OBJ(x);
if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|i:gf", kwlist, &x, &radix))
goto end;
if (GF_PYCHECK(x)) RETURN_OBJ(x);
- if (radix < -255 || radix > 62) VALERR("radix out of range");
+ if (!good_radix_p(radix, 1)) VALERR("radix out of range");
if ((z = mp_frompyobject(x, radix)) == 0) {
PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf",
x->ob_type->tp_name);
if ((z = mp_frompyobject(x, radix)) == 0) {
PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf",
x->ob_type->tp_name);
if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
kwlist, &me, &p, &len, &r))
goto end;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|i:fromstring",
kwlist, &me, &p, &len, &r))
goto end;
- if (r < -255 || r > 62) VALERR("radix out of range");
+ if (!good_radix_p(r, 1)) VALERR("radix out of range");
sc.buf = p; sc.lim = p + len;
if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0 || MP_NEGP(zz))
z = Py_BuildValue("(Os#)", Py_None, p, len);
sc.buf = p; sc.lim = p + len;
if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0 || MP_NEGP(zz))
z = Py_BuildValue("(Os#)", Py_None, p, len);
}
static PyObject *pfilt_pylong(PyObject *me)
}
static PyObject *pfilt_pylong(PyObject *me)
- { return ((PyObject *)mp_topylong(PFILT_F(me)->m)); }
+ { return (mp_topylong(PFILT_F(me)->m)); }
static PyObject *pfget_x(PyObject *me, void *hunoz)
{ return (mp_pywrap(MP_COPY(PFILT_F(me)->m))); }
static PyObject *pfget_x(PyObject *me, void *hunoz)
{ return (mp_pywrap(MP_COPY(PFILT_F(me)->m))); }
static int rsaset_rng(PyObject *me, PyObject *val, void *hunoz)
{
int rc = -1;
static int rsaset_rng(PyObject *me, PyObject *val, void *hunoz)
{
int rc = -1;
- if (val != Py_None && !GRAND_PYCHECK(val))
+ if (!val)
+ val = Py_None;
+ else if (val != Py_None && !GRAND_PYCHECK(val))
TYERR("expected grand or None");
Py_DECREF(RSA_RNG(me));
RSA_RNG(me) = val;
TYERR("expected grand or None");
Py_DECREF(RSA_RNG(me));
RSA_RNG(me) = val;
static int bbsset_x(PyObject *me, PyObject *val, void *hunoz)
{
static int bbsset_x(PyObject *me, PyObject *val, void *hunoz)
{
- mp *x = 0; grand *r = GRAND_R(me); int rc = -1;
+ mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!x) NIERR("__del__");
if ((x = getmp(val)) == 0) goto end; r->ops->misc(r, BBS_SET, x); rc = 0;
end: mp_drop(x); return (rc);
}
if ((x = getmp(val)) == 0) goto end; r->ops->misc(r, BBS_SET, x); rc = 0;
end: mp_drop(x); return (rc);
}