summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--cffi_random.py82
-rw-r--r--helloworld.pyx1
-rw-r--r--randomize.pyx14
-rw-r--r--setup.py11
5 files changed, 107 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 9021ee4..b2b6d48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,2 @@
-*.c
-*~
-*.so
-build/ \ No newline at end of file
+__pycache__/
+build/
diff --git a/cffi_random.py b/cffi_random.py
new file mode 100644
index 0000000..5f62e43
--- /dev/null
+++ b/cffi_random.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+import sys
+from typing import Optional
+
+from cffi import FFI
+
+class RandError(RuntimeError):
+ pass
+
+ffi = FFI()
+ffi.cdef('''
+ void RAND_seed(const void *buf, int num);
+
+ void RAND_add(const void *buf, int num, double entropy);
+
+ int RAND_status(void);
+
+ int RAND_event(unsigned int iMsg, void* wParam, void* lParam);
+ void RAND_screen(void);
+
+ int RAND_bytes(unsigned char *buf, int num);
+
+ int RAND_pseudo_bytes(unsigned char *buf, int num);
+
+ const char *ERR_reason_error_string(unsigned long);
+
+ unsigned long ERR_get_error(void);
+''')
+
+lib = ffi.dlopen('crypto')
+
+def rand_add(buf: bytes, num: int, entropy: float) -> None:
+ assert isinstance(entropy, float)
+ lib.RAND_add(buf, num, entropy)
+
+def rand_seed(buf: bytes, num: int) -> None:
+ lib.RAND_seed(buf, num)
+
+def rand_status() -> int:
+ return lib.RAND_status()
+
+def rand_event(iMsg: int, wParam: int, lParam: int) -> Optional[int]:
+ if sys.platform == 'win32':
+ return lib.RAND_event(iMsg, wParam, lParam)
+ else:
+ return None
+
+def rand_screen() -> None:
+ if sys.platform == 'win32':
+ lib.RAND_screen()
+
+def rand_bytes(n: int = 8) -> bytes:
+ buf = ffi.new('unsigned char buf[{:d}]'.format(n))
+ ret = lib.RAND_bytes(buf, n)
+ if ret == 1:
+ return bytes(buf)
+ elif ret == 0:
+ RandError("Not enough randomness.")
+ elif ret == -1:
+ RandError("Not supported by the current RAND method.")
+ else:
+ err_msg = lib.ERR_reason_error_string(lib.ERR_get_error())
+ if err_msg is not None:
+ RandError(err_msg)
+ else:
+ RandError("Unknown error in function RAND_bytes")
+
+def rand_pseudo_bytes(n: int) -> bytes:
+ blob = ffi.new('unsigned char buf[{:d}]'.format(n))
+ ret = lib.RAND_pseudo_bytes(blob, n)
+
+ if ret == -1:
+ RandError("Not supported by the current RAND method.")
+ elif ret in [0, 1]:
+ return (blob, ret)
+ else:
+ RandError("Unknown error in RAND_pseudo_bytes")
+
+
+if __name__=='__main__':
+ print(rand_bytes())
diff --git a/helloworld.pyx b/helloworld.pyx
deleted file mode 100644
index ad35e5a..0000000
--- a/helloworld.pyx
+++ /dev/null
@@ -1 +0,0 @@
-print("Hello World")
diff --git a/randomize.pyx b/randomize.pyx
new file mode 100644
index 0000000..99cd0ab
--- /dev/null
+++ b/randomize.pyx
@@ -0,0 +1,14 @@
+cdef extern from "openssl/rand.h":
+ void RAND_seed(
+ const void *buf, int num)
+ void RAND_add(const void *buf, int num, double entropy)
+ int RAND_status()
+ void RAND_screen()
+
+def rand_add(buf: bytes, num: int, entropy: float) -> None:
+ assert isinstance(entropy, float)
+ RAND_add(buf, num, entropy)
+
+def rand_seed(buf: bytes, num: int) -> None:
+ RAND_seed(buf, num)
+
diff --git a/setup.py b/setup.py
index 7b3ba28..800e1d7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,7 @@
from distutils.core import setup
-from Cython.Build import cythonize
+from distutils.extension import Extension
+
+from Cython.Distutils import build_ext
setup(
name='test_Cython',
@@ -8,5 +10,10 @@ setup(
platforms=['any'],
author='Matej Cepl',
author_email='mcepl@cepl.eu',
- ext_modules = cythonize("helloworld.pyx")
+ cmdclass={'build_ext': build_ext},
+ ext_modules = [
+ Extension("randomize",
+ ["randomize.pyx"],
+ libraries=["ssl", "crypto"])
+ ]
)