clearer encryption

This commit is contained in:
AF 2022-05-26 13:42:20 +03:00
parent d5d4026630
commit 2870c78c93
2 changed files with 48 additions and 31 deletions

View File

@ -21,10 +21,12 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
self, self,
key: bytes, key: bytes,
resolution: tuple[HashPoint['Encrypted'], ...], resolution: tuple[HashPoint['Encrypted'], ...],
mapping: dict[bytes, HashPoint['Encrypted']],
decrypted: EncryptedType decrypted: EncryptedType
): ):
assert isinstance(key, bytes) assert isinstance(key, bytes)
assert isinstance(resolution, tuple) assert isinstance(resolution, tuple)
assert isinstance(mapping, dict)
assert isinstance(decrypted, HashMentionable) assert isinstance(decrypted, HashMentionable)
self.factory: RainbowFactory[EncryptedType] = decrypted.__factory__() self.factory: RainbowFactory[EncryptedType] = decrypted.__factory__()
@ -33,11 +35,7 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
self.resolution = resolution self.resolution = resolution
self.decrypted: EncryptedType = decrypted self.decrypted: EncryptedType = decrypted
self.hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () self.mapping = mapping
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]: def points(self) -> Iterable[HashPoint]:
return self.resolution return self.resolution
@ -49,22 +47,19 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
cls.ecc += 1 cls.ecc += 1
assert isinstance(key, bytes) assert isinstance(key, bytes)
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
encrypted: Encrypted[EncryptedType] = object.__new__(cls) resolution = tuple(
encrypted.__init__( cls.encrypt_hashpoint(hashpoint, key)
key, for
tuple( hashpoint
cls.encrypt_hashpoint(hashpoint, key) in
for hashpoints
hashpoint )
in return cls.construct(
hashpoints key,
), resolution,
decrypted.__factory__().from_bytes( hashpoints,
bytes(decrypted), decrypted
EncryptedResolver(encrypted)
)
) )
return encrypted
@classmethod @classmethod
def encrypt_hashpoint( def encrypt_hashpoint(
@ -75,14 +70,35 @@ class Encrypted(RecursiveMentionable, Generic[EncryptedType]):
if isinstance(hashpoint.origin, ResolverOrigin): if isinstance(hashpoint.origin, ResolverOrigin):
resolver: HashResolver = hashpoint.origin.resolver resolver: HashResolver = hashpoint.origin.resolver
assert isinstance(resolver, HashResolver) assert isinstance(resolver, HashResolver)
if isinstance(resolver, EncryptedResolver) and resolver.encrypted.key == key: if isinstance(resolver, EncryptedResolver) and resolver.key == key:
return ShortcutOrigin( return ShortcutOrigin(
hashpoint.factory, hashpoint.factory,
resolver.encrypted.mapping[hashpoint.point], resolver.mapping[hashpoint.point],
key key
).hash_point() ).hash_point()
return HashPoint.of(cls.encrypt(hashpoint.resolve(), key)) return HashPoint.of(cls.encrypt(hashpoint.resolve(), key))
@classmethod
def construct(
cls,
key: bytes,
resolution: tuple[HashPoint['Encrypted'], ...],
hashpoints: tuple[HashPoint, ...],
decrypted: EncryptedType
) -> 'Encrypted[EncryptedType]':
mapping: dict[bytes, HashPoint[Encrypted]] = {
hashpoint.point: encrypted for hashpoint, encrypted in zip(hashpoints, resolution)
}
return Encrypted(
key,
resolution,
mapping,
decrypted.__factory__().from_bytes(
bytes(decrypted),
EncryptedResolver(mapping, key)
)
)
def __bytes__(self): def __bytes__(self):
source: bytes = len(self.resolution).to_bytes(8, 'little') + b''.join( source: bytes = len(self.resolution).to_bytes(8, 'little') + b''.join(
encrypted.point encrypted.point
@ -109,10 +125,9 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt
assert isinstance(resolver, HashResolver) assert isinstance(resolver, HashResolver)
plain: bytes = SecretBox(self.key).decrypt(source) plain: bytes = SecretBox(self.key).decrypt(source)
resolution_size: int = int.from_bytes(plain[:8], 'little') resolution_size: int = int.from_bytes(plain[:8], 'little')
encrypted: Encrypted[EncryptedType] = object.__new__(Encrypted)
decrypted: EncryptedType = self.factory.from_bytes( decrypted: EncryptedType = self.factory.from_bytes(
plain[8 + resolution_size * HashPoint.HASH_LENGTH:], plain[8 + resolution_size * HashPoint.HASH_LENGTH:],
EncryptedResolver(encrypted) resolver,
) )
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
assert len(hashpoints) == resolution_size assert len(hashpoints) == resolution_size
@ -126,26 +141,28 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt
resolver resolver
).hash_point() for i, hashpoint in enumerate(hashpoints) ).hash_point() for i, hashpoint in enumerate(hashpoints)
) )
encrypted.__init__( return Encrypted.construct(
self.key, self.key,
resolution, resolution,
hashpoints,
decrypted decrypted
) )
return encrypted
def loose(self) -> RainbowFactory[Encrypted[EncryptedType]]: def loose(self) -> RainbowFactory[Encrypted[EncryptedType]]:
return self return self
class EncryptedResolver(HashResolver): class EncryptedResolver(HashResolver):
def __init__(self, encrypted: Encrypted): def __init__(self, mapping: dict[bytes, HashPoint[Encrypted]], key: bytes):
assert isinstance(encrypted, Encrypted) assert isinstance(mapping, dict)
self.encrypted = encrypted assert isinstance(key, bytes)
self.mapping = mapping
self.key = key
def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']: def resolve(self, point: bytes) -> tuple[bytes, 'HashResolver']:
assert isinstance(point, bytes) assert isinstance(point, bytes)
encrypted = self.encrypted.mapping[point].resolve() encrypted = self.mapping[point].resolve()
return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted) return HashPoint.bytes_of_mentioned(encrypted.decrypted), EncryptedResolver(encrypted.mapping, self.key)
class ShortcutOrigin(Origin[Encrypted[EncryptedType]], Generic[EncryptedType]): class ShortcutOrigin(Origin[Encrypted[EncryptedType]], Generic[EncryptedType]):