return (MP_COPY(PFILT_F(o)->m));
else if (ECPT_PYCHECK(o)) {
ec p = EC_INIT;
+ if (EC_ATINF(ECPT_P(o))) return (0);
getecptout(&p, o);
x = MP_COPY(p.x);
EC_DESTROY(&p);
static PyMethodDef mp_pymethods[] = {
#define METHNAME(func) mpmeth_##func
- METH (jacobi, "X.jacobi(Y) -> Jacobi symbol (Y/X) (NB inversion!)")
+ METH (jacobi, "X.jacobi(Y) -> Jacobi symbol (Y|X) (NB inversion!)")
METH (setbit, "X.setbit(N) -> X with bit N set")
METH (clearbit, "X.clearbit(N) -> X with bit N clear")
METH (testbit, "X.testbit(N) -> true/false if bit N set/clear in X")
METH (modsqrt, "X.modsqrt(Y) -> square root of Y mod X, if X prime")
METH (leastcongruent,
"X.leastcongruent(B, M) -> smallest Z >= B with Z == X (mod M)")
- KWMETH(primep, "X.primep(rng = rand) -> true/false if X is prime")
- KWMETH(tostring, "X.tostring(radix = 10) -> STR")
- KWMETH(storel, "X.storel(len = -1) -> little-endian bytes")
- KWMETH(storeb, "X.storeb(len = -1) -> big-endian bytes")
+ KWMETH(primep, "X.primep([rng = rand]) -> true/false if X is prime")
+ KWMETH(tostring, "X.tostring([radix = 10]) -> STR")
+ KWMETH(storel, "X.storel([len = -1]) -> little-endian bytes")
+ KWMETH(storeb, "X.storeb([len = -1]) -> big-endian bytes")
KWMETH(storel2c,
- "X.storel2c(len = -1) -> little-endian bytes, two's complement")
+ "X.storel2c([len = -1]) -> little-endian bytes, two's complement")
KWMETH(storeb2c,
- "X.storeb2c(len = -1) -> big-endian bytes, two's complement")
+ "X.storeb2c([len = -1]) -> big-endian bytes, two's complement")
METH (tobuf, "X.tobuf() -> buffer format")
#undef METHNAME
{ 0 }
implicit conversions from `PrimeFilter', and other objects which\n\
convert to `long'.\n\
\n\
-Constructor MP(X, radix = R) attempts to convert X to an `MP'. If\n\
+Constructor MP(X, [radix = R]) attempts to convert X to an `MP'. If\n\
X is a string, it's read in radix-R form, or we look for a prefix\n\
if R = 0. Other acceptable things are field elements, elliptic curve\n\
points, group elements, Python `int' and `long' objects, and anything\n\
PyObject *q = 0, *x, *z = 0;
mp *xx;
mp **v = 0;
- int i = 0, n = c->k;
+ Py_ssize_t i = 0, n = c->k;
Py_INCREF(me);
if (PyTuple_Size(arg) == n)
static PyObject *mpcrt_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
{
mpcrt_mod *v = 0;
- int n, i = 0;
+ Py_ssize_t n, i = 0, j;
char *kwlist[] = { "mv", 0 };
PyObject *q = 0, *x;
- mp *xx;
+ mp *xx = MP_NEW, *y = MP_NEW, *g = MP_NEW;
+ mpmul mm;
mpcrt_pyobj *c = 0;
if (PyTuple_Size(arg) > 1)
for (i = 0; i < n; i++) {
if ((x = PySequence_GetItem(q, i)) == 0) goto end;
xx = getmp(x); Py_DECREF(x); if (!xx) goto end;
- v[i].m = xx; v[i].n = 0; v[i].ni = 0; v[i].nni = 0;
+ if (MP_CMP(xx, <=, MP_ZERO)) VALERR("moduli must be positive");
+ v[i].m = xx; v[i].n = 0; v[i].ni = 0; v[i].nni = 0; xx = MP_NEW;
+ }
+ mpmul_init(&mm);
+ for (j = 0; j < i; j++) mpmul_add(&mm, v[j].m);
+ xx = mpmul_done(&mm);
+ for (j = 0; j < i; j++) {
+ mp_div(&y, 0, xx, v[j].m);
+ mp_gcd(&g, 0, 0, y, v[j].m);
+ if (!MP_EQ(g, MP_ONE)) VALERR("moduli must be pairwise coprime");
}
+
c = (mpcrt_pyobj *)ty->tp_alloc(ty, 0);
mpcrt_create(&c->c, v, n, 0);
Py_DECREF(q);
+ mp_drop(xx); mp_drop(y); mp_drop(g);
return ((PyObject *)c);
end:
xfree(v);
}
Py_XDECREF(q);
+ mp_drop(xx); mp_drop(y); mp_drop(g);
return (0);
}
METH (irreduciblep, "X.irreduciblep() -> true/false")
#undef METHNAME
#define METHNAME(func) mpmeth_##func
- KWMETH(tostring, "X.tostring(radix = 10) -> STR")
- KWMETH(storel, "X.storel(len = -1) -> little-endian bytes")
- KWMETH(storeb, "X.storeb(len = -1) -> big-endian bytes")
+ KWMETH(tostring, "X.tostring([radix = 10]) -> STR")
+ KWMETH(storel, "X.storel([len = -1]) -> little-endian bytes")
+ KWMETH(storeb, "X.storeb([len = -1]) -> big-endian bytes")
KWMETH(storel2c,
- "X.storel2c(len = -1) -> little-endian bytes, two's complement")
+ "X.storel2c([len = -1]) -> little-endian bytes, two's complement")
KWMETH(storeb2c,
- "X.storeb2c(len = -1) -> big-endian bytes, two's complement")
+ "X.storeb2c([len = -1]) -> big-endian bytes, two's complement")
METH (tobuf, "X.tobuf() -> buffer format")
#undef METHNAME
{ 0 }
"Binary polynomials. Support almost all the standard arithmetic\n\
operations.\n\
\n\
-Constructor GF(X, radix = R) attempts to convert X to a `GF'. If\n\
+Constructor GF(X, [radix = R]) attempts to convert X to a `GF'. If\n\
X is a string, it's read in radix-R form, or we look for a prefix\n\
if R = 0. Other acceptable things are field elements, elliptic curve\n\
points, group elements, Python `int' and `long' objects, and anything\n\
convgf, &p, convgf, &beta))
goto end;
gg = PyObject_New(gfn_pyobj, ty);
+ gg->p = 0;
if (gfn_create(p, beta, &gg->ntop, &gg->pton)) {
- FREEOBJ(gg);
+ Py_DECREF(gg);
gg = 0;
VALERR("can't invert transformation matrix");
}
end: \
mp_drop(xx); \
if (!z) return (0); \
- return (mp_pywrap(z)); \
+ return (gf_pywrap(z)); \
}
XFORMOP(pton, PTON)
XFORMOP(ntop, NTOP)
static void gfn_pydealloc(PyObject *me)
{
- gfn_destroy(GFN_PTON(me));
- gfn_destroy(GFN_NTOP(me));
+ if (GFN_P(me)) {
+ MP_DROP(GFN_P(me));
+ gfn_destroy(GFN_PTON(me));
+ gfn_destroy(GFN_NTOP(me));
+ }
FREEOBJ(me);
}
static PyMethodDef methods[] = {
#define METHNAME(func) meth_##func
KWMETH(_MP_fromstring, "\
-fromstring(STR, radix = 0) -> (X, REST)\n\
+fromstring(STR, [radix = 0]) -> (X, REST)\n\
\n\
Parse STR as a large integer, according to radix. If radix is zero,\n\
read a prefix from STR to decide radix: allow `0' for octal, `0x' for hex\n\
or `R_' for other radix R.")
KWMETH(_GF_fromstring, "\
-fromstring(STR, radix = 0) -> (X, REST)\n\
+fromstring(STR, [radix = 0]) -> (X, REST)\n\
\n\
Parse STR as a binary polynomial, according to radix. If radix is zero,\n\
read a prefix from STR to decide radix: allow `0' for octal, `0x' for hex\n\