aboutsummaryrefslogtreecommitdiff
path: root/python-src/curve25519/curve25519module.c
diff options
context:
space:
mode:
Diffstat (limited to 'python-src/curve25519/curve25519module.c')
-rw-r--r--python-src/curve25519/curve25519module.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/python-src/curve25519/curve25519module.c b/python-src/curve25519/curve25519module.c
new file mode 100644
index 0000000..e309ec0
--- /dev/null
+++ b/python-src/curve25519/curve25519module.c
@@ -0,0 +1,105 @@
+/* tell python that PyArg_ParseTuple(t#) means Py_ssize_t, not int */
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#if (PY_VERSION_HEX < 0x02050000)
+ typedef int Py_ssize_t;
+#endif
+
+/* This is required for compatibility with Python 2. */
+#if PY_MAJOR_VERSION >= 3
+ #include <bytesobject.h>
+ #define y "y"
+#else
+ #define PyBytes_FromStringAndSize PyString_FromStringAndSize
+ #define y "t"
+#endif
+
+int curve25519_donna(char *mypublic,
+ const char *secret, const char *basepoint);
+
+static PyObject *
+pycurve25519_makeprivate(PyObject *self, PyObject *args)
+{
+ char *in1;
+ Py_ssize_t in1len;
+ if (!PyArg_ParseTuple(args, y"#:clamp", &in1, &in1len))
+ return NULL;
+ if (in1len != 32) {
+ PyErr_SetString(PyExc_ValueError, "input must be 32-byte string");
+ return NULL;
+ }
+ in1[0] &= 248;
+ in1[31] &= 127;
+ in1[31] |= 64;
+ return PyBytes_FromStringAndSize((char *)in1, 32);
+}
+
+static PyObject *
+pycurve25519_makepublic(PyObject *self, PyObject *args)
+{
+ const char *private;
+ char mypublic[32];
+ char basepoint[32] = {9};
+ Py_ssize_t privatelen;
+ if (!PyArg_ParseTuple(args, y"#:makepublic", &private, &privatelen))
+ return NULL;
+ if (privatelen != 32) {
+ PyErr_SetString(PyExc_ValueError, "input must be 32-byte string");
+ return NULL;
+ }
+ curve25519_donna(mypublic, private, basepoint);
+ return PyBytes_FromStringAndSize((char *)mypublic, 32);
+}
+
+static PyObject *
+pycurve25519_makeshared(PyObject *self, PyObject *args)
+{
+ const char *myprivate, *theirpublic;
+ char shared_key[32];
+ Py_ssize_t myprivatelen, theirpubliclen;
+ if (!PyArg_ParseTuple(args, y"#"y"#:generate",
+ &myprivate, &myprivatelen, &theirpublic, &theirpubliclen))
+ return NULL;
+ if (myprivatelen != 32) {
+ PyErr_SetString(PyExc_ValueError, "input must be 32-byte string");
+ return NULL;
+ }
+ if (theirpubliclen != 32) {
+ PyErr_SetString(PyExc_ValueError, "input must be 32-byte string");
+ return NULL;
+ }
+ curve25519_donna(shared_key, myprivate, theirpublic);
+ return PyBytes_FromStringAndSize((char *)shared_key, 32);
+}
+
+
+static PyMethodDef
+curve25519_functions[] = {
+ {"make_private", pycurve25519_makeprivate, METH_VARARGS, "data->private"},
+ {"make_public", pycurve25519_makepublic, METH_VARARGS, "private->public"},
+ {"make_shared", pycurve25519_makeshared, METH_VARARGS, "private+public->shared"},
+ {NULL, NULL, 0, NULL},
+};
+
+#if PY_MAJOR_VERSION >= 3
+ static struct PyModuleDef
+ curve25519_module = {
+ PyModuleDef_HEAD_INIT,
+ "_curve25519",
+ NULL,
+ NULL,
+ curve25519_functions,
+ };
+
+ PyObject *
+ PyInit__curve25519(void)
+ {
+ return PyModule_Create(&curve25519_module);
+ }
+#else
+ PyMODINIT_FUNC
+ init_curve25519(void)
+ {
+ (void)Py_InitModule("_curve25519", curve25519_functions);
+ }
+#endif \ No newline at end of file