Compare commits

..

No commits in common. "009f0736b34fb62cd24245d897e5884105f6c1b9" and "6a110685f8b9026df62567f5e503576f3e3b43d0" have entirely different histories.

11 changed files with 51 additions and 89 deletions

5
.gitignore vendored
View file

@ -1,6 +1,3 @@
__pycache__/
*.iml
.idea/
.venv/
.vscode/
debug.log
.idea/

4
.gitmodules vendored
View file

@ -1,4 +0,0 @@
[submodule "MeterFeeder"]
path = MeterFeeder
url = git@github.com:TheRandonauts/MeterFeeder.git
shallow = true

View file

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

@ -1 +0,0 @@
Subproject commit 6b8de4bd2c8fc0c483c1988b1d99694d8ad31d8d

View file

@ -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:<port>/api/json/randint32?length=3&deviceId=QWR4E001
< {"devices":['QWR4E002|MED100KX8 100 kHz', 'QWR4E001|MED100KX8 100 kHz']}
http://localhost:<port>/api/json/randint32?length=3&deviceId=QWR4E001
< {"server": "<servername>", "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.

1
debug.log Normal file
View file

@ -0,0 +1 @@
[0917/192900.742:ERROR:registration_protocol_win.cc(103)] CreateFile: The system cannot find the file specified. (0x2)

BIN
libmeterfeeder.dylib Executable file

Binary file not shown.

BIN
libmeterfeeder.so Normal file

Binary file not shown.

BIN
meterfeeder.dll Normal file

Binary file not shown.

View file

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

View file

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