chiark / gitweb /
algorithms.c: Add missing `copy' methods on hash and Keccak objects.
[catacomb-python] / algorithms.c
index 033176ba1d5825d09739fad1e445c104a149861d..50ae06859541304b3340b6f554f969b74e570667 100644 (file)
@@ -457,14 +457,13 @@ PyTypeObject *gccipher_pytype, *gcipher_pytype;
 CONVFUNC(gccipher, gccipher *, GCCIPHER_CC)
 CONVFUNC(gcipher, gcipher *, GCIPHER_C)
 
-PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c, unsigned f)
+PyObject *gcipher_pywrap(PyObject *cobj, gcipher *c)
 {
   gcipher_pyobj *g;
   if (!cobj) cobj = gccipher_pywrap((/*unconst*/ gccipher *)GC_CLASS(c));
   else Py_INCREF(cobj);
   g = PyObject_NEW(gcipher_pyobj, (PyTypeObject *)cobj);
   g->c = c;
-  g->f = f;
   return ((PyObject *)g);
 }
 
@@ -478,8 +477,7 @@ static PyObject *gcipher_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
     goto end;
   if (keysz(sz, GCCIPHER_CC(ty)->keysz) != sz) VALERR("bad key length");
   return (gcipher_pywrap((PyObject *)ty,
-                        GC_INIT(GCCIPHER_CC(ty), k, sz),
-                        f_freeme));
+                        GC_INIT(GCCIPHER_CC(ty), k, sz)));
 end:
   return (0);
 }
@@ -503,8 +501,7 @@ PyObject *gccipher_pywrap(gccipher *cc)
 
 static void gcipher_pydealloc(PyObject *me)
 {
-  if (GCIPHER_F(me) & f_freeme)
-    GC_DESTROY(GCIPHER_C(me));
+  GC_DESTROY(GCIPHER_C(me));
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
@@ -725,7 +722,7 @@ static PyObject *ghash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   static const char *const kwlist[] = { 0 };
   if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST))
     goto end;
-  return (ghash_pywrap((PyObject *)ty, GH_INIT(GCHASH_CH(ty)), f_freeme));
+  return (ghash_pywrap((PyObject *)ty, GH_INIT(GCHASH_CH(ty))));
 end:
   return (0);
 }
@@ -747,21 +744,19 @@ PyObject *gchash_pywrap(gchash *ch)
   return ((PyObject *)g);
 }
 
-PyObject *ghash_pywrap(PyObject *cobj, ghash *h, unsigned f)
+PyObject *ghash_pywrap(PyObject *cobj, ghash *h)
 {
   ghash_pyobj *g;
   if (!cobj) cobj = gchash_pywrap((/*unconst*/ gchash *)GH_CLASS(h));
   else Py_INCREF(cobj);
   g = PyObject_NEW(ghash_pyobj, (PyTypeObject *)cobj);
   g->h = h;
-  g->f = f;
   return ((PyObject *)g);
 }
 
 static void ghash_pydealloc(PyObject *me)
 {
-  if (GHASH_F(me) & f_freeme)
-    GH_DESTROY(GHASH_H(me));
+  GH_DESTROY(GHASH_H(me));
   Py_DECREF(me->ob_type);
   FREEOBJ(me);
 }
@@ -775,6 +770,12 @@ static PyObject *gchget_hashsz(PyObject *me, void *hunoz)
 static PyObject *gchget_bufsz(PyObject *me, void *hunoz)
   { return (PyInt_FromLong(GCHASH_CH(me)->bufsz)); }
 
+static PyObject *ghmeth_copy(PyObject *me, PyObject *arg)
+{
+  if (!PyArg_ParseTuple(arg, ":copy")) return (0);
+  return (ghash_pywrap((PyObject *)me->ob_type, GH_COPY(GHASH_H(me))));
+}
+
 static PyObject *ghmeth_hash(PyObject *me, PyObject *arg)
 {
   char *p;
@@ -839,6 +840,7 @@ static PyGetSetDef gchash_pygetset[] = {
 
 static PyMethodDef ghash_pymethods[] = {
 #define METHNAME(name) ghmeth_##name
+  METH (copy,                  "H.copy() -> HH")
   METH (hash,                  "H.hash(M)")
 #define METHU_(n, W, w) METH(hashu##w, "H.hashu" #w "(WORD)")
   DOUINTCONV(METHU_)
@@ -966,8 +968,7 @@ static PyObject *gmac_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
     goto end;
   if (keysz(sz, GCMAC_CM(ty)->keysz) != sz) VALERR("bad key length");
   return (gmac_pywrap((PyObject *)ty,
-                     GM_KEY(GCMAC_CM(ty), k, sz),
-                     f_freeme));
+                     GM_KEY(GCMAC_CM(ty), k, sz)));
 end:
   return (0);
 }
@@ -980,7 +981,6 @@ static PyObject *gmhash_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) return (0);
   g = PyObject_NEW(ghash_pyobj, ty);
   g->h = GM_INIT(GMAC_M(ty));
-  g->f = f_freeme;
   Py_INCREF(ty);
   return ((PyObject *)g);
 }
@@ -1002,7 +1002,7 @@ PyObject *gcmac_pywrap(gcmac *cm)
   return ((PyObject *)g);
 }
 
-PyObject *gmac_pywrap(PyObject *cobj, gmac *m, unsigned f)
+PyObject *gmac_pywrap(PyObject *cobj, gmac *m)
 {
   gmac_pyobj *g;
   if (!cobj) cobj = gcmac_pywrap((/*unconst*/ gcmac *)GM_CLASS(m));
@@ -1021,14 +1021,12 @@ PyObject *gmac_pywrap(PyObject *cobj, gmac *m, unsigned f)
   g->ty.ht_type.tp_new = gmhash_pynew;
   typeready(&g->ty.ht_type);
   g->m = m;
-  g->f = f;
   return ((PyObject *)g);
 }
 
 static void gmac_pydealloc(PyObject *me)
 {
-  if (GMAC_F(me) & f_freeme)
-    GM_DESTROY(GMAC_M(me));
+  GM_DESTROY(GMAC_M(me));
   Py_DECREF(me->ob_type);
   PyType_Type.tp_dealloc(me);
 }
@@ -1607,6 +1605,16 @@ end:
   return ((PyObject *)rc);
 }
 
+static PyObject *kxvikmeth_copy(PyObject *me, PyObject *arg)
+{
+  kxvik_pyobj *k = (kxvik_pyobj *)me, *rc = 0;
+  if (!PyArg_ParseTuple(arg, ":copy")) goto end;
+  rc = (kxvik_pyobj *)k->ob_type->tp_alloc(k->ob_type, 0);
+  rc->s = k->s; rc->n = k->n;
+end:
+  return ((PyObject *)rc);
+}
+
 static PyObject *kxvikmeth_mix(PyObject *me, PyObject *arg)
 {
   kxvik_pyobj *k = (kxvik_pyobj *)me;
@@ -1685,6 +1693,7 @@ static PyGetSetDef kxvik_pygetset[] = {
 
 static PyMethodDef kxvik_pymethods[] = {
 #define METHNAME(func) kxvikmeth_##func
+  METH (copy,                  "KECCAK.copy() -> KECCAK'")
   METH (mix,                   "KECCAK.mix(DATA)")
   METH (extract,               "KECCAK.extract(NOCTETS)")
   METH (step,                  "KECCAK.step()")