Source code for shuffled.crypto

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import math

from . import compat, feistel


[docs]class AesRandomizer: domain_size = 2 ** 128 def __init__(self, key): self._cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
[docs] def randomize(self, integer): encoded = compat.int128_to_bytes(integer) encryptor = self._cipher.encryptor() encrypted = encryptor.update(encoded) + encryptor.finalize() return compat.int128_from_bytes(encrypted)
[docs]class IndexEncryptor: """ Encrypt indexes using pseudo-random function. :param randomizers: List of instances with an appropriate pseudo-random ``randomize`` method and ``domain_size`` integer attribute, such as :py:class:`AesRandomizer` objects. :param size: Size of the domain :type size: int """ def __init__(self, randomizers, size): if any(size > randomizer.domain_size for randomizer in randomizers): raise ValueError('Size too big for at least one of the randomizers') self.round_functions = [randomizer.randomize for randomizer in randomizers] self.size = size self._a = self._b = int(math.ceil(math.sqrt(size)))
[docs] def encrypt(self, index): """ Permutation of ``range(self.size)`` :param index: Integer in ``range(self.size)`` :type index: int """ if index < 0 or index >= self.size: raise ValueError('Index out of range') return feistel.encrypt(self.round_functions, self._a, self._b, index, self.size)