Set ELF visibility to keep all of our external symbols to ourselves.
[pyke] / catacomb-python.h
index d71caa9..5815343 100644 (file)
@@ -1,13 +1,11 @@
 /* -*-c-*-
  *
- * $Id$
- *
  * Definitions for Catacomb bindings
  *
  * (c) 2004 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of the Python interface to Catacomb.
  *
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * Catacomb/Python is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with Catacomb/Python; if not, write to the Free Software Foundation,
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 /*----- Header files ------------------------------------------------------*/
 
+#define PY_SSIZE_T_CLEAN
+
 #include <Python.h>
 #include <longintrepr.h>
 #include <structmember.h>
 
-#undef ULLONG_MAX
-#undef ULONG_LONG_MAX
-
 #include <mLib/darray.h>
 #include <mLib/dstr.h>
 #include <mLib/macros.h>
 #include <mLib/quis.h>
+#include <mLib/unihash.h>
 
 #include <catacomb/buf.h>
+#include <catacomb/ct.h>
 
 #include <catacomb/grand.h>
 #include <catacomb/rand.h>
 #include <catacomb/blkc.h>
 
 #include <catacomb/gcipher.h>
+#include <catacomb/gaead.h>
 #include <catacomb/ghash.h>
 #include <catacomb/gmac.h>
 #include <catacomb/md5.h>
 #include <catacomb/md5-hmac.h>
+#include <catacomb/poly1305.h>
 #include <catacomb/sha.h>
 #include <catacomb/sha-mgf.h>
 #include <catacomb/sha-hmac.h>
+#include <catacomb/keccak1600.h>
+#include <catacomb/sha3.h>
 
 #include <catacomb/mp.h>
 #include <catacomb/mpint.h>
@@ -77,6 +80,7 @@
 #include <catacomb/mpmont.h>
 #include <catacomb/mpbarrett.h>
 #include <catacomb/mpreduce.h>
+#include <catacomb/mp-fibonacci.h>
 
 #include <catacomb/pgen.h>
 #include <catacomb/pfilt.h>
 #include <catacomb/ptab.h>
 #include <catacomb/bintab.h>
 #include <catacomb/dsa.h>
+#include <catacomb/x25519.h>
+#include <catacomb/x448.h>
+#include <catacomb/ed25519.h>
+#include <catacomb/ed448.h>
 
 #include <catacomb/gf.h>
 #include <catacomb/gfreduce.h>
 #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)
 } while (0)
 #define VALERR(str) EXCERR(PyExc_ValueError, str)
 #define TYERR(str) EXCERR(PyExc_TypeError, str)
+#define IXERR(str) EXCERR(PyExc_IndexError, str)
 #define ZDIVERR(str) EXCERR(PyExc_ZeroDivisionError, str)
-#define SYNERR(str) EXCERR(PyExc_SyntaxError, str)
 #define SYSERR(str) EXCERR(PyExc_SystemError, str)
+#define NIERR(str) EXCERR(PyExc_NotImplementedError, str)
 #define INDEXERR(idx) do {                                             \
   PyErr_SetObject(PyExc_KeyError, idx);                                        \
   goto end;                                                            \
     return (0);                                                                \
   }
 
+#if PY_VERSION_HEX < 0x02050000                /* Compatibility hack */
+#  define ht_name name
+#  define ht_type type
+#endif
+
 #define root_pytype 0
 #define type_pytype &PyType_Type
-#define INITTYPE(ty, base) do {                                                \
+#define INITTYPE_META(ty, base, meta) do {                             \
   ty##_pytype_skel.tp_base = base##_pytype;                            \
-  ty##_pytype = inittype(&ty##_pytype_skel);                           \
+  ty##_pytype = inittype(&ty##_pytype_skel, meta##_pytype);            \
 } while (0)
+#define INITTYPE(ty, base) INITTYPE_META(ty, base, type)
 
 #define INSERT(name, ob) do {                                          \
   PyObject *_o = (PyObject *)(ob);                                     \
-  Py_INCREF(_o);                                                       \
+  Py_INCREF(_o);                                                       \
   PyModule_AddObject(mod, name, _o);                                   \
 } while (0)
 
   { #name, ty, offsetof(MEMBERSTRUCT, name), f, doc },
 
 #define MODULES(_)                                                     \
+  _(util)                                                              \
   _(bytestring) _(buffer)                                              \
   _(rand) _(algorithms) _(pubkey) _(pgen)                              \
   _(mp) _(field) _(ec) _(group)                                                \
@@ -200,6 +231,90 @@ MODULES(DO)
 #define FREEOBJ(obj)                                                   \
   (((PyObject *)(obj))->ob_type->tp_free((PyObject *)(obj)))
 
+#define GEN(func, base)                                                        \
+  static PyObject *func(void)                                          \
+  {                                                                    \
+    PyObject *d = PyDict_New();                                                \
+    PyObject *o;                                                       \
+    int i;                                                             \
+                                                                       \
+    for (i = 0; g##base##tab[i]; i++) {                                        \
+      o = gc##base##_pywrap((/*unconst*/ gc##base *)g##base##tab[i]);  \
+      PyDict_SetItemString(d,                                          \
+                          (/*unconst*/ char *)g##base##tab[i]->name,   \
+                          o);                                          \
+      Py_DECREF(o);                                                    \
+    }                                                                  \
+    return (d);                                                                \
+  }
+
+#define KWLIST (/*unconst*/ char **)kwlist
+
+struct nameval { const char *name; unsigned long value; };
+extern void setconstants(PyObject *, const struct nameval *);
+
+extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
+                            PyObject *(*id)(PyObject *),
+                            int (*fill)(void *, PyObject *,
+                                        PyObject *, PyObject *),
+                            PyObject *(*exp)(PyObject *, void *, int),
+                            void (*drop)(void *));
+
+extern int convulong(PyObject *, void *);
+#define DECL_CONVU_(n) extern int convu##n(PyObject *, void *);
+DOUINTSZ(DECL_CONVU_)
+extern int convmpw(PyObject *, void *);
+extern int convuint(PyObject *, void *);
+extern int convk64(PyObject *, void *);
+extern int convszt(PyObject *, void *);
+extern int convbool(PyObject *, void *);
+extern PyObject *abstract_pynew(PyTypeObject *, PyObject *, PyObject *);
+extern PyObject *getbool(int);
+extern PyObject *getulong(unsigned long);
+extern PyObject *getk64(kludge64);
+extern void *newtype(PyTypeObject *, const PyTypeObject *, const char *);
+
+extern PyObject *mkexc(PyObject *, PyObject *, const char *, PyMethodDef *);
+extern void typeready(PyTypeObject *);
+extern PyTypeObject *inittype(PyTypeObject *, PyTypeObject *);
+extern void addmethods(const PyMethodDef *);
+extern PyMethodDef *donemethods(void);
+
+/*----- Mapping methods ---------------------------------------------------*/
+
+#define GMAP_METH(func, doc) { #func, gmapmeth_##func, METH_VARARGS, doc },
+#define GMAP_KWMETH(func, doc)                                         \
+  { #func, (PyCFunction)gmapmeth_##func, METH_VARARGS|METH_KEYWORDS, doc },
+#define GMAP_METHDECL(func, doc)                                       \
+  extern PyObject *gmapmeth_##func(PyObject *, PyObject *);
+#define GMAP_KWMETHDECL(func, doc)                                     \
+  extern PyObject *gmapmeth_##func(PyObject *, PyObject *, PyObject *);
+
+#define GMAP_DOROMETHODS(METH, KWMETH)                                 \
+  METH (has_key,       "D.has_key(KEY) -> BOOL")                       \
+  METH (keys,          "D.keys() -> LIST")                             \
+  METH (values,        "D.values() -> LIST")                           \
+  METH (items,         "D.items() -> LIST")                            \
+  METH (iterkeys,      "D.iterkeys() -> ITER")                         \
+  METH (itervalues,    "D.itervalues() -> ITER")                       \
+  METH (iteritems,     "D.iteritems() -> ITER")                        \
+  KWMETH(get,          "D.get(KEY, [default = None]) -> VALUE")        \
+
+#define GMAP_DOMETHODS(METH, KWMETH)                                   \
+  GMAP_DOROMETHODS(METH, KWMETH)                                       \
+  METH (clear,         "D.clear()")                                    \
+  KWMETH(setdefault,   "D.setdefault(K, [default = None]) -> VALUE")   \
+  KWMETH(pop,          "D.pop(KEY, [default = <error>]) -> VALUE")     \
+  METH (popitem,       "D.popitem() -> (KEY, VALUE)")                  \
+  METH (update,        "D.update(MAP)")
+
+GMAP_DOMETHODS(GMAP_METHDECL, GMAP_KWMETHDECL)
+#define GMAP_ROMETHODS GMAP_DOROMETHODS(GMAP_METH, GMAP_KWMETH)
+#define GMAP_METHODS GMAP_DOMETHODS(GMAP_METH, GMAP_KWMETH)
+extern Py_ssize_t gmap_pysize(PyObject *);
+extern PySequenceMethods gmap_pysequence;
+extern PyMethodDef gmap_pymethods[];
+
 /*----- Bytestrings -------------------------------------------------------*/
 
 PyTypeObject *bytestring_pyobj;
@@ -219,8 +334,8 @@ extern PyTypeObject *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 *);
@@ -231,7 +346,7 @@ extern PyObject *gf_pywrap(mp *);
 extern mp *mp_frompyobject(PyObject *, int);
 extern PyObject *mp_topystring(mp *, int,
                               const char *, const char *, const char *);
-extern int mp_tolong_checked(mp *, long *);
+extern int mp_tolong_checked(mp *, long *, int);
 
 /*----- Abstract fields ---------------------------------------------------*/
 
@@ -253,7 +368,7 @@ typedef struct fe_pyobj {
   field *f;
   mp *x;
 } fe_pyobj;
-      
+
 extern PyTypeObject *field_pytype;
 extern PyTypeObject *primefield_pytype;
 extern PyTypeObject *niceprimefield_pytype;
@@ -309,7 +424,7 @@ typedef struct ecinfo_pyobj {
   ec_info ei;
   PyObject *cobj;
 } ecinfo_pyobj;
-      
+
 extern PyTypeObject *ecinfo_pytype;
 #define ECINFO_PYCHECK(o) PyObject_TypeCheck((o), ecinfo_pytype)
 #define ECINFO_EI(o) (&((ecinfo_pyobj *)(o))->ei)
@@ -404,24 +519,130 @@ typedef struct gccipher_pyobj {
 extern PyTypeObject *gccipher_pytype;
 #define GCCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gccipher_pytype)
 #define GCCIPHER_CC(o) (((gccipher_pyobj *)(o))->cc)
-#define GCCIPHER_F(o) (((gccipher_pyobj *)(o))->f)
 extern PyObject *gccipher_pywrap(gccipher *);
 extern int convgccipher(PyObject *, void *);
-extern int convgcipher(PyObject *, void *);
 
 typedef struct gcipher_pyobj {
   PyObject_HEAD
-  unsigned f;
   gcipher *c;
 } gcipher_pyobj;
 
 extern PyTypeObject *gcipher_pytype;
 #define GCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gcipher_pytype)
 #define GCIPHER_C(o) (((gcipher_pyobj *)(o))->c)
-#define GCIPHER_F(o) (((gcipher_pyobj *)(o))->f)
-extern PyObject *gcipher_pywrap(PyObject *, gcipher *, unsigned);
+extern PyObject *gcipher_pywrap(PyObject *, gcipher *);
 extern int convgcipher(PyObject *, void *);
 
+typedef struct gcaead_pyobj {
+  PyHeapTypeObject ty;
+  gcaead *aec;
+  struct gcaeadaad_pyobj *aad;
+  struct gcaeadenc_pyobj *enc;
+  struct gcaeaddec_pyobj *dec;
+} gcaead_pyobj;
+
+extern PyTypeObject *gcaead_pytype;
+#define GCAEAD_PYCHECK(o) PyObject_TypeCheck((o), gcaead_pytype)
+#define GCAEAD_AEC(o) (((gcaead_pyobj *)(o))->aec)
+#define GCAEAD_AAD(o) (((gcaead_pyobj *)(o))->aad)
+#define GCAEAD_ENC(o) (((gcaead_pyobj *)(o))->enc)
+#define GCAEAD_DEC(o) (((gcaead_pyobj *)(o))->dec)
+extern PyObject *gcaead_pywrap(gcaead *);
+extern int convgcaead(PyObject *, void *);
+
+typedef struct gaeadkey_pyobj {
+  PyObject_HEAD
+  gaead_key *k;
+} gaeadkey_pyobj;
+
+extern PyTypeObject *gaeadkey_pytype;
+#define GAEADKEY_PYCHECK(o) PyObject_TypeCheck((o), gaeadkey_pytype)
+#define GAEADKEY_K(o) (((gaeadkey_pyobj *)(o))->k)
+extern PyObject *gaeadkey_pywrap(PyObject *, gaead_key *);
+extern int convgaeadkey(PyObject *, void *);
+
+typedef struct gcaeadaad_pyobj {
+  PyHeapTypeObject ty;
+  gcaead_pyobj *key;
+} gcaeadaad_pyobj;
+#define GCAEADAAD_KEY(o) (((gcaeadaad_pyobj *)(o))->key)
+extern PyTypeObject *gcaeadaad_pytype;
+
+typedef struct gaeadaad_pyobj {
+  PyObject_HEAD
+  gaead_aad *a;
+  unsigned f;
+#define AEADF_DEAD 32768u
+  size_t hsz, hlen;
+} gaeadaad_pyobj;
+
+extern PyTypeObject *gaeadaad_pytype;
+#define GAEADAAD_PYCHECK(o) PyObject_TypeCheck((o), gaeadaad_pytype)
+#define GAEADAAD_A(o) (((gaeadaad_pyobj *)(o))->a)
+#define GAEADAAD_F(o) (((gaeadaad_pyobj *)(o))->f)
+#define GAEADAAD_HSZ(o) (((gaeadaad_pyobj *)(o))->hsz)
+#define GAEADAAD_HLEN(o) (((gaeadaad_pyobj *)(o))->hlen)
+extern PyObject *gaeadaad_pywrap(PyObject *, gaead_aad *, unsigned, size_t);
+extern int convgaeadaad(PyObject *, void *);
+
+typedef struct gcaeadenc_pyobj {
+  PyHeapTypeObject ty;
+  gcaead_pyobj *key;
+} gcaeadenc_pyobj;
+#define GCAEADENC_KEY(o) (((gcaeadenc_pyobj *)(o))->key)
+extern PyTypeObject *gcaeadenc_pytype;
+
+typedef struct gaeadenc_pyobj {
+  PyObject_HEAD
+  gaead_enc *e;
+  gaeadaad_pyobj *aad;
+  unsigned f;
+  size_t hsz, msz, tsz;
+  size_t mlen;
+} gaeadenc_pyobj;
+
+extern PyTypeObject *gaeadenc_pytype;
+#define GAEADENC_PYCHECK(o) PyObject_TypeCheck((o), gaeadenc_pytype)
+#define GAEADENC_AAD(o) (((gaeadenc_pyobj *)(o))->aad)
+#define GAEADENC_E(o) (((gaeadenc_pyobj *)(o))->e)
+#define GAEADENC_F(o) (((gaeadenc_pyobj *)(o))->f)
+#define GAEADENC_HSZ(o) (((gaeadenc_pyobj *)(o))->hsz)
+#define GAEADENC_MSZ(o) (((gaeadenc_pyobj *)(o))->msz)
+#define GAEADENC_TSZ(o) (((gaeadenc_pyobj *)(o))->tsz)
+#define GAEADENC_MLEN(o) (((gaeadenc_pyobj *)(o))->mlen)
+extern PyObject *gaeadenc_pywrap(PyObject *, gaead_enc *, unsigned,
+                                size_t, size_t, size_t);
+extern int convgaeadenc(PyObject *, void *);
+
+typedef struct gcaeaddec_pyobj {
+  PyHeapTypeObject ty;
+  gcaead_pyobj *key;
+} gcaeaddec_pyobj;
+#define GCAEADDEC_KEY(o) (((gcaeaddec_pyobj *)(o))->key)
+extern PyTypeObject *gcaeaddec_pytype;
+
+typedef struct gaeaddec_pyobj {
+  PyObject_HEAD
+  gaead_dec *d;
+  gaeadaad_pyobj *aad;
+  unsigned f;
+  size_t hsz, csz, tsz;
+  size_t clen;
+} gaeaddec_pyobj;
+
+extern PyTypeObject *gaeaddec_pytype;
+#define GAEADDEC_PYCHECK(o) PyObject_TypeCheck((o), gaeaddec_pytype)
+#define GAEADDEC_AAD(o) (((gaeaddec_pyobj *)(o))->aad)
+#define GAEADDEC_D(o) (((gaeaddec_pyobj *)(o))->d)
+#define GAEADDEC_F(o) (((gaeaddec_pyobj *)(o))->f)
+#define GAEADDEC_HSZ(o) (((gaeaddec_pyobj *)(o))->hsz)
+#define GAEADDEC_CSZ(o) (((gaeaddec_pyobj *)(o))->csz)
+#define GAEADDEC_TSZ(o) (((gaeaddec_pyobj *)(o))->tsz)
+#define GAEADDEC_CLEN(o) (((gaeaddec_pyobj *)(o))->clen)
+extern PyObject *gaeaddec_pywrap(PyObject *, gaead_dec *, unsigned,
+                                size_t, size_t, size_t);
+extern int convgaeaddec(PyObject *, void *);
+
 typedef struct gchash_pyobj {
   PyHeapTypeObject ty;
   gchash *ch;
@@ -430,13 +651,11 @@ typedef struct gchash_pyobj {
 extern PyTypeObject *gchash_pytype;
 #define GCHASH_PYCHECK(o) PyObject_TypeCheck((o), gchash_pytype)
 #define GCHASH_CH(o) (((gchash_pyobj *)(o))->ch)
-#define GCHASH_F(o) (((gchash_pyobj *)(o))->f)
 extern PyObject *gchash_pywrap(gchash *);
 extern int convgchash(PyObject *, void *);
 
 typedef struct ghash_pyobj {
   PyObject_HEAD
-  unsigned f;
   ghash *h;
 } ghash_pyobj;
 
@@ -444,8 +663,7 @@ extern PyTypeObject *ghash_pytype, *gmhash_pytype;
 extern PyObject *sha_pyobj, *has160_pyobj;
 #define GHASH_PYCHECK(o) PyObject_TypeCheck((o), ghash_pytype)
 #define GHASH_H(o) (((ghash_pyobj *)(o))->h)
-#define GHASH_F(o) (((ghash_pyobj *)(o))->f)
-extern PyObject *ghash_pywrap(PyObject *, ghash *, unsigned);
+extern PyObject *ghash_pywrap(PyObject *, ghash *);
 extern int convghash(PyObject *, void *);
 extern int convgmhash(PyObject *, void *);
 
@@ -463,7 +681,6 @@ extern int convgcmac(PyObject *, void *);
 
 typedef struct gmac_pyobj {
   PyHeapTypeObject ty;
-  unsigned f;
   gmac *m;
 } gmac_pyobj;
 
@@ -471,11 +688,11 @@ extern PyTypeObject *gmac_pytype;
 #define GMAC_PYCHECK(o) PyObject_TypeCheck((o), gmac_pytype)
 #define GMAC_M(o) (((gmac_pyobj *)(o))->m)
 #define GMAC_F(o) (((gmac_pyobj *)(o))->f)
-extern PyObject *gmac_pywrap(PyObject *, gmac *, unsigned);
+extern PyObject *gmac_pywrap(PyObject *, gmac *);
 extern int convgmac(PyObject *, void *);
 
 /*----- Key generation ----------------------------------------------------*/
-    
+
 typedef struct pfilt_pyobj {
   PyObject_HEAD
   pfilt f;
@@ -502,31 +719,6 @@ extern int convpgev(PyObject *, void *);
 extern void droppgev(pgev *);
 extern void pgenerr(void);
 
-/*----- Core utility functions --------------------------------------------*/
-
-extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
-                            PyObject *(*id)(PyObject *),
-                            int (*fill)(void *, PyObject *,
-                                        PyObject *, PyObject *),
-                            PyObject *(*exp)(PyObject *, void *, int),
-                            void (*drop)(void *));
-
-extern int convulong(PyObject *, void *);
-#define DECL_CONVU_(n) extern int convu##n(PyObject *, void *);
-DOUINTSZ(DECL_CONVU_)
-extern int convmpw(PyObject *, void *);
-extern int convuint(PyObject *, void *);
-extern int convszt(PyObject *, void *);
-extern int convbool(PyObject *, void *);
-extern PyObject *abstract_pynew(PyTypeObject *, PyObject *, PyObject *);
-extern PyObject *getbool(int);
-#define DECL_GETU_(n) extern PyObject *getu##n(uint##n);
-DOUINTSZ(DECL_GETU_)
-extern PyObject * mkexc(PyObject *, PyObject *, const char *, PyMethodDef *);
-extern void *newtype(PyTypeObject *, const PyTypeObject *, const char *);
-extern PyTypeObject *inittype(PyTypeObject *);
-extern void addmethods(const PyMethodDef *);
-
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus