mirror of https://github.com/nucypher/nucypher.git
Merge branch 'master' of github.com:nucypher/nucypher-kms
commit
e9ce021283
|
@ -161,7 +161,7 @@ rather than just one rekey.
|
|||
After the calculation, the rk is stored with the KMS network. It will be stored in the following
|
||||
persistent mapping::
|
||||
|
||||
hmac(pk_b, '/'.join(path[:i])) -> (rk, policy, algorithm, sign(hash + rk + policy + algorithm, pk_o))
|
||||
hmac(pk_o + pk_b, '/'.join(path[:i])) -> (rk, policy, algorithm, sign(hash + rk + policy + algorithm, pk_o))
|
||||
|
||||
The policy is signed by the owner's public key in order to protect from submitting by someone else.
|
||||
In order to protect from submitting after being revoked, the signature can be saved on blockchain
|
||||
|
@ -182,7 +182,7 @@ with miner's public key (on the client side)::
|
|||
# Path is transformed into a series of hashes
|
||||
path_split = path.split('/')
|
||||
path_pieces = ['/'.join(path_split[:i + 1]) for i in len(path_split)]
|
||||
path_hashes = [hmac(pk_b, piece) for piece in path_pieces]
|
||||
path_hashes = [hmac(pk_o + pk_b, piece) for piece in path_pieces]
|
||||
|
||||
# Multiple pieces are when m-of-n split-key reencryption is used
|
||||
# if not, there is only one piece
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import appdirs
|
||||
import lmdb
|
||||
import msgpack
|
||||
import os.path
|
||||
|
||||
CONFIG_APPNAME = 'nucypher-kms'
|
||||
DB_NAME = 'rekeys-db'
|
||||
|
||||
|
||||
class DB(object):
|
||||
def __init__(self, path=None):
|
||||
self.path = path or os.path.join(
|
||||
appdirs.user_data_dir(CONFIG_APPNAME), DB_NAME)
|
||||
db_dir = os.path.dirname(self.path)
|
||||
if not os.path.exists(db_dir):
|
||||
os.makedirs(db_dir)
|
||||
|
||||
self.db = lmdb.open(self.path)
|
||||
# XXX removal when expired? Indexing by time?
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
with self.db.begin(write=True) as tx:
|
||||
tx.put(key, msgpack.dumps(value))
|
||||
|
||||
def __getitem__(self, key):
|
||||
with self.db.begin(write=False) as tx:
|
||||
result = tx.get(key)
|
||||
if result is None:
|
||||
raise KeyError(key)
|
||||
else:
|
||||
return msgpack.loads(result)
|
||||
|
||||
def __delitem__(self, key):
|
||||
with self.db.begin(write=True) as tx:
|
||||
tx.pop(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
with self.db.begin(write=False) as tx:
|
||||
cursor = tx.cursor()
|
||||
return cursor.set_key(key)
|
||||
|
||||
def close(self):
|
||||
self.db.close()
|
|
@ -1,8 +1,6 @@
|
|||
from collections import defaultdict
|
||||
from nkms.db import DB
|
||||
from nkms import crypto
|
||||
|
||||
_storage = defaultdict(dict)
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""
|
||||
|
@ -22,7 +20,9 @@ class Client(object):
|
|||
"""
|
||||
|
||||
def __init__(self, **kw):
|
||||
pass
|
||||
# Dummy client stores in lmdb
|
||||
# in the actual network it should be done on the server
|
||||
self._storage = DB()
|
||||
|
||||
def store_rekeys(self, pub, k, rekeys, algorithm):
|
||||
"""
|
||||
|
@ -39,11 +39,11 @@ class Client(object):
|
|||
'm-of-n reencryption not yet available')
|
||||
rekeys = rekeys[0]
|
||||
# Should specify and check signature also
|
||||
_storage[pub][k] = {'rk': rekeys, 'algorithm': algorithm}
|
||||
self._storage[k] = {b'rk': rekeys, b'algorithm': algorithm}
|
||||
|
||||
def remove_rekeys(self, pub, k):
|
||||
# Should specify and check signature also
|
||||
del _storage[pub][k]
|
||||
del self._storage[k]
|
||||
|
||||
def reencrypt(self, pub, k, ekey):
|
||||
"""
|
||||
|
@ -51,8 +51,8 @@ class Client(object):
|
|||
:param bytes k: Address of the rekey derived from the path/pubkey
|
||||
:param bytes ekey: Encrypted symmetric key to reencrypt
|
||||
"""
|
||||
rekey = _storage[pub][k]['rk']
|
||||
algorithm = _storage[pub][k]['algorithm']
|
||||
rekey = self._storage[k][b'rk']
|
||||
algorithm = self._storage[k][b'algorithm']
|
||||
pre = crypto.pre_from_algorithm(algorithm)
|
||||
return pre.reencrypt(rekey, ekey)
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|||
INSTALL_REQUIRES = [
|
||||
'kademlia>=1.0',
|
||||
'rpcudp>=3.0',
|
||||
'ZODB>=5.0',
|
||||
'lmdb',
|
||||
'pynacl',
|
||||
'npre',
|
||||
'pysha3==1.0.2',
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import nkms.db
|
||||
import shutil
|
||||
import os
|
||||
import appdirs
|
||||
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
# Monkey-patching for tests so that we don't overwrite the default db
|
||||
nkms.db.DB_NAME = 'debug-rekeys-db'
|
||||
|
||||
|
||||
def pytest_runtest_teardown(item, nextitem):
|
||||
path = os.path.join(
|
||||
appdirs.user_data_dir(nkms.db.CONFIG_APPNAME), nkms.db.DB_NAME)
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
|
@ -0,0 +1,30 @@
|
|||
from nkms.db import DB
|
||||
import pytest
|
||||
|
||||
|
||||
def test_db():
|
||||
db = DB()
|
||||
db[b'x'] = b'y'
|
||||
assert db[b'x'] == b'y'
|
||||
db.close()
|
||||
|
||||
db2 = DB()
|
||||
assert b'x' in db2
|
||||
assert db2[b'x'] == b'y'
|
||||
del db2[b'x']
|
||||
db2.close()
|
||||
|
||||
db = DB()
|
||||
with pytest.raises(KeyError):
|
||||
db[b'x']
|
||||
assert b'x' not in db
|
||||
db.close()
|
||||
|
||||
assert db.path == db2.path
|
||||
|
||||
|
||||
def test_store_dict():
|
||||
db = DB()
|
||||
db[b'x'] = {b'a': 1, b'b': 2}
|
||||
assert db[b'x'][b'a'] == 1
|
||||
db.close()
|
Loading…
Reference in New Issue