encryption protocol

This commit is contained in:
AF 2022-05-20 03:42:19 +03:00
parent 899415f580
commit 56f876f905
6 changed files with 224 additions and 8 deletions

35
main.py
View File

@ -1,4 +1,5 @@
import os import os
import string
import time import time
from collections import OrderedDict from collections import OrderedDict
from typing import Any, MutableMapping from typing import Any, MutableMapping
@ -14,6 +15,7 @@ from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinar
from rainbowadn.data.collection.trees.binary.avl import AVLBTBP from rainbowadn.data.collection.trees.binary.avl import AVLBTBP
from rainbowadn.data.collection.trees.comparison.comparator import Replace from rainbowadn.data.collection.trees.comparison.comparator import Replace
from rainbowadn.data.collection.trees.comparison.plaincomparator import PlainComparator from rainbowadn.data.collection.trees.comparison.plaincomparator import PlainComparator
from rainbowadn.encryption.encrypted import Encrypted
from rainbowadn.hashing.hashmentionable import HashMentionable from rainbowadn.hashing.hashmentionable import HashMentionable
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver from rainbowadn.hashing.hashresolver import HashResolver
@ -33,9 +35,9 @@ class DumbResolver(HashResolver):
def __init__(self): def __init__(self):
self.table: MutableMapping[bytes, bytes] = OrderedDict() self.table: MutableMapping[bytes, bytes] = OrderedDict()
def resolve_bytes(self, point: bytes) -> bytes: def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
assert isinstance(point, bytes) assert isinstance(point, bytes)
return self.table[point] return self.table[point], self
def save(self, hash_point: HashPoint) -> None: def save(self, hash_point: HashPoint) -> None:
assert isinstance(hash_point, HashPoint) assert isinstance(hash_point, HashPoint)
@ -132,7 +134,7 @@ def main2():
print(chain.actual_state().reference.value.resolve().height) print(chain.actual_state().reference.value.resolve().height)
def main(): def main3():
tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty( tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
AVLBTBP(PlainComparator(Replace())), Plain.factory() AVLBTBP(PlainComparator(Replace())), Plain.factory()
) )
@ -141,5 +143,30 @@ def main():
print(tree.reference.str(0)) print(tree.reference.str(0))
def main():
key = b'a' * 32
dr = DumbResolver()
tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
AVLBTBP(PlainComparator(Replace())), Plain.factory()
)
for char in string.ascii_uppercase:
tree = tree.add(HashPoint.of(Plain(char.encode())))
print(tree.reference.str(0))
target = tree.reference
target = Encrypted.encrypt(target, key).decrypted
print(Encrypted.ecc)
tree = tree.create(target)
print(tree.reference.str(0))
tree = tree.add(HashPoint.of(Plain(b'NEWKEY')))
print(tree.reference.str(0))
target = tree.reference
eeed = Encrypted.encrypt(target, key)
print(Encrypted.ecc)
dr.save(HashPoint.of(eeed))
# for key, value in dr.table.items():
# print(key.hex(), value.hex())
print(ResolverMetaOrigin(dr).migrate(HashPoint.of(eeed)).resolve().decrypted.str(0))
if __name__ == '__main__': if __name__ == '__main__':
main0() main()

View File

@ -0,0 +1,185 @@
from typing import Generic, Iterable, TypeVar
from nacl.bindings import crypto_hash_sha256
from nacl.secret import SecretBox
from rainbowadn.hashing.hashmentionable import HashMentionable
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.origin import Origin
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
from rainbowadn.hashing.resolverorigin import ResolverOrigin
__all__ = ('Encrypted', 'EncryptedFactory')
EncryptedType = TypeVar('EncryptedType')
class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
def __init__(
self,
key: bytes,
resolution: tuple[HashPoint['Encrypted'], ...],
decrypted: EncryptedType
):
assert isinstance(key, bytes)
assert isinstance(resolution, tuple)
assert isinstance(decrypted, HashMentionable)
self.factory: RainbowFactory[EncryptedType] = decrypted.__factory__()
self.key = key
self.resolution = resolution
self.decrypted: EncryptedType = decrypted
self.hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
assert len(self.hashpoints) == len(self.resolution)
self.mapping: dict[bytes, HashPoint[Encrypted]] = {
hashpoint.point: encrypted for hashpoint, encrypted in zip(self.hashpoints, resolution)
}
def points(self) -> Iterable[HashPoint]:
return self.resolution
ecc = 0
@classmethod
def encrypt(cls, decrypted: EncryptedType, key: bytes) -> 'Encrypted[EncryptedType]':
cls.ecc += 1
assert isinstance(key, bytes)
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
encrypted: Encrypted[EncryptedType] = object.__new__(cls)
encrypted.__init__(
key,
tuple(
cls.encrypt_hashpoint(hashpoint, key)
for
hashpoint
in
hashpoints
),
decrypted.__factory__().from_bytes(
bytes(decrypted),
EncryptedResolver(encrypted)
)
)
return encrypted
@classmethod
def encrypt_hashpoint(
cls, hashpoint: HashPoint[EncryptedType], key: bytes
) -> HashPoint['Encrypted[EncryptedType]']:
assert isinstance(hashpoint, HashPoint)
assert isinstance(key, bytes)
if isinstance(hashpoint.origin, ResolverOrigin):
resolver: HashResolver = hashpoint.origin.resolver
assert isinstance(resolver, HashResolver)
if isinstance(resolver, EncryptedResolver):
return ShortcutOrigin(
hashpoint.factory,
resolver.encrypted.mapping[hashpoint.point],
key
).hash_point()
return HashPoint.of(cls.encrypt(hashpoint.resolve(), key))
def __bytes__(self):
source: bytes = len(self.resolution).to_bytes(8, 'little') + b''.join(
encrypted.point
for
encrypted
in self.resolution
) + bytes(self.decrypted)
nonce: bytes = crypto_hash_sha256(self.key + source)[:24]
return SecretBox(self.key).encrypt(source, nonce=nonce)
def __factory__(self) -> RainbowFactory['Encrypted[EncryptedType]']:
return EncryptedFactory(self.factory, self.key)
class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[EncryptedType]):
def __init__(self, factory: RainbowFactory[EncryptedType], key: bytes):
assert isinstance(factory, RainbowFactory)
assert isinstance(key, bytes)
self.factory = factory
self.key = key
def from_bytes(self, source: bytes, resolver: HashResolver) -> Encrypted[EncryptedType]:
assert isinstance(source, bytes)
assert isinstance(resolver, HashResolver)
plain: bytes = SecretBox(self.key).decrypt(source)
resolution_size: int = int.from_bytes(plain[:8], 'little')
encrypted: Encrypted[EncryptedType] = object.__new__(Encrypted)
decrypted: EncryptedType = self.factory.from_bytes(
plain[8 + resolution_size * HashPoint.HASH_LENGTH:],
EncryptedResolver(encrypted)
)
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
assert len(hashpoints) == resolution_size
encrypted.__init__(
self.key,
tuple(
ResolverOrigin(
EncryptedFactory(
hashpoint.factory,
self.key
),
plain[8 + i * HashPoint.HASH_LENGTH: 8 + (i + 1) * HashPoint.HASH_LENGTH],
resolver
).hash_point() for i, hashpoint in enumerate(hashpoints)
),
decrypted
)
return encrypted
def loose(self) -> RainbowFactory[Encrypted[EncryptedType]]:
return self
class EncryptedResolver(HashResolver):
def __init__(self, encrypted: Encrypted):
assert isinstance(encrypted, Encrypted)
self.encrypted = encrypted
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
assert isinstance(point, bytes)
encrypted = self.encrypted.mapping[point].resolve()
return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted)
class ShortcutOrigin(Origin[Encrypted[EncryptedType]], Generic[EncryptedType]):
def __init__(self, factory: RainbowFactory[EncryptedType], hashpoint: HashPoint[Encrypted], key: bytes):
assert isinstance(factory, RainbowFactory)
assert isinstance(hashpoint, HashPoint)
assert isinstance(key, bytes)
self.factory: RainbowFactory[Encrypted[EncryptedType]] = EncryptedFactory(factory, key)
assert isinstance(self.factory, RainbowFactory)
self.hashpoint = hashpoint
def resolve(self) -> Encrypted[EncryptedType]:
encrypted = self.hashpoint.resolve()
encrypted = self.factory.from_bytes(bytes(encrypted), ShortcutResolver(encrypted))
assert HashPoint.of(encrypted) == self.hashpoint
return encrypted
def hash_point(self) -> HashPoint[Encrypted[EncryptedType]]:
return HashPoint(
self.factory,
self.hashpoint.point,
self
)
class ShortcutResolver(HashResolver):
def __init__(self, encrypted: Encrypted):
assert isinstance(encrypted, Encrypted)
self.mapping: dict[bytes, HashPoint[Encrypted]] = {
hashpoint.point: hashpoint for hashpoint in encrypted.resolution
}
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
assert isinstance(point, bytes)
return (
HashPoint.bytes_of_mentioned(self.mapping[point].resolve()),
ShortcutResolver(self.mapping[point].resolve())
)

View File

@ -9,6 +9,7 @@ from rainbowadn.hashing.rainbow_factory import RainbowFactory
__all__ = ('HashPoint',) __all__ = ('HashPoint',)
HashMentioned = TypeVar('HashMentioned') HashMentioned = TypeVar('HashMentioned')
ReHashMentioned = TypeVar('ReHashMentioned')
def _hash(source: bytes) -> bytes: def _hash(source: bytes) -> bytes:
@ -60,6 +61,7 @@ class HashPoint(Generic[HashMentioned]):
def resolve(self) -> HashMentioned: def resolve(self) -> HashMentioned:
resolved = self.origin.resolve() resolved = self.origin.resolve()
assert isinstance(resolved, HashMentionable) assert isinstance(resolved, HashMentionable)
assert self.point == self.hash(self.bytes_of_mentioned(resolved))
return resolved return resolved
def __eq__(self, other): def __eq__(self, other):

View File

@ -6,5 +6,5 @@ RHashMentioned = TypeVar('RHashMentioned')
class HashResolver: class HashResolver:
def resolve_bytes(self, point: bytes) -> bytes: def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
raise NotImplementedError raise NotImplementedError

View File

@ -26,11 +26,13 @@ class ResolverOrigin(Origin[OriginType], Generic[OriginType]):
self.resolver = resolver self.resolver = resolver
def resolve(self) -> OriginType: def resolve(self) -> OriginType:
resolved: bytes = self.resolver.resolve_bytes(self.point) resolved, resolver = self.resolver.resolve(self.point)
assert isinstance(resolved, bytes) assert isinstance(resolved, bytes)
mentioned: OriginType = self.factory.from_bytes(resolved[HashPoint.HASH_LENGTH:], self.resolver) assert isinstance(resolver, HashResolver)
mentioned: OriginType = self.factory.from_bytes(resolved[HashPoint.HASH_LENGTH:], resolver)
assert isinstance(mentioned, HashMentionable) assert isinstance(mentioned, HashMentionable)
assert mentioned.__topology_hash__() == resolved[:HashPoint.HASH_LENGTH] assert mentioned.__topology_hash__() == resolved[:HashPoint.HASH_LENGTH]
assert self.point == HashPoint.hash(HashPoint.bytes_of_mentioned(mentioned))
return mentioned return mentioned
def hash_point(self) -> HashPoint[OriginType]: def hash_point(self) -> HashPoint[OriginType]:

View File

@ -2,5 +2,5 @@ from rainbowadn.hashing.hashresolver import HashResolver
class FailResolver(HashResolver): class FailResolver(HashResolver):
def resolve_bytes(self, point: bytes) -> bytes: def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
raise TypeError('fail-resolver always fails') raise TypeError('fail-resolver always fails')