Compare commits

...

10 commits

Author SHA1 Message Date
randogoth
009f0736b3 updated 2023-05-28 17:48:05 +03:00
randogoth
956de4527f vscode 2023-05-28 16:31:48 +03:00
randogoth
249de6f98d ignore VS stuff 2023-05-28 16:31:31 +03:00
randogoth
6d4b8c8e86 metefeeder submodule 2023-05-28 16:19:30 +03:00
randogoth
d4acf64815 MeterFeeder as submodule 2023-05-28 16:19:27 +03:00
randogoth
05b0da388d
Update README.md 2023-05-28 15:53:40 +03:00
randogoth
b3b12b5bcc
Update README.md
renamed
2023-05-28 15:45:08 +03:00
Randonauts Co
3052b46d77
Merge pull request #2 from Taha-Firoz/Patch
Fixed success type to boolean
2022-01-04 18:43:21 +00:00
Mohammad Taha Bin Firoz
bd9df52b3e fixed to boolean type 2022-01-04 17:17:56 +00:00
Simon Nishi McCorkindale
8bf5b4bbda Update WebSockets API to MeterFeeder (untested) 2021-06-05 21:39:39 +08:00
11 changed files with 89 additions and 51 deletions

3
.gitignore vendored
View file

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

4
.gitmodules vendored Normal file
View file

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

View file

@ -1,6 +1,8 @@
MIT License MIT License
Copyright (c) 2020 Andika Wasisto 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

1
MeterFeeder Submodule

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

View file

@ -1,9 +1,9 @@
Pod Entropy Server Quanttp 2 Entropy Server
================== ========================
_based on [quanttp](https://github.com/awasisto/quanttp) by [Andika Wasisto](https://www.wasisto.com/)_ _based on [quanttp](https://github.com/awasisto/quanttp) by [Andika Wasisto](https://www.wasisto.com/)_
An HTTP API that wraps [ComScire quantum random number generator API](https://comscire.com/downloads/qwqngdoc/). 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.
Running Running
------- -------
@ -37,9 +37,6 @@ Usage Example
### REST JSON API ### 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 http://localhost:<port>/api/json/randint32?length=3&deviceId=QWR4E001
< {"server": "<servername>", "type": "string", "format": "int32", "length": 3, "data": [1524492492, -1194151004, 1365408501], "success": "true"} < {"server": "<servername>", "type": "string", "format": "int32", "length": 3, "data": [1524492492, -1194151004, 1365408501], "success": "true"}
@ -103,7 +100,7 @@ License
------- -------
Copyright (c) 2020 Andika Wasisto Copyright (c) 2020 Andika Wasisto
Modified by Tobias Raayoni Last / Randonauts Co. Modified by randogoth / Randonauts Co.
Modified by soliax / fp2.dev Modified by soliax / fp2.dev
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,5 @@
# Copyright (c) 2020 Andika Wasisto # Copyright (c) 2020 Andika Wasisto
# Modified by Tobias Raayoni Last # Modified by randogoth
# Modified by soliax # Modified by soliax
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
@ -159,95 +159,95 @@ def serve(servername, port, id):
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: 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()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: 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 = [] int32array = []
for x in range(0, length): for x in range(0, length):
int32array.append(mf_wrapper.randint32(deviceId)) 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: 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') @app.route('/api/json/randuniform')
def randjsonuniform(): def randjsonuniform():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: 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()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: 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 = [] uniformarray = []
for x in range(0, length): for x in range(0, length):
uniformarray.append(mf_wrapper.randuniform(deviceId)) 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: 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') @app.route('/api/json/randnormal')
def randjsonnormal(): def randjsonnormal():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: 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()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
if length < 1: 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 = [] normarray = []
for x in range(0, length): for x in range(0, length):
normarray.append(mf_wrapper.randnormal(deviceId)) 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: 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') @app.route('/api/json/randhex')
def randjsonhex(): def randjsonhex():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: 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()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
size = int(request.args.get('size')) size = int(request.args.get('size'))
if length < 1: 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: 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) # entropy = mf_wrapper.randbytes(size*length)
hexarray = [] hexarray = []
for x in range(0, length): for x in range(0, length):
hexarray.append(mf_wrapper.randbytes(deviceId, size).hex()) hexarray.append(mf_wrapper.randbytes(deviceId, size).hex())
# hexarray.append(entropy[x*size:(x+1)*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: 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') @app.route('/api/json/randbase64')
def randjsonbase64(): def randjsonbase64():
try: try:
deviceId = request.args.get('deviceId') deviceId = request.args.get('deviceId')
if len(deviceId) != 8: 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()) status = str(mf_wrapper.status())
length = int(request.args.get('length')) length = int(request.args.get('length'))
size = int(request.args.get('size')) size = int(request.args.get('size'))
if length < 1: 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: 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) # entropy = mf_wrapper.randbytes(size*length)
basearray = [] basearray = []
for x in range(0, length): for x in range(0, length):
basearray.append(base64.b64encode(mf_wrapper.randbytes(deviceId, size)).decode('utf-8')) 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')) # 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: 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 ---------------------------------------------- # Websockets ----------------------------------------------
@ -261,53 +261,85 @@ def serve(servername, port, id):
def handle_ws_message(message, websocket, subscribed): def handle_ws_message(message, websocket, subscribed):
try: try:
split_message = message.strip().upper().split() split_message = message.strip().upper().split()
if split_message[0] == 'RANDINT32': if split_message[0] == 'DEVICES':
websocket.send(str(mf_wrapper.randint32())) 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)))
elif split_message[0] == 'RANDUNIFORM': elif split_message[0] == 'RANDUNIFORM':
websocket.send(str(mf_wrapper.randuniform())) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
websocket.send(str(mf_wrapper.randuniform(deviceId)))
elif split_message[0] == 'RANDNORMAL': elif split_message[0] == 'RANDNORMAL':
websocket.send(str(mf_wrapper.randnormal())) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
websocket.send(str(mf_wrapper.randnormal(deviceId)))
elif split_message[0] == 'RANDBYTES': elif split_message[0] == 'RANDBYTES':
length = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
length = int(split_message[2])
if length < 1: if length < 1:
raise ValueError() raise ValueError()
websocket.send(mf_wrapper.randbytes(length)) websocket.send(mf_wrapper.randbytes(deviceId, length))
elif split_message[0] == 'SUBSCRIBEINT32': elif split_message[0] == 'SUBSCRIBEINT32':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randint32())) websocket.send(str(mf_wrapper.randint32(deviceId)))
elif split_message[0] == 'SUBSCRIBEUNIFORM': elif split_message[0] == 'SUBSCRIBEUNIFORM':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randuniform())) websocket.send(str(mf_wrapper.randuniform(deviceId)))
elif split_message[0] == 'SUBSCRIBENORMAL': elif split_message[0] == 'SUBSCRIBENORMAL':
deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(str(mf_wrapper.randnormal())) websocket.send(str(mf_wrapper.randnormal(deviceId)))
elif split_message[0] == 'SUBSCRIBEBYTES': elif split_message[0] == 'SUBSCRIBEBYTES':
chunk = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
chunk = int(split_message[2])
if chunk < 1: if chunk < 1:
raise ValueError() raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(mf_wrapper.randbytes(chunk)) websocket.send(mf_wrapper.randbytes(deviceId, chunk))
elif split_message[0] == 'SUBSCRIBEHEX': elif split_message[0] == 'SUBSCRIBEHEX':
chunk = int(split_message[1]) deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
chunk = int(split_message[2])
if chunk < 1: if chunk < 1:
raise ValueError() raise ValueError()
if not subscribed[0]: if not subscribed[0]:
subscribed[0] = True subscribed[0] = True
while subscribed[0] and not websocket.closed: while subscribed[0] and not websocket.closed:
websocket.send(mf_wrapper.randbytes(chunk).hex()) websocket.send(mf_wrapper.randbytes(deviceId, chunk).hex())
elif split_message[0] == 'UNSUBSCRIBE': elif split_message[0] == 'UNSUBSCRIBE':
subscribed[0] = False subscribed[0] = False
websocket.send('UNSUBSCRIBED') websocket.send('UNSUBSCRIBED')
elif split_message[0] == 'CLEAR': elif split_message[0] == 'CLEAR':
mf_wrapper.clear() deviceId = split_message[1]
if len(deviceId) != 8:
raise ValueError()
mf_wrapper.clear(deviceId)
except (IndexError, ValueError, BlockingIOError): except (IndexError, ValueError, BlockingIOError):
pass pass
except Exception as e: except Exception as e:

View file

@ -1,7 +1,7 @@
## ##
# MeterFeeder Library Wrapper # MeterFeeder Library Wrapper
# #
# by soliax # by soliax, randogoth
## ##
from platform import os from platform import os
@ -15,13 +15,13 @@ class MeterFeederWrapper:
def __init__(self): def __init__(self):
if platform == "linux" or platform == "linux2": if platform == "linux" or platform == "linux2":
# Linux # Linux
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.so') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/linux/libmeterfeeder.so')
elif platform == "darwin": elif platform == "darwin":
# OS X # OS X
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/libmeterfeeder.dylib') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/mac/libmeterfeeder.dylib')
elif platform == "win32": elif platform == "win32":
# Windows # Windows
self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/meterfeeder.dll') self._meterfeeder = cdll.LoadLibrary(os.getcwd() + '/MeterFeeder/builds/windows/meterfeeder.dll')
# Declare function bridging # Declare function bridging
self._meterfeeder.MF_Initialize.argtypes = c_char_p, self._meterfeeder.MF_Initialize.argtypes = c_char_p,