switched to read/write-keypair and incremental key-scheduling to enable encryption-based sharing / permissions in the future

This commit is contained in:
Dominik Moritz Roth 2020-06-19 18:11:10 +02:00
parent 5306d82371
commit f5ec35fb29

54
next.py
View File

@ -9,14 +9,10 @@
# TODO: inode_id -> actuall Inode lookup table # TODO: inode_id -> actuall Inode lookup table
# TODO: Add chareable folders: # TODO: Add chareable folders:
# TODO: No more 'tokens' -> write-key for address-gen and read-key for encryption # TODO: No more 'tokens' -> write-key for address-gen and read-key for encryption
# TODO: Chunksize-=1 -> flag # TODO: Change iota receive adress to next adress (encrypted with read-key)
# TODO: Allow next-public-adress-pointer to be added to blog (reducing avaible Chunksize)
# TODO: Add share-functionality: # TODO: Add share-functionality:
# 1. switch directory to a shared-type (store this in parent-dir) # 1. publish read-key of the directory
# 2. append next-public-adress-pointer to every future block # 2. publish public adress of current milestone-block
# 3. make a new milestone; forcing a new block
# 4. publish read-key of the directory
# 5. publish public adress of new milestone
# Problem: No updateable milestone-index... -> Create share-genesis? # Problem: No updateable milestone-index... -> Create share-genesis?
from iota import Iota, ProposedTransaction, Address, TryteString, Tag from iota import Iota, ProposedTransaction, Address, TryteString, Tag
@ -107,13 +103,14 @@ class BlobChunk():
return self.sealed return self.sealed
class TangleBlob(): class TangleBlob():
def __init__(self, token: bytes, iotaApi: Iota) -> None: def __init__(self, writeKey: bytes, readKey: bytes, iotaApi: Iota) -> None:
self.token = token self.writeKey = writeKey
self.readKey = readKey
self.iotaApi = iotaApi self.iotaApi = iotaApi
self.preChunks = 0 self.preChunks = 0
self.chunks = [] self.chunks = []
m = hashlib.sha3_512() m = hashlib.sha3_512()
m.update(self.token) m.update(self.writeKey)
trSeed = TryteString.from_bytes(m.digest())[:81] trSeed = TryteString.from_bytes(m.digest())[:81]
self.adressGen = AddressGenerator(Seed(trSeed)) self.adressGen = AddressGenerator(Seed(trSeed))
self.fetched = False self.fetched = False
@ -123,11 +120,11 @@ class TangleBlob():
if not self.fetched: if not self.fetched:
self.fetch() self.fetch()
def _getKey(self, chunkNum: int) -> bytes: def _getReadKey(self, chunkNum: int) -> bytes:
m = hashlib.sha3_384() m = hashlib.sha3_384()
m.update(self.token) m.update(self.readKey)
m.update(chunkNum.to_bytes(8, "little")) # 64 bits should be enought... m.update(chunkNum.to_bytes(8, "little")) # 64 bits should be enought...
m.update(self.token) m.update(self.readKey)
return m.digest() return m.digest()
def _genBundle(self, data, addr) -> str: def _genBundle(self, data, addr) -> str:
@ -144,9 +141,9 @@ class TangleBlob():
)['trytes'] )['trytes']
def _dumpChunk(self, chunkNum: int) -> str: def _dumpChunk(self, chunkNum: int) -> str:
key = self._getKey(chunkNum + self.preChunks) readKey = self._getReadKey(chunkNum + self.preChunks)
data = self.chunks[chunkNum].getData() data = self.chunks[chunkNum].getData()
cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16]) cipher = AES.new(readKey[16:][:16], AES.MODE_CBC, readKey[:16])
ct_bytes = cipher.encrypt(pad(data, AES.block_size)) ct_bytes = cipher.encrypt(pad(data, AES.block_size))
addr = self.adressGen.get_addresses(start=chunkNum + self.preChunks, count=1)[0] addr = self.adressGen.get_addresses(start=chunkNum + self.preChunks, count=1)[0]
return self._genBundle(ct_bytes, addr) return self._genBundle(ct_bytes, addr)
@ -214,8 +211,8 @@ class TangleBlob():
skipChunks = self.preChunks skipChunks = self.preChunks
chunkNum = self.getChunkLen() + skipChunks chunkNum = self.getChunkLen() + skipChunks
while True: while True:
key = self._getKey(chunkNum) readKey = self._getReadKey(chunkNum)
cipher = AES.new(key[16:][:16], AES.MODE_CBC, key[:16]) cipher = AES.new(readKey[16:][:16], AES.MODE_CBC, readKey[:16])
addr = self.adressGen.get_addresses(start=chunkNum, count=1)[0] addr = self.adressGen.get_addresses(start=chunkNum, count=1)[0]
txHash = self.iotaApi.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"] txHash = self.iotaApi.find_transactions(tags=[Tag("IOTAFS")], addresses=[addr])["hashes"]
if len(txHash)==0: if len(txHash)==0:
@ -238,9 +235,6 @@ class TangleBlob():
def _afterFetch(self) -> None: def _afterFetch(self) -> None:
return return
def genToken(self) -> bytes:
return secrets.token_bytes(32)
def sealLastChunk(self) -> None: def sealLastChunk(self) -> None:
self.chunks[-1].seal() self.chunks[-1].seal()
@ -266,10 +260,12 @@ class TangleBlob():
class TangleFileTreeElement(TangleBlob): class TangleFileTreeElement(TangleBlob):
def __init__(self, name: str, lastMilestoneIndex: int, parent, iotaApi: Iota) -> None: def __init__(self, name: str, lastMilestoneIndex: int, parent, iotaApi: Iota) -> None:
if isinstance(parent, bytes): if isinstance(parent, bytes):
self.token = hashlib.sha3_384(parent + name.encode()).digest() self.writeKey = hashlib.sha3_384(parent + name.encode() + b'write' + parent).digest()
self.readKey = hashlib.sha3_384(parent + name.encode() + b'read' + parent).digest()
else: else:
self.token = hashlib.sha3_384(parent.token + name.encode()).digest() self.writeKey = hashlib.sha3_384(parent.writeKey + name.encode()).digest()
super(TangleFileTreeElement, self).__init__(self.token, iotaApi) self.readKey = hashlib.sha3_384(parent.readKey + name.encode()).digest()
super(TangleFileTreeElement, self).__init__(self.writeKey, self.readKey, iotaApi)
self.name = name self.name = name
self.inodes = {} self.inodes = {}
self.parent = parent self.parent = parent
@ -389,7 +385,7 @@ class TangleFileTreeElement(TangleBlob):
self._newAtom(atom) self._newAtom(atom)
def _updateFileHash(self, name: str, hash: bytes, size: int) -> None: def _updateFileHash(self, name: str, hash: bytes, size: int) -> None:
log("New FileToken for file '"+name+"' registered") log("New Hash for file '"+name+"' registered")
self._requireFetched() self._requireFetched()
atom = self.inodes[name].change(size=size, hash=hash) atom = self.inodes[name].change(size=size, hash=hash)
self._newAtom(atom) self._newAtom(atom)
@ -427,13 +423,14 @@ class TangleFileTreeElement(TangleBlob):
class TangleFile(): class TangleFile():
def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None: def __init__(self, name: str, parent: TangleFileTreeElement, iotaApi: Iota) -> None:
self.api = iotaApi self.iotaApi = iotaApi
self.name = name self.name = name
self.parent = parent self.parent = parent
self.reflexiveInode = parent.inodes[name] self.reflexiveInode = parent.inodes[name]
self.size = self.reflexiveInode.size self.size = self.reflexiveInode.size
self.hash = self.reflexiveInode.hash self.hash = self.reflexiveInode.hash
self.token = hashlib.sha3_384(b'f' + parent.token + self.hash).digest() self.writeKey = hashlib.sha3_384(b'f' + parent.writeKey + self.hash).digest()
self.readKey = hashlib.sha3_384(b'f' + parent.readKey + self.hash).digest()
self.blob = TangleBlob(self.token, iotaApi) self.blob = TangleBlob(self.token, iotaApi)
def write(self, offset: int, data: bytes): def write(self, offset: int, data: bytes):
@ -445,8 +442,9 @@ class TangleFile():
oldData = self.blob.read() oldData = self.blob.read()
newData = oldData[:offset] + data + oldData[offset+len(data):] newData = oldData[:offset] + data + oldData[offset+len(data):]
self.hash = hashlib.sha256(newData).digest() self.hash = hashlib.sha256(newData).digest()
self.token = hashlib.sha3_384(b'f' + self.parent.token + self.hash).digest() self.writeKey = hashlib.sha3_384(b'f' + self.parent.writeKey + self.hash).digest()
self.blob = TangleBlob(self.token) self.readKey = hashlib.sha3_384(b'f' + self.parent.readKey + self.hash).digest()
self.blob = TangleBlob(self.writeKey, self.readKey, self.iotaApi)
self.blob.append(newData) self.blob.append(newData)
self.size = self.blob.getSize() self.size = self.blob.getSize()
self.parent._updateFileHash(self.name, self.hash, self.size) self.parent._updateFileHash(self.name, self.hash, self.size)