Start on Python interface without SWIG
This commit is contained in:
parent
4789a830e9
commit
aa60016dd2
|
@ -15,8 +15,7 @@ inc/blst_aux.h*
|
|||
.vscode/
|
||||
*.json
|
||||
.clang-format
|
||||
*bindings/*/_*.so
|
||||
*bindings/*/lib*.so
|
||||
*bindings/*/*.so
|
||||
*bindings/python/ckzg_swig.py
|
||||
*bindings/python/ckzg.py
|
||||
*bindings/C#/ckzg_swig.cs
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
INCLUDE_DIRS = .. ../../min-src ../../inc
|
||||
INCLUDE_PY = $(shell python -c 'import sysconfig; print(sysconfig.get_config_var("INCLUDEPY"))')
|
||||
|
||||
test: tests.py ckzg.so
|
||||
python $<
|
||||
|
||||
test_swig: tests_swig.py _ckzg_swig.so
|
||||
python $<
|
||||
|
||||
_ckzg_swig.so: c_kzg_4844_wrap.c ../../min-src/c_kzg_4844.o ../../lib/libblst.a
|
||||
clang -O -Wall -shared -fPIC -Wl,-Bsymbolic -I${INCLUDE_PY} ${addprefix -I,${INCLUDE_DIRS}} -o $@ $^
|
||||
|
||||
ckzg.so: ckzg.c ../../min-src/c_kzg_4844.o ../../lib/libblst.a
|
||||
clang -O -Wall -shared -fPIC -Wl,-Bsymbolic -I${INCLUDE_PY} ${addprefix -I,${INCLUDE_DIRS}} -o $@ $^
|
||||
|
||||
c_kzg_4844_wrap.c ckzg_swig.py: ../c_kzg_4844.swg
|
||||
swig -DSWIGWORDSIZE64 -O -Wall -python -outcurrentdir $<
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include "c_kzg_4844.h"
|
||||
|
||||
static void free_capsule(PyObject *c) {
|
||||
free(PyCapsule_GetPointer(c, PyCapsule_GetName(c)));
|
||||
}
|
||||
|
||||
static PyObject* bytes_to_bls_field_wrap(PyObject *self, PyObject *args) {
|
||||
PyBytesObject *pybytes;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "S", &pybytes) ||
|
||||
PyBytes_Size((PyObject*)pybytes) != 32)
|
||||
return PyErr_Format(PyExc_ValueError, "expected 32 bytes");
|
||||
|
||||
BLSFieldElement *out = (BLSFieldElement*)malloc(sizeof(BLSFieldElement));
|
||||
|
||||
if (out == NULL) return PyErr_NoMemory();
|
||||
|
||||
bytes_to_bls_field(out, (const uint8_t*)PyBytes_AsString((PyObject*)pybytes));
|
||||
|
||||
return PyCapsule_New(out, "BLSFieldElement", free_capsule);
|
||||
}
|
||||
|
||||
static PyObject* uint64s_from_BLSFieldElement_wrap(PyObject *self, PyObject *args) {
|
||||
PyObject *c;
|
||||
if (!PyArg_UnpackTuple(args, "uint64s_from_BLSFieldElement", 1, 1, &c) ||
|
||||
!PyCapsule_IsValid(c, "BLSFieldElement"))
|
||||
return PyErr_Format(PyExc_ValueError, "expected a BLSFieldElement capsule");
|
||||
uint64_t out[4];
|
||||
uint64s_from_BLSFieldElement(out, PyCapsule_GetPointer(c, PyCapsule_GetName(c)));
|
||||
return PyTuple_Pack(4,
|
||||
PyLong_FromUnsignedLong(out[0]),
|
||||
PyLong_FromUnsignedLong(out[1]),
|
||||
PyLong_FromUnsignedLong(out[2]),
|
||||
PyLong_FromUnsignedLong(out[3]));
|
||||
}
|
||||
|
||||
static PyMethodDef ckzgmethods[] = {
|
||||
{"uint64s_from_BLSFieldElement", uint64s_from_BLSFieldElement_wrap, METH_VARARGS, "Convert a field element to a 4-tuple of uint64s"},
|
||||
{"bytes_to_bls_field", bytes_to_bls_field_wrap, METH_VARARGS, "Convert 32 bytes to a field element"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef ckzg = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"ckzg",
|
||||
NULL,
|
||||
-1,
|
||||
ckzgmethods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_ckzg(void)
|
||||
{
|
||||
return PyModule_Create(&ckzg);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import atexit
|
||||
import ckzg
|
||||
import random
|
||||
import ssz
|
||||
|
||||
def int_from_fr(fr):
|
||||
digits = ckzg.uint64s_from_BLSFieldElement(fr)
|
||||
res, mult = 0, 1
|
||||
for x in digits:
|
||||
res += mult * x
|
||||
mult *= 2**64
|
||||
return res
|
||||
|
||||
# Simple test of bytes_to_bls_field
|
||||
|
||||
bs = (329).to_bytes(32, "little")
|
||||
fr = ckzg.bytes_to_bls_field(bs)
|
||||
assert int_from_fr(fr) == 329
|
||||
|
||||
print('Tests passed')
|
||||
|
||||
def cleanup():
|
||||
pass
|
||||
|
||||
atexit.register(cleanup)
|
Loading…
Reference in New Issue