/*----- Header files ------------------------------------------------------*/
#include "catacomb-python.h"
+PUBLIC_SYMBOLS;
#include "algorithms.h"
+PRIVATE_SYMBOLS;
/*----- Key sizes ---------------------------------------------------------*/
if (!set) set = PyTuple_New(0);
else Py_INCREF(set);
if (!PySequence_Check(set)) TYERR("want a sequence");
- n = PySequence_Size(set);
- l = PyList_New(0);
- if (PyErr_Occurred()) goto end;
+ n = PySequence_Size(set); if (n < 0) goto end;
+ l = PyList_New(0); if (!l) goto end;
if (dfl < 0) VALERR("key size cannot be negative");
x = PyInt_FromLong(dfl);
PyList_Append(l, x);
static PyGetSetDef keyszany_pygetset[] = {
#define GETSETNAME(op, name) ka##op##_##name
GET (min, "KSZ.min -> smallest allowed key size")
- GET (max, "KSZ.min -> largest allowed key size")
+ GET (max, "KSZ.max -> largest allowed key size")
#undef GETSETNAME
{ 0 }
};
static PyMemberDef keyszrange_pymembers[] = {
#define MEMBERSTRUCT keyszrange_pyobj
MEMBER(min, T_INT, READONLY, "KSZ.min -> smallest allowed key size")
- MEMBER(max, T_INT, READONLY, "KSZ.min -> largest allowed key size")
+ MEMBER(max, T_INT, READONLY, "KSZ.max -> largest allowed key size")
MEMBER(mod, T_INT, READONLY,
"KSZ.mod -> key size must be a multiple of this")
#undef MEMBERSTRUCT
static PyGetSetDef keyszset_pygetset[] = {
#define GETSETNAME(op, name) ks##op##_##name
GET (min, "KSZ.min -> smallest allowed key size")
- GET (max, "KSZ.min -> largest allowed key size")
+ GET (max, "KSZ.max -> largest allowed key size")
#undef GETSETNAME
{ 0 }
};
VALERR("can't duplicate nonce-dependent aad");
rc = gaeadaad_pywrap((PyObject *)me->ob_type,
GAEAD_DUP(GAEADAAD_A(me)), 0, 0);
+ GAEADAAD_HLEN(rc) = GAEADAAD_HLEN(me);
end:
return (rc);
}
if (!ge->aad)
ge->aad = (gaeadaad_pyobj *)
gaeadaad_pywrap((PyObject *)GCAEADENC_KEY(ge->ob_type)->aad,
- GAEAD_AAD(ge->e), ge->f&AEADF_PCHSZ, ge->hsz);
+ GAEAD_AAD(ge->e), ge->f&(AEADF_PCHSZ | AEADF_NOAAD),
+ ge->hsz);
Py_INCREF(ge->aad);
rc = (PyObject *)ge->aad;
}
if (!gd->aad)
gd->aad = (gaeadaad_pyobj *)
gaeadaad_pywrap((PyObject *)GCAEADENC_KEY(gd->ob_type)->aad,
- GAEAD_AAD(gd->d), gd->f&AEADF_PCHSZ, gd->hsz);
+ GAEAD_AAD(gd->d), gd->f&(AEADF_PCHSZ | AEADF_NOAAD),
+ gd->hsz);
Py_INCREF(gd->aad);
return ((PyObject *)gd->aad);
}
if (!PyArg_ParseTuple(arg, "s#s#:" #hdance "_prf", \
&k, &ksz, &n, &nsz)) \
goto end; \
- if (ksz != DANCE##_KEYSZ) VALERR("bad key length"); \
+ if (ksz != keysz(ksz, dance##_keysz)) VALERR("bad key length"); \
if (nsz != HDANCE##_INSZ) VALERR("bad input length"); \
rc = bytestring_pywrap(0, HSALSA20_OUTSZ); \
dance##_init(&dance, k, ksz, 0); \
unsigned n;
} kxvik_pyobj;
-static PyObject *kxvik_pynew(PyTypeObject *ty,
- PyObject *arg, PyObject *kw)
+static PyObject *kxvik_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
{
unsigned n = 24;
kxvik_pyobj *rc = 0;
unsigned i;
unsigned n;
- if (!PyArg_ParseTuple(arg, "O&:mix", convuint, &n)) goto end;
+ if (!PyArg_ParseTuple(arg, "O&:extract", convuint, &n)) goto end;
if (n > 200) VALERR("out of range");
rc = bytestring_pywrap(0, n);
q = (octet *)PyString_AS_STRING(rc);
{
kxvik_pyobj *k = (kxvik_pyobj *)me;
unsigned n;
+ int rc = -1;
- if (!convuint(val, &n)) return (-1);
+ if (!val) NIERR("__del__");
+ if (!convuint(val, &n)) goto end;
k->n = n;
- return (0);
+ rc = 0;
+ end:
+ return (rc);
}
static PyGetSetDef kxvik_pygetset[] = {
rc->h = *SHAKE_H(me);
rc->st = SHAKE_ST(me);
end:
- return ((PyObject *)me);
+ return ((PyObject *)rc);
}
static PyObject *shakemeth_get(PyObject *me, PyObject *arg)
#include <catacomb/share.h>
#include <catacomb/gfshare.h>
+/*----- Other preliminaries -----------------------------------------------*/
+
+#define GOBBLE_SEMI extern int notexist
+#if defined(__GNUC__) && defined(__ELF__)
+# define PRIVATE_SYMBOLS _Pragma("GCC visibility push(hidden)") GOBBLE_SEMI
+# define PUBLIC_SYMBOLS _Pragma("GCC visibility pop") GOBBLE_SEMI
+# define EXPORT __attribute__((__visibility__("default")))
+#else
+# define PRIVATE_SYMBOLS GOBBLE_SEMI
+# define PUBLIC_SYMBOLS GOBBLE_SEMI
+# define EXPORT
+#endif
+
+PRIVATE_SYMBOLS;
+
/*----- Utility macros ----------------------------------------------------*/
#define RETURN_OBJ(obj) do { Py_INCREF(obj); return (obj); } while (0)
goto end; \
} while (0)
#define VALERR(str) EXCERR(PyExc_ValueError, str)
+ #define OVFERR(str) EXCERR(PyExc_OverflowError, str)
#define TYERR(str) EXCERR(PyExc_TypeError, str)
#define IXERR(str) EXCERR(PyExc_IndexError, str)
#define ZDIVERR(str) EXCERR(PyExc_ZeroDivisionError, str)
PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); \
goto end; \
} while (0)
- #define PGENERR do { pgenerr(); goto end; } while (0)
+ #define PGENERR(exc) do { pgenerr(exc); goto end; } while (0)
#define CONVFUNC(ty, cty, ext) \
int conv##ty(PyObject *o, void *p) \
} while (0)
#define INITTYPE(ty, base) INITTYPE_META(ty, base, type)
- #define INSERT(name, ob) do { \
+ extern PyObject *home_module;
+
+ #define INSERT(name, ob) do { \
PyObject *_o = (PyObject *)(ob); \
Py_INCREF(_o); \
PyModule_AddObject(mod, name, _o); \
#define KWLIST (/*unconst*/ char **)kwlist
- struct nameval { const char *name; unsigned long value; };
+ struct nameval { const char *name; unsigned f; unsigned long value; };
+ #define CF_SIGNED 1u
extern void setconstants(PyObject *, const struct nameval *);
extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
extern PyObject *getk64(kludge64);
extern void *newtype(PyTypeObject *, const PyTypeObject *, const char *);
+ struct excinfo { PyObject *ty, *val, *tb; };
+ #define EXCINFO_INIT { 0, 0, 0 }
+
extern PyObject *mkexc(PyObject *, PyObject *, const char *, PyMethodDef *);
+ #define INIT_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); _exc->ty = _exc->val = _exc->tb = 0; \
+ } while (0)
+ #define RELEASE_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ Py_XDECREF(_exc->ty); _exc->ty = 0; \
+ Py_XDECREF(_exc->val); _exc->val = 0; \
+ Py_XDECREF(_exc->tb); _exc->tb = 0; \
+ } while (0)
+ #define STASH_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ PyErr_Fetch(&_exc->ty, &_exc->val, &_exc->tb); \
+ PyErr_NormalizeException(&_exc->ty, &_exc->val, &_exc->tb); \
+ } while (0)
+ #define RESTORE_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ PyErr_Restore(_exc->ty, _exc->val, _exc->tb); \
+ _exc->ty = _exc->val = _exc->tb = 0; \
+ } while (0)
+ extern void report_lost_exception(struct excinfo *, const char *, ...);
+ extern void report_lost_exception_v(struct excinfo *, const char *, va_list);
+ extern void stash_exception(struct excinfo *, const char *, ...);
+ extern void restore_exception(struct excinfo *, const char *, ...);
+
extern void typeready(PyTypeObject *);
extern PyTypeObject *inittype(PyTypeObject *, PyTypeObject *);
extern void addmethods(const PyMethodDef *);
extern int convgf(PyObject *, void *);
extern PyObject *mp_pywrap(mp *);
extern PyObject *gf_pywrap(mp *);
+ extern long mphash(mp *);
extern mp *mp_frompyobject(PyObject *, int);
extern PyObject *mp_topystring(mp *, int,
const char *, const char *, const char *);
#define FE_FOBJ(o) ((PyObject *)(o)->ob_type)
#define FE_X(o) (((fe_pyobj *)(o))->x)
extern PyObject *fe_pywrap(PyObject *, mp *);
- extern mp *getfe(field *, PyObject *);
typedef struct fe_pyobj {
PyObject_HEAD
#define PGEV_PYCHECK(o) PyObject_TypeCheck(o, pgev_pytype)
#define PGEV_PG(o) (&((pgev_pyobj *)(o))->pg)
+ typedef struct pypgev {
+ pgev ev;
+ PyObject *obj;
+ struct excinfo *exc;
+ } pypgev;
+
extern int convpgev(PyObject *, void *);
- extern void droppgev(pgev *);
- extern void pgenerr(void);
+ extern void droppgev(pypgev *);
+ extern void pgenerr(struct excinfo *exc);
/*----- That's all, folks -------------------------------------------------*/
/*----- Main code ---------------------------------------------------------*/
static const struct nameval consts[] = {
- #define C(x) { #x, x }
+ #define CF(f, x) { #x, f, x }
+ #define C(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x }
C(FTY_PRIME), C(FTY_BINARY),
C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
C(PGEN_ABORT),
C(MPW_MAX),
+ C(RAND_IBITS),
C(PMODE_READ), C(PMODE_VERIFY),
C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
- C(KEXP_FOREVER), C(KEXP_EXPIRE),
+ CF(0, KEXP_FOREVER), CF(0, KEXP_EXPIRE),
C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
KEY_ERRORS(ENTRY)
#undef ENTRY
#undef C
+ #undef CF
{ 0 }
};
arg = PyTuple_GetItem(arg, 0);
Py_INCREF(arg);
if (!PySequence_Check(arg)) TYERR("not a sequence");
- n = PySequence_Size(arg); if (!n) { z = id(me); goto end; }
+ n = PySequence_Size(arg); if (n < 0) goto end;
+ if (!n) { z = id(me); goto end; }
x = PySequence_GetItem(arg, 0);
if (PySequence_Check(x))
flat = 0;
char *argv0;
if (!PyArg_ParseTuple(arg, "s:_ego", &argv0))
return (0);
- if (strcmp(QUIS, "<UNNAMED>") == 0)
+ if (STRCMP(QUIS, ==, "<UNNAMED>"))
ego(argv0);
RETURN_NONE;
}
if (!Py_HashRandomizationFlag) return;
seed = getenv("PYTHONHASHSEED");
- if (!seed || strcmp(seed, "random") == 0) r = GR_WORD(&rand_global);
+ if (!seed || STRCMP(seed, ==, "random")) r = GR_WORD(&rand_global);
else r = strtoul(seed, 0, 0);
if (!r) r = 0xe011f220; /* zero doesn't work well */
unihash_setkey(&unihash_global, r);
#endif
}
-void init_base(void)
+EXPORT void init_base(void)
{
PyObject *mod;
addmethods(methods);
+catacomb-python (1.3.99~) experimental; urgency=medium
+
+ * (placeholder for next release)
+
+ -- Mark Wooding <mdw@distorted.org.uk> Tue, 01 Oct 2019 12:57:58 +0100
+
catacomb-python (1.3.0.1) experimental; urgency=medium
* Fix required Catacomb version in `setup.py' script. Only affects the
-- Mark Wooding <mdw@distorted.org.uk> Sat, 21 Sep 2019 23:00:25 +0100
+ catacomb-python (1.2.1.1) experimental; urgency=medium
+
+ * Fixing to build against Debian `stretch'.
+
+ -- Mark Wooding <mdw@distorted.org.uk> Mon, 24 Dec 2018 15:21:08 +0000
+
catacomb-python (1.2.1) experimental; urgency=low
* Fix use-after-free bug in ECPt hashing causing hash instability.
Priority: extra
XS-Python-Version: >= 2.6, << 2.8
Maintainer: Mark Wooding <mdw@distorted.org.uk>
- Build-Depends: debhelper (>= 10), pkg-config,
-Build-Depends: debhelper (>= 9), dh-python, pkg-config,
++Build-Depends: debhelper (>= 10), dh-python, pkg-config,
python (>= 2.6.6-3~), python-all-dev,
- mlib-dev (>= 2.2.2.1), catacomb-dev (>= 2.5.0)
+ mlib-dev (>= 2.4.99~), catacomb-dev (>= 2.5.0)
Standards-Version: 3.8.0
Package: python-catacomb
return (0);
a = F_OUT(f, MP_NEW, c->a);
b = F_OUT(f, MP_NEW, c->b);
- if (strcmp(EC_NAME(c), "prime") == 0)
+ if (STRCMP(EC_NAME(c), ==, "prime"))
c = ec_prime(f, a, b);
- else if (strcmp(EC_NAME(c), "primeproj") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "primeproj"))
c = ec_primeproj(f, a, b);
- else if (strcmp(EC_NAME(c), "bin") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "bin"))
c = ec_bin(f, a, b);
- else if (strcmp(EC_NAME(c), "binproj") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "binproj"))
c = ec_binproj(f, a, b);
else
c = 0;
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)
{
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));
- ec_putraw(ECPT_C(me), &b, &p);
+ getecptout(&p, me);
+ if (EC_ATINF(&p)) h = 0x81d81a94;
+ else h = 0xe0fdd039 ^ (2*mphash(p.x)) ^ (3*mphash(p.y));
EC_DESTROY(&p);
- h = unihash_hash(&unihash_global, h, BBASE(&b), BLEN(&b));
- xfree(q);
- return (h % LONG_MAX);
+ 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;
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);
char *p;
ec_curve *c = ECPT_C(me);
ec pp = EC_INIT;
- int f = EC_EXPLY;
+ unsigned f = EC_EXPLY;
int len;
static const char *const kwlist[] = { "flags", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:ectosp", KWLIST, &f))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:ec2osp", KWLIST,
+ convuint, &f))
return (0);
len = c->f->noctets * 2 + 1;
rc = bytestring_pywrap(0, len);
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;
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_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 ||
(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;
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);
}
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);
}
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));
buf b;
PyObject *rc = 0;
ec_curve *cc;
- int f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY;
+ unsigned f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY;
ec pp = EC_INIT;
- static const char *const kwlist[] = { "buf", "flags", 0 };
+ static const char *const kwlist[] = { "class", "buf", "flags", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|f:os2ecp", KWLIST,
- &me, &p, &len, &f))
+ 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);
else
Py_INCREF(fobj);
assert(FIELD_F(fobj) == c->f);
- if (strcmp(EC_NAME(c), "prime") == 0)
+ if (STRCMP(EC_NAME(c), ==, "prime"))
ty = ecprimecurve_pytype;
- else if (strcmp(EC_NAME(c), "primeproj") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "primeproj"))
ty = ecprimeprojcurve_pytype;
- else if (strcmp(EC_NAME(c), "bin") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "bin"))
ty = ecbincurve_pytype;
- else if (strcmp(EC_NAME(c), "binproj") == 0)
+ else if (STRCMP(EC_NAME(c), ==, "binproj"))
ty = ecbinprojcurve_pytype;
else
abort();
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 PyMethodDef ecinfo_pymethods[] = {
#define METHNAME(name) eimeth_##name
- KWMETH(check, "I.check() -> None")
+ KWMETH(check, "I.check([rng = rand]) -> None")
#undef METHNAME
{ 0 }
};
{
PyTypeObject *ty;
- if (strcmp(F_NAME(f), "prime") == 0) ty = primefield_pytype;
- else if (strcmp(F_NAME(f), "niceprime") == 0) ty = niceprimefield_pytype;
- else if (strcmp(F_NAME(f), "binpoly") == 0) ty = binpolyfield_pytype;
- else if (strcmp(F_NAME(f), "binnorm") == 0) ty = binnormfield_pytype;
+ if (STRCMP(F_NAME(f), ==, "prime")) ty = primefield_pytype;
+ else if (STRCMP(F_NAME(f), ==, "niceprime")) ty = niceprimefield_pytype;
+ else if (STRCMP(F_NAME(f), ==, "binpoly")) ty = binpolyfield_pytype;
+ else if (STRCMP(F_NAME(f), ==, "binnorm")) ty = binnormfield_pytype;
else abort();
return (field_dopywrap(ty, f));
}
field *field_copy(field *f)
{
- if (strcmp(F_NAME(f), "prime") == 0)
+ if (STRCMP(F_NAME(f), ==, "prime"))
f = field_prime(f->m);
- else if (strcmp(F_NAME(f), "niceprime") == 0)
+ else if (STRCMP(F_NAME(f), ==, "niceprime"))
f = field_niceprime(f->m);
- else if (strcmp(F_NAME(f), "binpoly") == 0)
+ else if (STRCMP(F_NAME(f), ==, "binpoly"))
f = field_binpoly(f->m);
- else if (strcmp(F_NAME(f), "binnorm") == 0) {
+ else if (STRCMP(F_NAME(f), ==, "binnorm")) {
fctx_binnorm *fc = (fctx_binnorm *)f;
f = field_binnorm(f->m, fc->ntop.r[fc->ntop.n - 1]);
} else
return (y);
}
- mp *getfe(field *f, PyObject *o)
- {
- mp *x = 0;
- if ((x = tofe(f, o)) == 0) {
- PyErr_Format(PyExc_TypeError, "can't convert %.100s to fe",
- o->ob_type->tp_name);
- }
- return (x);
- }
-
/*----- Field elements ----------------------------------------------------*/
static int febinop(PyObject *x, PyObject *y,
}
static long fe_pyhash(PyObject *me)
- {
- size_t sz = FE_F(me)->noctets;
- uint32 h = 0xe0c127ca + FE_F(me)->ops->ty;
- octet *p = xmalloc(sz);
- mp_storeb(FE_X(me), p, sz);
- h = unihash_hash(&unihash_global, h, p, sz);
- xfree(p);
- return (h % LONG_MAX);
- }
+ { return (mphash(FE_X(me))); }
static int fe_pycoerce(PyObject **x, PyObject **y)
{
#define BASEOP(name, radix, pre) \
static PyObject *fe_py##name(PyObject *x) { \
mp *xx = F_OUT(FE_F(x), MP_NEW, FE_X(x)); \
- PyObject *rc = mp_topystring(FE_X(x), radix, 0, pre, 0); \
+ PyObject *rc = mp_topystring(xx, radix, 0, pre, 0); \
MP_DROP(xx); \
return (rc); \
}
static PyGetSetDef fe_pygetset[] = {
#define GETSETNAME(op, name) fe##op##_##name
GET (field, "X.field -> field containing X")
- GET (value, "X.value -> `natural' integer representation of X")
- GET (_value, "X._value -> internal integer representation of X")
+ GET (value, "X.value -> `natural' MP/GF representation of X")
+ GET (_value, "X._value -> internal MP/GF representation of X")
#undef GETSETNAME
{ 0 }
};
static PyMethodDef field_pymethods[] = {
#define METHNAME(name) fmeth_##name
METH (_adopt, "F._adopt(X) -> FE")
- KWMETH(rand, "F.rand(rng = rand) -> FE, uniformly distributed")
+ KWMETH(rand, "F.rand([rng = rand]) -> FE, uniformly distributed")
#undef METHNAME
{ 0 }
};
return (0);
}
+ static PyObject *bfget_p(PyObject *me, void *hunoz)
+ { return (gf_pywrap(MP_COPY(FIELD_F(me)->m))); }
+
static PyGetSetDef binpolyfield_pygetset[] = {
- #define GETSETNAME(op, name) pf##op##_##name
+ #define GETSETNAME(op, name) bf##op##_##name
GET (p, "F.p -> field polynomial")
#undef GETSETNAME
{ 0 }
}
static PyGetSetDef binnormfield_pygetset[] = {
- #define GETSETNAME(op, name) pf##op##_##name
+ #define GETSETNAME(op, name) bf##op##_##name
GET (p, "F.p -> field polynomial")
#undef GETSETNAME
#define GETSETNAME(op, name) bnf##op##_##name
unsigned ql = 0, pl;
unsigned steps = 0;
grand *r = &rand_global;
- pgev evt = { 0 };
+ struct excinfo exc = EXCINFO_INIT;
+ pypgev evt = { { 0 } };
static const char *const kwlist[] =
{ "class", "pbits", "qbits", "event", "rng", "nsteps", 0 };
PyObject *rc = 0;
+ evt.exc = &exc;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", KWLIST,
&me, convuint, &pl, convuint, &ql,
convpgev, &evt, convgrand, &r,
convuint, &steps))
goto end;
- if (dh_gen(&dp, ql, pl, steps, r, evt.proc, evt.ctx))
- PGENERR;
+ if (dh_gen(&dp, ql, pl, steps, r, evt.ev.proc, evt.ev.ctx))
+ PGENERR(&exc);
rc = fginfo_pywrap(&dp, dhinfo_pytype);
end:
droppgev(&evt);
unsigned ql, pl;
unsigned steps = 0;
grand *r = &rand_global;
- pgev oe = { 0 }, ie = { 0 };
+ struct excinfo exc = EXCINFO_INIT;
+ pypgev oe = { { 0 } }, ie = { { 0 } };
int subgroupp = 1;
unsigned f = 0;
static const char *const kwlist[] = {
mp **v = 0;
PyObject *rc = 0, *vec = 0;
+ oe.exc = ie.exc = &exc;
if (!PyArg_ParseTupleAndKeywords(arg, kw,
"OO&O&|O&O&O&O&O&:genlimlee", KWLIST,
&me, convuint, &pl, convuint, &ql,
goto end;
if (subgroupp) f |= DH_SUBGROUP;
if (dh_limlee(&dp, ql, pl, f, steps, r,
- oe.proc, oe.ctx, ie.proc, ie.ctx, &nf, &v))
- PGENERR;
+ oe.ev.proc, oe.ev.ctx, ie.ev.proc, ie.ev.ctx, &nf, &v))
+ PGENERR(&exc);
vec = PyList_New(nf);
for (i = 0; i < nf; i++)
PyList_SetItem(vec, i, mp_pywrap(v[i]));
unsigned ql, pl;
unsigned steps = 0;
grand *r = &rand_global;
- pgev evt = { 0 };
+ struct excinfo exc = EXCINFO_INIT;
+ pypgev evt = { { 0 } };
static const char *const kwlist[] =
{ "class", "pbits", "qbits", "event", "rng", "nsteps", 0 };
mp *v = MP_NEW;
PyObject *rc = 0;
+ evt.exc = &exc;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&|O&O&O&:genkcdsa", KWLIST,
&me, convuint, &pl, convuint, &ql,
convpgev, &evt, convgrand, &r,
convuint, &steps))
goto end;
- if (dh_kcdsagen(&dp, ql, pl, 0, steps, r, evt.proc, evt.ctx))
- PGENERR;
+ if (dh_kcdsagen(&dp, ql, pl, 0, steps, r, evt.ev.proc, evt.ev.ctx))
+ PGENERR(&exc);
mp_div(&v, 0, dp.p, dp.q);
v = mp_lsr(v, v, 1);
rc = Py_BuildValue("(NN)", fginfo_pywrap(&dp, dhinfo_pytype),
dsa_seed ds;
char *k;
Py_ssize_t ksz;
- pgev evt = { 0 };
+ struct excinfo exc = EXCINFO_INIT;
+ pypgev evt = { { 0 } };
static const char *const kwlist[] =
{ "class", "pbits", "qbits", "seed", "event", "nsteps", 0 };
PyObject *rc = 0;
+ evt.exc = &exc;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:gendsa", KWLIST,
&me, convuint, &pl, convuint, &ql,
&k, &ksz, convpgev, &evt,
convuint, &steps))
goto end;
- if (dsa_gen(&dp, ql, pl, steps, k, ksz, &ds, evt.proc, evt.ctx))
- PGENERR;
+ if (dsa_gen(&dp, ql, pl, steps, k, ksz, &ds, evt.ev.proc, evt.ev.ctx))
+ PGENERR(&exc);
rc = Py_BuildValue("(NNl)", fginfo_pywrap(&dp, dhinfo_pytype),
bytestring_pywrap(ds.p, ds.sz), (long)ds.count);
xfree(ds.p);
group *group_copy(group *g)
{
- if (strcmp(G_NAME(g), "prime") == 0) {
+ if (STRCMP(G_NAME(g), ==, "prime")) {
gctx_prime *gc = (gctx_prime *)g;
gprime_param gp;
gp.g = G_TOINT(g, MP_NEW, g->g);
gp.q = gc->g.r;
g = group_prime(&gp);
MP_DROP(gp.g);
- } else if (strcmp(G_NAME(g), "bin") == 0) {
+ } else if (STRCMP(G_NAME(g), ==, "bin")) {
gctx_bin *gc = (gctx_bin *)g;
gbin_param gb;
gb.g = G_TOINT(g, MP_NEW, g->g);
gb.q = gc->g.r;
g = group_binary(&gb);
MP_DROP(gb.g);
- } else if (strcmp(G_NAME(g), "ec") == 0) {
+ } else if (STRCMP(G_NAME(g), ==, "ec")) {
gctx_ec *gc = (gctx_ec *)g;
ec_info ei;
if ((ei.c = eccurve_copy(gc->ei.c)) == 0)
{
PyTypeObject *ty;
- if (strcmp(G_NAME(g), "prime") == 0) ty = primegroup_pytype;
- else if (strcmp(G_NAME(g), "bin") == 0) ty = bingroup_pytype;
- else if (strcmp(G_NAME(g), "ec") == 0) ty = ecgroup_pytype;
+ if (STRCMP(G_NAME(g), ==, "prime")) ty = primegroup_pytype;
+ else if (STRCMP(G_NAME(g), ==, "bin")) ty = bingroup_pytype;
+ else if (STRCMP(G_NAME(g), ==, "ec")) ty = ecgroup_pytype;
else abort();
return (group_dopywrap(ty, g));
}
if (!PyType_Check(cty) || !PyType_IsSubtype(cty, ecpt_pytype))
TYERR("want subtype of catacomb.ECPt");
Py_INCREF((PyObject *)cty);
- } else if (strcmp(G_NAME(g), "ec") == 0) {
+ } else if (STRCMP(G_NAME(g), ==, "ec")) {
c = eccurve_copy(((gctx_ec *)g)->ei.c);
cty = (PyTypeObject *)eccurve_pywrap(0, c);
} else {
METH (check, "X.check() -> check X really belongs to its group")
METH (toint, "X.toint() -> X converted to an integer")
KWMETH(toec, "\
- X.toec(curve = ecpt) -> X converted to elliptic curve point")
+ X.toec([curve = ECPt]) -> X converted to elliptic curve point")
METH (tobuf, "X.tobuf() -> X in buffer representation")
METH (toraw, "X.toraw() -> X in raw representation")
#undef METHNAME
#define METHNAME(name) gmeth_##name
METH (mexp, "\
G.mexp([(X0, N0), (X1, N1), ...]) -> X0^N0 X1^N1 ...")
- KWMETH(checkgroup, "G.checkgroup(rand = random): check group is good")
+ KWMETH(checkgroup, "G.checkgroup([rng = rand]): check group is good")
#undef METHNAME
{ 0 }
};
METH (_DHInfo__groupn, 0)
METH (_BinDHInfo__groupn, 0)
KWMETH(_DHInfo_generate, "\
- generate(PBITS, [qbits = 0, event = pgen_nullev,\n\
- rng = rand, nsteps = 0]) -> D")
+ generate(PBITS, [qbits = 0], [event = pgen_nullev],\n\
+ [rng = rand], [nsteps = 0]) -> D")
KWMETH(_DHInfo_genlimlee, "\
- genlimlee(PBITS, QBITS, [event = pgen_nullev, ievent = pgen_nullev,\n\
- rng = rand, nsteps = 0, subgroupp = True]) -> (D, [Q, ...])")
+ genlimlee(PBITS, QBITS, [event = pgen_nullev], [ievent = pgen_nullev],\n\
+ [rng = rand], [nsteps = 0], [subgroupp = True]) -> (D, [Q, ...])")
KWMETH(_DHInfo_gendsa, "\
- gendsa(PBITS, QBITS, SEED, [event = pgen_nullev, nsteps = 0])\n\
+ gendsa(PBITS, QBITS, SEED, [event = pgen_nullev], [nsteps = 0])\n\
-> (D, SEED, COUNT)")
KWMETH(_DHInfo_genkcdsa, "\
- gendsa(PBITS, QBITS, [event = pgen_nullev, rng = rand, nsteps = 0])\n\
+ gendsa(PBITS, QBITS, [event = pgen_nullev], [rng = rand], [nsteps = 0])\n\
-> (D, V)")
#undef METHNAME
{ 0 }
/*----- Header files ------------------------------------------------------*/
#include "catacomb-python.h"
+PUBLIC_SYMBOLS;
#include "algorithms.h"
+PRIVATE_SYMBOLS;
/*----- Main code ---------------------------------------------------------*/
PyTypeObject *ty = grand_pytype;
PyObject *ob;
- if (strcmp(r->ops->name, "rand") == 0) ty = truerand_pytype;
- else if (strcmp(r->ops->name, "lcrand") == 0) ty = lcrand_pytype;
- else if (strcmp(r->ops->name, "fibrand") == 0) ty = fibrand_pytype;
- else if (strcmp(r->ops->name, "dsarand") == 0) ty = dsarand_pytype;
- else if (strcmp(r->ops->name, "bbs") == 0) ty = bbs_pytype;
- else if (strcmp(r->ops->name, "sslprf") == 0) ty = sslprf_pytype;
- else if (strcmp(r->ops->name, "tlsdx") == 0) ty = tlsdx_pytype;
- else if (strcmp(r->ops->name, "tlsprf") == 0) ty = tlsprf_pytype;
+ if (STRCMP(r->ops->name, ==, "rand")) ty = truerand_pytype;
+ else if (STRCMP(r->ops->name, ==, "lcrand")) ty = lcrand_pytype;
+ else if (STRCMP(r->ops->name, ==, "fibrand")) ty = fibrand_pytype;
+ else if (STRCMP(r->ops->name, ==, "dsarand")) ty = dsarand_pytype;
+ else if (STRCMP(r->ops->name, ==, "bbs")) ty = bbs_pytype;
+ else if (STRCMP(r->ops->name, ==, "sslprf")) ty = sslprf_pytype;
+ else if (STRCMP(r->ops->name, ==, "tlsdx")) ty = tlsdx_pytype;
+ else if (STRCMP(r->ops->name, ==, "tlsprf")) ty = tlsprf_pytype;
else if ((ob = PyDict_GetItemString(gccrands_dict, r->ops->name)) != 0)
ty = (PyTypeObject *)ob;
return (grand_dopywrap(ty, r, f));
static const char *const kwlist[] = { 0 };
grand *r;
PyObject *rc = 0;
- if (PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) goto end;
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) goto end;
r = rand_create();
r->ops->misc(r, RAND_NOISESRC, &noise_source);
r->ops->misc(r, RAND_SEED, 160);
static int bbsset_x(PyObject *me, PyObject *val, void *hunoz)
{
- mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!x) NIERR("__del__");
+ mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!val) NIERR("__del__");
if ((x = getmp(val)) == 0) goto end;
r->ops->misc(r, BBS_SET, x); rc = 0;
end: mp_drop(x); return (rc);
{
bbs_priv bp = { 0 };
mp *x = MP_TWO;
- pgev evt = { 0 };
+ struct excinfo exc = EXCINFO_INIT;
+ pypgev evt = { { 0 } };
unsigned nbits, n = 0;
grand *r = &rand_global;
static const char *const kwlist[] =
{ "class", "nbits", "event", "rng", "nsteps", "seed", 0 };
bbspriv_pyobj *rc = 0;
+ evt.exc = &exc;
if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", KWLIST,
&me, convuint, &nbits, convpgev, &evt,
convgrand, &r, convuint, &n, convmp, &x))
goto end;
- if (bbs_gen(&bp, nbits, r, n, evt.proc, evt.ctx))
- VALERR("prime genration failed");
+ if (bbs_gen(&bp, nbits, r, n, evt.ev.proc, evt.ev.ctx))
+ PGENERR(&exc);
rc = PyObject_New(bbspriv_pyobj, bbspriv_pytype);
rc->gr.r = bbs_rand(bp.n, x);
rc->gr.f = f_freeme;
Py_TPFLAGS_BASETYPE,
/* @tp_doc@ */
- "BBSPriv(..., seed = 2]): Blum-Blum-Shub, with private key.\n\
+ "BBSPriv(..., [seed = 2]): Blum-Blum-Shub, with private key.\n\
Keywords: n, p, q; must provide at least two",
0, /* @tp_traverse@ */
static PyMethodDef methods[] = {
#define METHNAME(name) meth_##name
KWMETH(_BBSPriv_generate, "\
- generate(NBITS, [event = pgen_nullev, rng = rand, nsteps = 0, seed = 2])")
+ generate(NBITS, [event = pgen_nullev], [rng = rand],\n\
+ [nsteps = 0], [seed = 2]) -> R")
#undef METHNAME
{ 0 }
};
import mdwsetup as MS
MS.pkg_config('catacomb', '2.5.0')
-MS.pkg_config('mLib', '2.2.2.1')
+MS.pkg_config('mLib', '2.4.99~')
cat = DC.Extension('catacomb._base',
['catacomb.c', 'bytestring.c', 'buffer.c',
scripts = ['pock', 'pwsafe'],
data_files = [('share/man/man1', ['pock.1', 'pwsafe.1'])],
genfiles = [MS.Generate('algorithms.h')],
+ unittest_dir = "t",
+ unittests = ["t-misc", "t-algorithms", "t-bytes", "t-buffer",
+ "t-convert", "t-ec", "t-field", "t-group", "t-key",
+ "t-mp", "t-passphrase", "t-pgen", "t-pubkey",
+ "t-rand", "t-rat", "t-share"],
ext_modules = [cat])