Start on Python interface without SWIG

This commit is contained in:
Ramana Kumar 2022-10-02 00:52:12 +01:00
parent 4789a830e9
commit aa60016dd2
No known key found for this signature in database
GPG Key ID: ED471C788B900433
4 changed files with 88 additions and 2 deletions

3
.gitignore vendored
View File

@ -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

View File

@ -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 $<

View File

@ -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);
}

View File

@ -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)