diff --git a/.gitignore b/.gitignore index cbc0f6d..a5179e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ __pycache__/ *.iml -.idea/ -.venv/ -.vscode/ -debug.log \ No newline at end of file +.idea/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 501d18b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "MeterFeeder"] - path = MeterFeeder - url = git@github.com:TheRandonauts/MeterFeeder.git - shallow = true diff --git a/LICENSE b/LICENSE index 23eab68..2105aad 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,6 @@ MIT License Copyright (c) 2020 Andika Wasisto -Modified by randogoth / Randonauts Co. -Modified by soliax / fp2.dev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MeterFeeder b/MeterFeeder deleted file mode 160000 index 6b8de4b..0000000 --- a/MeterFeeder +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6b8de4bd2c8fc0c483c1988b1d99694d8ad31d8d diff --git a/README.md b/README.md index dad2bdc..de56092 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -Quanttp 2 Entropy Server -======================== +Pod Entropy Server +================== _based on [quanttp](https://github.com/awasisto/quanttp) by [Andika Wasisto](https://www.wasisto.com/)_ -An HTTP API that wraps [MeterFeeder](https://github.com/TheRandonauts/MeterFeeder) instead of the [ComScire quantum random number generator API](https://comscire.com/downloads/qwqngdoc/) to support serving entropy from multiple devices. It also adds JSON endpoints. +An HTTP API that wraps [ComScire quantum random number generator API](https://comscire.com/downloads/qwqngdoc/). Running ------- @@ -37,6 +37,9 @@ Usage Example ### REST JSON API + http://localhost:/api/json/randint32?length=3&deviceId=QWR4E001 + < {"devices":['QWR4E002|MED100KX8 100 kHz', 'QWR4E001|MED100KX8 100 kHz']} + http://localhost:/api/json/randint32?length=3&deviceId=QWR4E001 < {"server": "", "type": "string", "format": "int32", "length": 3, "data": [1524492492, -1194151004, 1365408501], "success": "true"} @@ -100,7 +103,7 @@ License ------- Copyright (c) 2020 Andika Wasisto - Modified by randogoth / Randonauts Co. + Modified by Tobias Raayoni Last / Randonauts Co. Modified by soliax / fp2.dev Permission is hereby granted, free of charge, to any person obtaining a copy @@ -119,4 +122,4 @@ License AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + SOFTWARE. \ No newline at end of file diff --git a/debug.log b/debug.log new file mode 100644 index 0000000..2398904 --- /dev/null +++ b/debug.log @@ -0,0 +1 @@ +[0917/192900.742:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2) diff --git a/libmeterfeeder.dylib b/libmeterfeeder.dylib new file mode 100755 index 0000000..7968ec6 Binary files /dev/null and b/libmeterfeeder.dylib differ diff --git a/libmeterfeeder.so b/libmeterfeeder.so new file mode 100644 index 0000000..7b1073e Binary files /dev/null and b/libmeterfeeder.so differ diff --git a/meterfeeder.dll b/meterfeeder.dll new file mode 100644 index 0000000..3bdb168 Binary files /dev/null and b/meterfeeder.dll differ diff --git a/quanttp/__main__.py b/quanttp/__main__.py index f7a61bc..961171b 100644 --- a/quanttp/__main__.py +++ b/quanttp/__main__.py @@ -1,5 +1,5 @@ # Copyright (c) 2020 Andika Wasisto -# Modified by randogoth +# Modified by Tobias Raayoni Last # Modified by soliax # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -159,95 +159,95 @@ def serve(servername, port, id): try: deviceId = request.args.get('deviceId') if len(deviceId) != 8: - return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') int32array = [] for x in range(0, length): int32array.append(mf_wrapper.randint32(deviceId)) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "int32", "length":length, "data": int32array, "success":True}), content_type='application/json') + return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "int32", "length":length, "data": int32array, "success": "true"}), content_type='application/json') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "status": status, "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": str(e), "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randuniform') def randjsonuniform(): try: deviceId = request.args.get('deviceId') if len(deviceId) != 8: - return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') uniformarray = [] for x in range(0, length): uniformarray.append(mf_wrapper.randuniform(deviceId)) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "uniform", "length":length, "data": uniformarray, "success":True}), content_type='application/json') + return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "uniform", "length":length, "data": uniformarray, "success": "true"}), content_type='application/json') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randnormal') def randjsonnormal(): try: deviceId = request.args.get('deviceId') if len(deviceId) != 8: - return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') status = str(mf_wrapper.status()) length = int(request.args.get('length')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') normarray = [] for x in range(0, length): normarray.append(mf_wrapper.randnormal(deviceId)) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "normal", "length":length, "data": normarray, "success":True}), content_type='application/json') + return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "normal", "length":length, "data": normarray, "success": "true"}), content_type='application/json') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randhex') def randjsonhex(): try: deviceId = request.args.get('deviceId') if len(deviceId) != 8: - return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') status = str(mf_wrapper.status()) length = int(request.args.get('length')) size = int(request.args.get('size')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') if size < 1: - return Response(json.dumps({"error": 'size must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='application/json') # entropy = mf_wrapper.randbytes(size*length) hexarray = [] for x in range(0, length): hexarray.append(mf_wrapper.randbytes(deviceId, size).hex()) # hexarray.append(entropy[x*size:(x+1)*size].hex()) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "hex", "length":length, "size": size, "data": hexarray, "success":True}), content_type='application/json') + return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "hex", "length":length, "size": size, "data": hexarray, "success": "true"}), content_type='application/json') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') @app.route('/api/json/randbase64') def randjsonbase64(): try: deviceId = request.args.get('deviceId') if len(deviceId) != 8: - return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'deviceId must be a valid 8 character serial number', "success":"false"}), status=400, content_type='application/json') status = str(mf_wrapper.status()) length = int(request.args.get('length')) size = int(request.args.get('size')) if length < 1: - return Response(json.dumps({"error": 'length must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'length must be greater than 0', "success":"false"}), status=400, content_type='application/json') if size < 1: - return Response(json.dumps({"error": 'size must be greater than 0', "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": 'size must be greater than 0', "success":"false"}), status=400, content_type='application/json') # entropy = mf_wrapper.randbytes(size*length) basearray = [] for x in range(0, length): basearray.append(base64.b64encode(mf_wrapper.randbytes(deviceId, size)).decode('utf-8')) # basearray.append(base64.b64encode(entropy[x*size:(x+1)*size]).decode('utf-8')) - return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "base64", "length":length, "size": size, "data": basearray, "success":True}), content_type='application/json') + return Response(json.dumps({"server" : servername, "device": id, "status": status, "type": "string", "format": "base64", "length":length, "size": size, "data": basearray, "success": "true"}), content_type='application/json') except (TypeError, ValueError) as e: - return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":False}), status=400, content_type='application/json') + return Response(json.dumps({"error": str(e), "device": id, "status": status, "success":"false"}), status=400, content_type='application/json') # Websockets ---------------------------------------------- @@ -261,85 +261,53 @@ def serve(servername, port, id): def handle_ws_message(message, websocket, subscribed): try: split_message = message.strip().upper().split() - if split_message[0] == 'DEVICES': - websocket.send(str(mf_wrapper.deviceIds(False))) - elif split_message[0] == 'RANDINT32': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - websocket.send(str(mf_wrapper.randint32(deviceId))) + if split_message[0] == 'RANDINT32': + websocket.send(str(mf_wrapper.randint32())) elif split_message[0] == 'RANDUNIFORM': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - websocket.send(str(mf_wrapper.randuniform(deviceId))) + websocket.send(str(mf_wrapper.randuniform())) elif split_message[0] == 'RANDNORMAL': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - websocket.send(str(mf_wrapper.randnormal(deviceId))) + websocket.send(str(mf_wrapper.randnormal())) elif split_message[0] == 'RANDBYTES': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - length = int(split_message[2]) + length = int(split_message[1]) if length < 1: raise ValueError() - websocket.send(mf_wrapper.randbytes(deviceId, length)) + websocket.send(mf_wrapper.randbytes(length)) elif split_message[0] == 'SUBSCRIBEINT32': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(mf_wrapper.randint32(deviceId))) + websocket.send(str(mf_wrapper.randint32())) elif split_message[0] == 'SUBSCRIBEUNIFORM': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(mf_wrapper.randuniform(deviceId))) + websocket.send(str(mf_wrapper.randuniform())) elif split_message[0] == 'SUBSCRIBENORMAL': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(str(mf_wrapper.randnormal(deviceId))) + websocket.send(str(mf_wrapper.randnormal())) elif split_message[0] == 'SUBSCRIBEBYTES': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - chunk = int(split_message[2]) + chunk = int(split_message[1]) if chunk < 1: raise ValueError() if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(mf_wrapper.randbytes(deviceId, chunk)) + websocket.send(mf_wrapper.randbytes(chunk)) elif split_message[0] == 'SUBSCRIBEHEX': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - chunk = int(split_message[2]) + chunk = int(split_message[1]) if chunk < 1: raise ValueError() if not subscribed[0]: subscribed[0] = True while subscribed[0] and not websocket.closed: - websocket.send(mf_wrapper.randbytes(deviceId, chunk).hex()) + websocket.send(mf_wrapper.randbytes(chunk).hex()) elif split_message[0] == 'UNSUBSCRIBE': subscribed[0] = False websocket.send('UNSUBSCRIBED') elif split_message[0] == 'CLEAR': - deviceId = split_message[1] - if len(deviceId) != 8: - raise ValueError() - mf_wrapper.clear(deviceId) + mf_wrapper.clear() except (IndexError, ValueError, BlockingIOError): pass except Exception as e: diff --git a/quanttp/data/meterfeeder_wrapper.py b/quanttp/data/meterfeeder_wrapper.py index f8cb3cb..86aa006 100644 --- a/quanttp/data/meterfeeder_wrapper.py +++ b/quanttp/data/meterfeeder_wrapper.py @@ -1,7 +1,7 @@ ## # MeterFeeder Library Wrapper # - # by soliax, randogoth + # by soliax ## from platform import os @@ -15,13 +15,13 @@ class MeterFeederWrapper: def __init__(self): if platform == "linux" or platform == "linux2": # Linux - self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/linux/libmeterfeeder.so') + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.so') elif platform == "darwin": # OS X - self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/mac/libmeterfeeder.dylib') + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.dylib') elif platform == "win32": # Windows - self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/windows/meterfeeder.dll') + self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/meterfeeder.dll') # Declare function bridging self._meterfeeder.MF_Initialize.argtypes = c_char_p,