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