Python Crypto.Random.get_random_bytes() Examples

The following are 30 code examples of Crypto.Random.get_random_bytes(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module Crypto.Random , or try the search function .
Example #1
Source File: file.py    From keyrings.alt with MIT License 8 votes vote down vote up
def encrypt(self, password, assoc=None):
        # encrypt password, ignore associated data
        from Crypto.Random import get_random_bytes

        salt = get_random_bytes(self.block_size)
        from Crypto.Cipher import AES

        IV = get_random_bytes(AES.block_size)
        cipher = self._create_cipher(self.keyring_key, salt, IV)
        password_encrypted = cipher.encrypt(self.pw_prefix + password)
        # Serialize the salt, IV, and encrypted password in a secure format
        data = dict(salt=salt, IV=IV, password_encrypted=password_encrypted)
        for key in data:
            # spare a few bytes: throw away newline from base64 encoding
            data[key] = encodebytes(data[key]).decode()[:-1]
        return json.dumps(data).encode() 
Example #2
Source File: number.py    From android_universal with MIT License 6 votes vote down vote up
def getRandomRange(a, b, randfunc=None):
    """Return a random number *n* so that *a <= n < b*.

    If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used.

    .. deprecated:: 3.0
        This function is for internal use only and may be renamed or removed in
        the future. Use :func:`Crypto.Random.random.randrange` instead.
    """

    range_ = b - a - 1
    bits = size(range_)
    value = getRandomInteger(bits, randfunc)
    while value > range_:
        value = getRandomInteger(bits, randfunc)
    return a + value 
Example #3
Source File: ECC.py    From FODI with GNU General Public License v3.0 6 votes vote down vote up
def generate(**kwargs):
    """Generate a new private key on the given curve.

    Args:

      curve (string):
        Mandatory. It must be a curve name defined in :numref:`curve_names`.

      randfunc (callable):
        Optional. The RNG to read randomness from.
        If ``None``, :func:`Crypto.Random.get_random_bytes` is used.
    """

    curve_name = kwargs.pop("curve")
    curve = _curves[curve_name]
    randfunc = kwargs.pop("randfunc", get_random_bytes)
    if kwargs:
        raise TypeError("Unknown parameters: " + str(kwargs))

    d = Integer.random_range(min_inclusive=1,
                             max_exclusive=curve.order,
                             randfunc=randfunc)

    return EccKey(curve=curve_name, d=d) 
Example #4
Source File: number.py    From FODI with GNU General Public License v3.0 6 votes vote down vote up
def getRandomInteger(N, randfunc=None):
    """Return a random number at most N bits long.

    If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used.

    .. deprecated:: 3.0
        This function is for internal use only and may be renamed or removed in
        the future. Use :func:`Crypto.Random.random.getrandbits` instead.
    """

    if randfunc is None:
        randfunc = Random.get_random_bytes

    S = randfunc(N>>3)
    odd_bits = N % 8
    if odd_bits != 0:
        rand_bits = ord(randfunc(1)) >> (8-odd_bits)
        S = struct.pack('B', rand_bits) + S
    value = bytes_to_long(S)
    return value 
Example #5
Source File: number.py    From FODI with GNU General Public License v3.0 6 votes vote down vote up
def getRandomRange(a, b, randfunc=None):
    """Return a random number *n* so that *a <= n < b*.

    If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used.

    .. deprecated:: 3.0
        This function is for internal use only and may be renamed or removed in
        the future. Use :func:`Crypto.Random.random.randrange` instead.
    """

    range_ = b - a - 1
    bits = size(range_)
    value = getRandomInteger(bits, randfunc)
    while value > range_:
        value = getRandomInteger(bits, randfunc)
    return a + value 
Example #6
Source File: AES.py    From FODI with GNU General Public License v3.0 6 votes vote down vote up
def _derive_Poly1305_key_pair(key, nonce):
    """Derive a tuple (r, s, nonce) for a Poly1305 MAC.
    
    If nonce is ``None``, a new 16-byte nonce is generated.
    """

    if len(key) != 32:
        raise ValueError("Poly1305 with AES requires a 32-byte key")

    if nonce is None:
        nonce = get_random_bytes(16)
    elif len(nonce) != 16:
        raise ValueError("Poly1305 with AES requires a 16-byte nonce")

    s = new(key[:16], MODE_ECB).encrypt(nonce)
    return key[16:], s, nonce 
Example #7
Source File: Salsa20.py    From FODI with GNU General Public License v3.0 6 votes vote down vote up
def new(key, nonce=None):
    """Create a new Salsa20 cipher

    :keyword key: The secret key to use. It must be 16 or 32 bytes long.
    :type key: bytes/bytearray/memoryview

    :keyword nonce:
        A value that must never be reused for any other encryption
        done with this key. It must be 8 bytes long.

        If not provided, a random byte string will be generated (you can read
        it back via the ``nonce`` attribute of the returned object).
    :type nonce: bytes/bytearray/memoryview

    :Return: a :class:`Crypto.Cipher.Salsa20.Salsa20Cipher` object
    """

    if nonce is None:
        nonce = get_random_bytes(8)

    return Salsa20Cipher(key, nonce)

# Size of a data block (in bytes) 
Example #8
Source File: Wallet.py    From neo-python with MIT License 6 votes vote down vote up
def CreateKey(self, private_key=None):
        """
        Create a KeyPair

        Args:
            private_key (iterable_of_ints): (optional) 32 byte private key

        Returns:
            KeyPair: a KeyPair instance
        """
        if private_key is None:
            private_key = bytes(Random.get_random_bytes(32))

        key = KeyPair(priv_key=private_key)
        self._keys[key.PublicKeyHash.ToBytes()] = key
        return key 
Example #9
Source File: tls.py    From python-validity with MIT License 6 votes vote down vote up
def make_client_hello(self):
        h = unhexlify('0303') # TLS 1.2
        #self.client_random = unhexlify('bc349559ac16c8f8362191395b4d04a435d870315f519eed8777488bc2b9600c')
        self.client_random = get_random_bytes(0x20)
        h += self.client_random # client's random
        h += with_1byte_size(unhexlify('00000000000000')) # session ID

        suits = b''
        suits += pack('>H', 0xc005) # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
        suits += pack('>H', 0x003d) # TLS_RSA_WITH_AES_256_CBC_SHA256
        suits += pack('>H', 0x008d) # TLS_RSA_WITH_AES_256_CBC_SHA256
        h += with_2bytes_size(suits)

        h += with_1byte_size(b'') # no compression options

        exts = b''
        exts += self.make_ext(0x004, pack('>H', 0x0017)) # truncated_hmac = 0x17
        exts += self.make_ext(0x00b, with_1byte_size(unhexlify('00'))) # EC points format = uncompressed
        # h += with_2bytes_size(exts)
        h += pack('>H', len(exts)-2) + exts # -2? WHY?!...

        return self.with_neg_hdr(0x01, h) 
Example #10
Source File: BLAKE2b.py    From android_universal with MIT License 6 votes vote down vote up
def verify(self, mac_tag):
        """Verify that a given **binary** MAC (computed by another party)
        is valid.

        Args:
          mac_tag (bytes/bytearray/memoryview): the expected MAC of the message.

        Raises:
            ValueError: if the MAC does not match. It means that the message
                has been tampered with or that the MAC key is incorrect.
        """

        secret = get_random_bytes(16)

        mac1 = new(digest_bits=160, key=secret, data=mac_tag)
        mac2 = new(digest_bits=160, key=secret, data=self.digest())

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #11
Source File: HMAC.py    From android_universal with MIT License 6 votes vote down vote up
def verify(self, mac_tag):
        """Verify that a given **binary** MAC (computed by another party)
        is valid.

        Args:
          mac_tag (byte string/byte string/memoryview): the expected MAC of the message.

        Raises:
            ValueError: if the MAC does not match. It means that the message
                has been tampered with or that the MAC key is incorrect.
        """

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=self.digest())

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #12
Source File: BLAKE2s.py    From android_universal with MIT License 6 votes vote down vote up
def verify(self, mac_tag):
        """Verify that a given **binary** MAC (computed by another party)
        is valid.

        Args:
          mac_tag (byte string/byte array/memoryview): the expected MAC of the message.

        Raises:
            ValueError: if the MAC does not match. It means that the message
                has been tampered with or that the MAC key is incorrect.
        """

        secret = get_random_bytes(16)

        mac1 = new(digest_bits=160, key=secret, data=mac_tag)
        mac2 = new(digest_bits=160, key=secret, data=self.digest())

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #13
Source File: CMAC.py    From android_universal with MIT License 6 votes vote down vote up
def verify(self, mac_tag):
        """Verify that a given **binary** MAC (computed by another party)
        is valid.

        Args:
          mac_tag (byte string/byte array/memoryview): the expected MAC of the message.

        Raises:
            ValueError: if the MAC does not match. It means that the message
                has been tampered with or that the MAC key is incorrect.
        """

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=self.digest())

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #14
Source File: number.py    From android_universal with MIT License 6 votes vote down vote up
def getRandomInteger(N, randfunc=None):
    """Return a random number at most N bits long.

    If :data:`randfunc` is omitted, then :meth:`Random.get_random_bytes` is used.

    .. deprecated:: 3.0
        This function is for internal use only and may be renamed or removed in
        the future. Use :func:`Crypto.Random.random.getrandbits` instead.
    """

    if randfunc is None:
        randfunc = Random.get_random_bytes

    S = randfunc(N>>3)
    odd_bits = N % 8
    if odd_bits != 0:
        rand_bits = ord(randfunc(1)) >> (8-odd_bits)
        S = struct.pack('B', rand_bits) + S
    value = bytes_to_long(S)
    return value 
Example #15
Source File: _mode_eax.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def _create_eax_cipher(factory, **kwargs):
    """Create a new block cipher, configured in EAX mode.

    :Parameters:
      factory : module
        A symmetric cipher module from `Crypto.Cipher` (like
        `Crypto.Cipher.AES`).

    :Keywords:
      key : bytes/bytearray/memoryview
        The secret key to use in the symmetric cipher.

      nonce : bytes/bytearray/memoryview
        A value that must never be reused for any other encryption.
        There are no restrictions on its length, but it is recommended to use
        at least 16 bytes.

        The nonce shall never repeat for two different messages encrypted with
        the same key, but it does not need to be random.

        If not specified, a 16 byte long random string is used.

      mac_len : integer
        Length of the MAC, in bytes. It must be no larger than the cipher
        block bytes (which is the default).
    """

    try:
        key = kwargs.pop("key")
        nonce = kwargs.pop("nonce", None)
        if nonce is None:
            nonce = get_random_bytes(16)
        mac_len = kwargs.pop("mac_len", factory.block_size)
    except KeyError as e:
        raise TypeError("Missing parameter: " + str(e))

    return EaxMode(factory, key, nonce, mac_len, kwargs) 
Example #16
Source File: database.py    From Notebook with MIT License 5 votes vote down vote up
def generate_user_key(self, username, password):
        return sha256((username + password).encode() + get_random_bytes(64 * 4)).digest() 
Example #17
Source File: ChaCha20.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def _derive_Poly1305_key_pair(key, nonce):
    """Derive a tuple (r, s, nonce) for a Poly1305 MAC.

    If nonce is ``None``, a new 12-byte nonce is generated.
    """

    if len(key) != 32:
        raise ValueError("Poly1305 with ChaCha20 requires a 32-byte key")

    if nonce is None:
        padded_nonce = nonce = get_random_bytes(12)
    elif len(nonce) == 8:
        # See RFC7538, 2.6: [...] ChaCha20 as specified here requires a 96-bit
        # nonce.  So if the provided nonce is only 64-bit, then the first 32
        # bits of the nonce will be set to a constant number.
        # This will usually be zero, but for protocols with multiple senders it may be
        # different for each sender, but should be the same for all
        # invocations of the function with the same key by a particular
        # sender.
        padded_nonce = b'\x00\x00\x00\x00' + nonce
    elif len(nonce) == 12:
        padded_nonce = nonce
    else:
        raise ValueError("Poly1305 with ChaCha20 requires an 8- or 12-byte nonce")

    rs = new(key=key, nonce=padded_nonce).encrypt(b'\x00' * 32)
    return rs[:16], rs[16:], nonce 
Example #18
Source File: common.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def __init__(self, module, params):
        from Crypto import Random
        unittest.TestCase.__init__(self)
        self.module = module
        self.iv = Random.get_random_bytes(module.block_size)
        self.key = b(params['key'])
        self.plaintext = 100 * b(params['plaintext'])
        self.module_name = params.get('module_name', None) 
Example #19
Source File: PKCS1_OAEP.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def new(key, hashAlgo=None, mgfunc=None, label=b'', randfunc=None):
    """Return a cipher object :class:`PKCS1OAEP_Cipher` that can be used to perform PKCS#1 OAEP encryption or decryption.

    :param key:
      The key object to use to encrypt or decrypt the message.
      Decryption is only possible with a private RSA key.
    :type key: RSA key object

    :param hashAlgo:
      The hash function to use. This can be a module under `Crypto.Hash`
      or an existing hash object created from any of such modules.
      If not specified, `Crypto.Hash.SHA1` is used.
    :type hashAlgo: hash object

    :param mgfunc:
      A mask generation function that accepts two parameters: a string to
      use as seed, and the lenth of the mask to generate, in bytes.
      If not specified, the standard MGF1 consistent with ``hashAlgo`` is used (a safe choice).
    :type mgfunc: callable

    :param label:
      A label to apply to this particular encryption. If not specified,
      an empty string is used. Specifying a label does not improve
      security.
    :type label: bytes/bytearray/memoryview

    :param randfunc:
      A function that returns random bytes.
      The default is `Random.get_random_bytes`.
    :type randfunc: callable
    """

    if randfunc is None:
        randfunc = Random.get_random_bytes
    return PKCS1OAEP_Cipher(key, hashAlgo, mgfunc, label, randfunc) 
Example #20
Source File: _mode_gcm.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method checks if the decrypted message is indeed valid
        (that is, if the key is correct) and it has not been
        tampered with while in transit.

        :Parameters:
          received_mac_tag : bytes/bytearray/memoryview
            This is the *binary* MAC, as received from the sender.
        :Raises ValueError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called"
                            " when encrypting a message")
        self._next = [self.verify]

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret,
                           data=self._compute_mac())
        mac2 = BLAKE2s.new(digest_bits=160, key=secret,
                           data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #21
Source File: _mode_cbc.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def _create_cbc_cipher(factory, **kwargs):
    """Instantiate a cipher object that performs CBC encryption/decryption.

    :Parameters:
      factory : module
        The underlying block cipher, a module from ``Crypto.Cipher``.

    :Keywords:
      iv : bytes/bytearray/memoryview
        The IV to use for CBC.

      IV : bytes/bytearray/memoryview
        Alias for ``iv``.

    Any other keyword will be passed to the underlying block cipher.
    See the relevant documentation for details (at least ``key`` will need
    to be present).
    """

    cipher_state = factory._create_base_cipher(kwargs)
    iv = kwargs.pop("IV", None)
    IV = kwargs.pop("iv", None)

    if (None, None) == (iv, IV):
        iv = get_random_bytes(factory.block_size)
    if iv is not None:
        if IV is not None:
            raise TypeError("You must either use 'iv' or 'IV', not both")
    else:
        iv = IV

    if len(iv) != factory.block_size:
        raise ValueError("Incorrect IV length (it must be %d bytes long)" %
                factory.block_size)

    if kwargs:
        raise TypeError("Unknown parameters for CBC: %s" % str(kwargs))

    return CbcMode(cipher_state, iv) 
Example #22
Source File: _mode_eax.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method checks if the decrypted message is indeed valid
        (that is, if the key is correct) and it has not been
        tampered with while in transit.

        :Parameters:
          received_mac_tag : bytes/bytearray/memoryview
            This is the *binary* MAC, as received from the sender.
        :Raises MacMismatchError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called"
                                " when encrypting a message")
        self._next = [self.verify]

        if not self._mac_tag:
            tag = b'\x00' * self.block_size
            for i in range(3):
                tag = strxor(tag, self._omac[i].digest())
            self._mac_tag = tag[:self._mac_len]

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #23
Source File: _mode_openpgp.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def _create_openpgp_cipher(factory, **kwargs):
    """Create a new block cipher, configured in OpenPGP mode.

    :Parameters:
      factory : module
        The module.

    :Keywords:
      key : bytes/bytearray/memoryview
        The secret key to use in the symmetric cipher.

      IV : bytes/bytearray/memoryview
        The initialization vector to use for encryption or decryption.

        For encryption, the IV must be as long as the cipher block size.

        For decryption, it must be 2 bytes longer (it is actually the
        *encrypted* IV which was prefixed to the ciphertext).
    """

    iv = kwargs.pop("IV", None)
    IV = kwargs.pop("iv", None)

    if (None, None) == (iv, IV):
        iv = get_random_bytes(factory.block_size)
    if iv is not None:
        if IV is not None:
            raise TypeError("You must either use 'iv' or 'IV', not both")
    else:
        iv = IV

    try:
        key = kwargs.pop("key")
    except KeyError as e:
        raise TypeError("Missing component: " + str(e))

    return OpenPgpMode(factory, key, iv, kwargs) 
Example #24
Source File: _mode_ocb.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        Call this method after the final `decrypt` (the one with no arguments)
        to check if the message is authentic and valid.

        :Parameters:
          received_mac_tag : bytes/bytearray/memoryview
            This is the *binary* MAC, as received from the sender.
        :Raises ValueError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called now for this cipher")

        assert(len(self._cache_P) == 0)

        self._next = [self.verify]

        if self._mac_tag is None:
            self._compute_mac_tag()

        secret = get_random_bytes(16)
        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #25
Source File: _mode_ocb.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def _create_ocb_cipher(factory, **kwargs):
    """Create a new block cipher, configured in OCB mode.

    :Parameters:
      factory : module
        A symmetric cipher module from `Crypto.Cipher`
        (like `Crypto.Cipher.AES`).

    :Keywords:
      nonce : bytes/bytearray/memoryview
        A  value that must never be reused for any other encryption.
        Its length can vary from 1 to 15 bytes.
        If not specified, a random 15 bytes long nonce is generated.

      mac_len : integer
        Length of the MAC, in bytes.
        It must be in the range ``[8..16]``.
        The default is 16 (128 bits).

    Any other keyword will be passed to the underlying block cipher.
    See the relevant documentation for details (at least ``key`` will need
    to be present).
    """

    try:
        nonce = kwargs.pop("nonce", None)
        if nonce is None:
            nonce = get_random_bytes(15)
        mac_len = kwargs.pop("mac_len", 16)
    except KeyError as e:
        raise TypeError("Keyword missing: " + str(e))

    return OcbMode(factory, nonce, mac_len, kwargs) 
Example #26
Source File: _mode_ccm.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method checks if the decrypted message is indeed valid
        (that is, if the key is correct) and it has not been
        tampered with while in transit.

        :Parameters:
          received_mac_tag : bytes/bytearray/memoryview
            This is the *binary* MAC, as received from the sender.
        :Raises ValueError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called"
                            " when encrypting a message")
        self._next = [self.verify]

        self._digest()
        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #27
Source File: ChaCha20_Poly1305.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* authentication tag (MAC).

        The receiver invokes this method at the very end, to
        check if the associated data (if any) and the decrypted
        messages are valid.

        :param bytes/bytearray/memoryview received_mac_tag:
            This is the 16-byte *binary* MAC, as received from the sender.
        :Raises ValueError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called"
                            " when encrypting a message")
        self._next = (self.verify,)

        secret = get_random_bytes(16)

        self._compute_mac()

        mac1 = BLAKE2s.new(digest_bits=160, key=secret,
                           data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret,
                           data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed") 
Example #28
Source File: encrypted.py    From federation with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_iv_key_encrypter():
        iv = get_random_bytes(AES.block_size)
        key = get_random_bytes(32)
        encrypter = AES.new(key, AES.MODE_CBC, iv)
        return iv, key, encrypter 
Example #29
Source File: cli.py    From neo-python with MIT License 5 votes vote down vote up
def create_wallet():
    private_key = bytes(Random.get_random_bytes(32))
    keypair = KeyPair(priv_key=private_key)
    return {
        "private_key": keypair.Export(),
        "address": keypair.GetAddress()
    } 
Example #30
Source File: _mode_siv.py    From FODI with GNU General Public License v3.0 5 votes vote down vote up
def verify(self, received_mac_tag):
        """Validate the *binary* MAC tag.

        The caller invokes this function at the very end.

        This method checks if the decrypted message is indeed valid
        (that is, if the key is correct) and it has not been
        tampered with while in transit.

        :Parameters:
          received_mac_tag : bytes/bytearray/memoryview
            This is the *binary* MAC, as received from the sender.
        :Raises ValueError:
            if the MAC does not match. The message has been tampered with
            or the key is incorrect.
        """

        if self.verify not in self._next:
            raise TypeError("verify() cannot be called"
                            " when encrypting a message")
        self._next = [self.verify]

        if self._mac_tag is None:
            self._mac_tag = self._kdf.derive()

        secret = get_random_bytes(16)

        mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
        mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)

        if mac1.digest() != mac2.digest():
            raise ValueError("MAC check failed")