diff options
Diffstat (limited to 'frozen_deps/Cryptodome/Hash')
45 files changed, 1262 insertions, 48 deletions
diff --git a/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi b/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi index ac3bf57..d37c374 100644 --- a/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi +++ b/frozen_deps/Cryptodome/Hash/BLAKE2b.pyi @@ -1,4 +1,5 @@ from typing import Any, Union +from types import ModuleType Buffer = Union[bytes, bytearray, memoryview] diff --git a/frozen_deps/Cryptodome/Hash/CMAC.py b/frozen_deps/Cryptodome/Hash/CMAC.py index df69f00..e831700 100644 --- a/frozen_deps/Cryptodome/Hash/CMAC.py +++ b/frozen_deps/Cryptodome/Hash/CMAC.py @@ -20,7 +20,6 @@ # SOFTWARE. # =================================================================== -import sys from binascii import unhexlify from Cryptodome.Hash import BLAKE2s @@ -29,8 +28,6 @@ from Cryptodome.Util.number import long_to_bytes, bytes_to_long from Cryptodome.Util.py3compat import bord, tobytes, _copy_bytes from Cryptodome.Random import get_random_bytes -if sys.version_info[:2] == (2, 6): - memoryview = bytes # The size of the authentication tag produced by the MAC. digest_size = None diff --git a/frozen_deps/Cryptodome/Hash/CMAC.pyi b/frozen_deps/Cryptodome/Hash/CMAC.pyi index 33773aa..acdf055 100644 --- a/frozen_deps/Cryptodome/Hash/CMAC.pyi +++ b/frozen_deps/Cryptodome/Hash/CMAC.pyi @@ -1,5 +1,5 @@ from types import ModuleType -from typing import Union, Dict +from typing import Union, Dict, Any Buffer = Union[bytes, bytearray, memoryview] @@ -12,7 +12,7 @@ class CMAC(object): key: Buffer, msg: Buffer, ciphermod: ModuleType, - cipher_params: dict, + cipher_params: Dict[str, Any], mac_len: int, update_after_digest: bool) -> None: ... def update(self, data: Buffer) -> CMAC: ... def copy(self) -> CMAC: ... @@ -25,6 +25,6 @@ class CMAC(object): def new(key: Buffer, msg: Buffer = ..., ciphermod: ModuleType = ..., - cipher_params: Dict = ..., + cipher_params: Dict[str, Any] = ..., mac_len: int = ..., update_after_digest: bool = ...) -> CMAC: ... diff --git a/frozen_deps/Cryptodome/Hash/HMAC.py b/frozen_deps/Cryptodome/Hash/HMAC.py index ac94b20..165dd83 100644 --- a/frozen_deps/Cryptodome/Hash/HMAC.py +++ b/frozen_deps/Cryptodome/Hash/HMAC.py @@ -31,7 +31,7 @@ # POSSIBILITY OF SUCH DAMAGE. # =================================================================== -from Cryptodome.Util.py3compat import bord, tobytes, _memoryview +from Cryptodome.Util.py3compat import bord, tobytes from binascii import unhexlify @@ -64,7 +64,7 @@ class HMAC(object): self._digestmod = digestmod - if isinstance(key, _memoryview): + if isinstance(key, memoryview): key = key.tobytes() try: diff --git a/frozen_deps/Cryptodome/Hash/KMAC128.py b/frozen_deps/Cryptodome/Hash/KMAC128.py new file mode 100644 index 0000000..afd91c4 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KMAC128.py @@ -0,0 +1,179 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from binascii import unhexlify + +from Cryptodome.Util.py3compat import bord, tobytes, is_bytes +from Cryptodome.Random import get_random_bytes + +from . import cSHAKE128, SHA3_256 +from .cSHAKE128 import _bytepad, _encode_str, _right_encode + + +class KMAC_Hash(object): + """A KMAC hash object. + Do not instantiate directly. + Use the :func:`new` function. + """ + + def __init__(self, data, key, mac_len, custom, + oid_variant, cshake, rate): + + # See https://tools.ietf.org/html/rfc8702 + self.oid = "2.16.840.1.101.3.4.2." + oid_variant + self.digest_size = mac_len + + self._mac = None + + partial_newX = _bytepad(_encode_str(tobytes(key)), rate) + self._cshake = cshake._new(partial_newX, custom, b"KMAC") + + if data: + self._cshake.update(data) + + def update(self, data): + """Authenticate the next chunk of message. + + Args: + data (bytes/bytearray/memoryview): The next chunk of the message to + authenticate. + """ + + if self._mac: + raise TypeError("You can only call 'digest' or 'hexdigest' on this object") + + self._cshake.update(data) + return self + + def digest(self): + """Return the **binary** (non-printable) MAC tag of the message. + + :return: The MAC tag. Binary form. + :rtype: byte string + """ + + if not self._mac: + self._cshake.update(_right_encode(self.digest_size * 8)) + self._mac = self._cshake.read(self.digest_size) + + return self._mac + + def hexdigest(self): + """Return the **printable** MAC tag of the message. + + :return: The MAC tag. Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in tuple(self.digest())]) + + 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 = SHA3_256.new(secret + mac_tag) + mac2 = SHA3_256.new(secret + self.digest()) + + if mac1.digest() != mac2.digest(): + raise ValueError("MAC check failed") + + def hexverify(self, hex_mac_tag): + """Verify that a given **printable** MAC (computed by another party) + is valid. + + Args: + hex_mac_tag (string): the expected MAC of the message, as a hexadecimal string. + + Raises: + ValueError: if the MAC does not match. It means that the message + has been tampered with or that the MAC key is incorrect. + """ + + self.verify(unhexlify(tobytes(hex_mac_tag))) + + def new(self, **kwargs): + """Return a new instance of a KMAC hash object. + See :func:`new`. + """ + + if "mac_len" not in kwargs: + kwargs["mac_len"] = self.digest_size + + return new(**kwargs) + + +def new(**kwargs): + """Create a new KMAC128 object. + + Args: + key (bytes/bytearray/memoryview): + The key to use to compute the MAC. + It must be at least 128 bits long (16 bytes). + data (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to authenticate. + It is equivalent to an early call to :meth:`KMAC_Hash.update`. + mac_len (integer): + Optional. The size of the authentication tag, in bytes. + Default is 64. Minimum is 8. + custom (bytes/bytearray/memoryview): + Optional. A customization byte string (``S`` in SP 800-185). + + Returns: + A :class:`KMAC_Hash` hash object + """ + + key = kwargs.pop("key", None) + if not is_bytes(key): + raise TypeError("You must pass a key to KMAC128") + if len(key) < 16: + raise ValueError("The key must be at least 128 bits long (16 bytes)") + + data = kwargs.pop("data", None) + + mac_len = kwargs.pop("mac_len", 64) + if mac_len < 8: + raise ValueError("'mac_len' must be 8 bytes or more") + + custom = kwargs.pop("custom", b"") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return KMAC_Hash(data, key, mac_len, custom, "19", cSHAKE128, 168) diff --git a/frozen_deps/Cryptodome/Hash/KMAC128.pyi b/frozen_deps/Cryptodome/Hash/KMAC128.pyi new file mode 100644 index 0000000..8947dab --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KMAC128.pyi @@ -0,0 +1,33 @@ +from typing import Union +from types import ModuleType + +Buffer = Union[bytes, bytearray, memoryview] + +class KMAC_Hash(object): + + def __init__(self, + data: Buffer, + key: Buffer, + mac_len: int, + custom: Buffer, + oid_variant: str, + cshake: ModuleType, + rate: int) -> None: ... + + def update(self, data: Buffer) -> KMAC_Hash: ... + + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def verify(self, mac_tag: Buffer) -> None: ... + def hexverify(self, hex_mac_tag: str) -> None: ... + def new(self, + data: Buffer = ..., + mac_len: int = ..., + key: Buffer = ..., + custom: Buffer = ...) -> KMAC_Hash: ... + + +def new(key: Buffer, + data: Buffer = ..., + mac_len: int = ..., + custom: Buffer = ...) -> KMAC_Hash: ... diff --git a/frozen_deps/Cryptodome/Hash/KMAC256.py b/frozen_deps/Cryptodome/Hash/KMAC256.py new file mode 100644 index 0000000..82da062 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KMAC256.py @@ -0,0 +1,74 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import is_bytes + +from .KMAC128 import KMAC_Hash +from . import cSHAKE256 + + +def new(**kwargs): + """Create a new KMAC256 object. + + Args: + key (bytes/bytearray/memoryview): + The key to use to compute the MAC. + It must be at least 256 bits long (32 bytes). + data (bytes/bytearray/memoryview): + Optional. The very first chunk of the message to authenticate. + It is equivalent to an early call to :meth:`KMAC_Hash.update`. + mac_len (integer): + Optional. The size of the authentication tag, in bytes. + Default is 64. Minimum is 8. + custom (bytes/bytearray/memoryview): + Optional. A customization byte string (``S`` in SP 800-185). + + Returns: + A :class:`KMAC_Hash` hash object + """ + + key = kwargs.pop("key", None) + if not is_bytes(key): + raise TypeError("You must pass a key to KMAC256") + if len(key) < 32: + raise ValueError("The key must be at least 256 bits long (32 bytes)") + + data = kwargs.pop("data", None) + + mac_len = kwargs.pop("mac_len", 64) + if mac_len < 8: + raise ValueError("'mac_len' must be 8 bytes or more") + + custom = kwargs.pop("custom", b"") + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return KMAC_Hash(data, key, mac_len, custom, "20", cSHAKE256, 136) diff --git a/frozen_deps/Cryptodome/Hash/KMAC256.pyi b/frozen_deps/Cryptodome/Hash/KMAC256.pyi new file mode 100644 index 0000000..86cc500 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KMAC256.pyi @@ -0,0 +1,10 @@ +from typing import Union + +from .KMAC128 import KMAC_Hash + +Buffer = Union[bytes, bytearray, memoryview] + +def new(key: Buffer, + data: Buffer = ..., + mac_len: int = ..., + custom: Buffer = ...) -> KMAC_Hash: ... diff --git a/frozen_deps/Cryptodome/Hash/KangarooTwelve.py b/frozen_deps/Cryptodome/Hash/KangarooTwelve.py new file mode 100644 index 0000000..44d935f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KangarooTwelve.py @@ -0,0 +1,262 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util._raw_api import (VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr, c_ubyte) + +from Cryptodome.Util.number import long_to_bytes +from Cryptodome.Util.py3compat import bchr + +from .keccak import _raw_keccak_lib + + +def _length_encode(x): + if x == 0: + return b'\x00' + + S = long_to_bytes(x) + return S + bchr(len(S)) + + +# Possible states for a KangarooTwelve instance, which depend on the amount of data processed so far. +SHORT_MSG = 1 # Still within the first 8192 bytes, but it is not certain we will exceed them. +LONG_MSG_S0 = 2 # Still within the first 8192 bytes, and it is certain we will exceed them. +LONG_MSG_SX = 3 # Beyond the first 8192 bytes. +SQUEEZING = 4 # No more data to process. + + +class K12_XOF(object): + """A KangarooTwelve hash object. + Do not instantiate directly. + Use the :func:`new` function. + """ + + def __init__(self, data, custom): + + if custom == None: + custom = b'' + + self._custom = custom + _length_encode(len(custom)) + self._state = SHORT_MSG + self._padding = None # Final padding is only decided in read() + + # Internal hash that consumes FinalNode + self._hash1 = self._create_keccak() + self._length1 = 0 + + # Internal hash that produces CV_i (reset each time) + self._hash2 = None + self._length2 = 0 + + # Incremented by one for each 8192-byte block + self._ctr = 0 + + if data: + self.update(data) + + def _create_keccak(self): + state = VoidPointer() + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(32), # 32 bytes of capacity (256 bits) + c_ubyte(12)) # Reduced number of rounds + if result: + raise ValueError("Error %d while instantiating KangarooTwelve" + % result) + return SmartPointer(state.get(), _raw_keccak_lib.keccak_destroy) + + def _update(self, data, hash_obj): + result = _raw_keccak_lib.keccak_absorb(hash_obj.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating KangarooTwelve state" + % result) + + def _squeeze(self, hash_obj, length, padding): + bfr = create_string_buffer(length) + result = _raw_keccak_lib.keccak_squeeze(hash_obj.get(), + bfr, + c_size_t(length), + c_ubyte(padding)) + if result: + raise ValueError("Error %d while extracting from KangarooTwelve" + % result) + + return get_raw_buffer(bfr) + + def _reset(self, hash_obj): + result = _raw_keccak_lib.keccak_reset(hash_obj.get()) + if result: + raise ValueError("Error %d while resetting KangarooTwelve state" + % result) + + def update(self, data): + """Hash the next piece of data. + + .. note:: + For better performance, submit chunks with a length multiple of 8192 bytes. + + Args: + data (byte string/byte array/memoryview): The next chunk of the + message to hash. + """ + + if self._state == SQUEEZING: + raise TypeError("You cannot call 'update' after the first 'read'") + + if self._state == SHORT_MSG: + next_length = self._length1 + len(data) + + if next_length + len(self._custom) <= 8192: + self._length1 = next_length + self._update(data, self._hash1) + return self + + # Switch to tree hashing + self._state = LONG_MSG_S0 + + if self._state == LONG_MSG_S0: + data_mem = memoryview(data) + assert(self._length1 < 8192) + dtc = min(len(data), 8192 - self._length1) + self._update(data_mem[:dtc], self._hash1) + self._length1 += dtc + + if self._length1 < 8192: + return self + + # Finish hashing S_0 and start S_1 + assert(self._length1 == 8192) + + divider = b'\x03' + b'\x00' * 7 + self._update(divider, self._hash1) + self._length1 += 8 + + self._hash2 = self._create_keccak() + self._length2 = 0 + self._ctr = 1 + + self._state = LONG_MSG_SX + return self.update(data_mem[dtc:]) + + # LONG_MSG_SX + assert(self._state == LONG_MSG_SX) + index = 0 + len_data = len(data) + + # All iteractions could actually run in parallel + data_mem = memoryview(data) + while index < len_data: + + new_index = min(index + 8192 - self._length2, len_data) + self._update(data_mem[index:new_index], self._hash2) + self._length2 += new_index - index + index = new_index + + if self._length2 == 8192: + cv_i = self._squeeze(self._hash2, 32, 0x0B) + self._update(cv_i, self._hash1) + self._length1 += 32 + self._reset(self._hash2) + self._length2 = 0 + self._ctr += 1 + + return self + + def read(self, length): + """ + Produce more bytes of the digest. + + .. note:: + You cannot use :meth:`update` anymore after the first call to + :meth:`read`. + + Args: + length (integer): the amount of bytes this method must return + + :return: the next piece of XOF output (of the given length) + :rtype: byte string + """ + + custom_was_consumed = False + + if self._state == SHORT_MSG: + self._update(self._custom, self._hash1) + self._padding = 0x07 + self._state = SQUEEZING + + if self._state == LONG_MSG_S0: + self.update(self._custom) + custom_was_consumed = True + assert(self._state == LONG_MSG_SX) + + if self._state == LONG_MSG_SX: + if not custom_was_consumed: + self.update(self._custom) + + # Is there still some leftover data in hash2? + if self._length2 > 0: + cv_i = self._squeeze(self._hash2, 32, 0x0B) + self._update(cv_i, self._hash1) + self._length1 += 32 + self._reset(self._hash2) + self._length2 = 0 + self._ctr += 1 + + trailer = _length_encode(self._ctr - 1) + b'\xFF\xFF' + self._update(trailer, self._hash1) + + self._padding = 0x06 + self._state = SQUEEZING + + return self._squeeze(self._hash1, length, self._padding) + + def new(self, data=None, custom=b''): + return type(self)(data, custom) + + +def new(data=None, custom=None): + """Return a fresh instance of a KangarooTwelve object. + + Args: + data (bytes/bytearray/memoryview): + Optional. + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + custom (bytes): + Optional. + A customization byte string. + + :Return: A :class:`K12_XOF` object + """ + + return K12_XOF(data, custom) diff --git a/frozen_deps/Cryptodome/Hash/KangarooTwelve.pyi b/frozen_deps/Cryptodome/Hash/KangarooTwelve.pyi new file mode 100644 index 0000000..8b3fd74 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/KangarooTwelve.pyi @@ -0,0 +1,16 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class K12_XOF(object): + def __init__(self, + data: Optional[Buffer] = ..., + custom: Optional[bytes] = ...) -> None: ... + def update(self, data: Buffer) -> K12_XOF: ... + def read(self, length: int) -> bytes: ... + def new(self, + data: Optional[Buffer] = ..., + custom: Optional[bytes] = ...) -> None: ... + +def new(data: Optional[Buffer] = ..., + custom: Optional[Buffer] = ...) -> K12_XOF: ... diff --git a/frozen_deps/Cryptodome/Hash/SHA3_224.py b/frozen_deps/Cryptodome/Hash/SHA3_224.py index 3196bd6..34888c5 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_224.py +++ b/frozen_deps/Cryptodome/Hash/SHA3_224.py @@ -24,7 +24,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -46,14 +46,18 @@ class SHA3_224_Hash(object): # ASN.1 Object ID oid = "2.16.840.1.101.3.4.2.7" + # Input block size for HMAC + block_size = 144 + def __init__(self, data, update_after_digest): self._update_after_digest = update_after_digest self._digest_done = False + self._padding = 0x06 state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(self.digest_size * 2), - 0x06) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHA-3/224" % result) @@ -74,7 +78,8 @@ class SHA3_224_Hash(object): result = _raw_keccak_lib.keccak_absorb(self._state.get(), c_uint8_ptr(data), - c_size_t(len(data))) + c_size_t(len(data)) + ) if result: raise ValueError("Error %d while updating SHA-3/224" % result) @@ -93,7 +98,8 @@ class SHA3_224_Hash(object): bfr = create_string_buffer(self.digest_size) result = _raw_keccak_lib.keccak_digest(self._state.get(), bfr, - c_size_t(self.digest_size)) + c_size_t(self.digest_size), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while instantiating SHA-3/224" % result) @@ -111,10 +117,28 @@ class SHA3_224_Hash(object): return "".join(["%02x" % bord(x) for x in self.digest()]) - def new(self): + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :return: A hash object of the same type + """ + + clone = self.new() + result = _raw_keccak_lib.keccak_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA3-224" % result) + return clone + + def new(self, data=None): """Create a fresh SHA3-224 hash object.""" - return type(self)(None, self._update_after_digest) + return type(self)(data, self._update_after_digest) def new(*args, **kwargs): @@ -145,3 +169,6 @@ def new(*args, **kwargs): # The size of the resulting hash in bytes. digest_size = SHA3_224_Hash.digest_size + +# Input block size for HMAC +block_size = 144 diff --git a/frozen_deps/Cryptodome/Hash/SHA3_224.pyi b/frozen_deps/Cryptodome/Hash/SHA3_224.pyi index 3437042..2180821 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_224.pyi +++ b/frozen_deps/Cryptodome/Hash/SHA3_224.pyi @@ -4,13 +4,16 @@ Buffer = Union[bytes, bytearray, memoryview] class SHA3_224_Hash(object): digest_size: int + block_size: int oid: str def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... def update(self, data: Buffer) -> SHA3_224_Hash: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... - def new(self) -> SHA3_224_Hash: ... + def copy(self) -> SHA3_224_Hash: ... + def new(self, data: Optional[Buffer]) -> SHA3_224_Hash: ... def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_224_Hash: ... digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_256.py b/frozen_deps/Cryptodome/Hash/SHA3_256.py index 89e3b42..024962f 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_256.py +++ b/frozen_deps/Cryptodome/Hash/SHA3_256.py @@ -24,7 +24,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -46,14 +46,18 @@ class SHA3_256_Hash(object): # ASN.1 Object ID oid = "2.16.840.1.101.3.4.2.8" + # Input block size for HMAC + block_size = 136 + def __init__(self, data, update_after_digest): self._update_after_digest = update_after_digest self._digest_done = False + self._padding = 0x06 state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(self.digest_size * 2), - 0x06) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHA-3/256" % result) @@ -74,7 +78,8 @@ class SHA3_256_Hash(object): result = _raw_keccak_lib.keccak_absorb(self._state.get(), c_uint8_ptr(data), - c_size_t(len(data))) + c_size_t(len(data)) + ) if result: raise ValueError("Error %d while updating SHA-3/256" % result) @@ -93,7 +98,8 @@ class SHA3_256_Hash(object): bfr = create_string_buffer(self.digest_size) result = _raw_keccak_lib.keccak_digest(self._state.get(), bfr, - c_size_t(self.digest_size)) + c_size_t(self.digest_size), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while instantiating SHA-3/256" % result) @@ -111,10 +117,28 @@ class SHA3_256_Hash(object): return "".join(["%02x" % bord(x) for x in self.digest()]) - def new(self): + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :return: A hash object of the same type + """ + + clone = self.new() + result = _raw_keccak_lib.keccak_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA3-256" % result) + return clone + + def new(self, data=None): """Create a fresh SHA3-256 hash object.""" - return type(self)(None, self._update_after_digest) + return type(self)(data, self._update_after_digest) def new(*args, **kwargs): @@ -145,3 +169,6 @@ def new(*args, **kwargs): # The size of the resulting hash in bytes. digest_size = SHA3_256_Hash.digest_size + +# Input block size for HMAC +block_size = 136 diff --git a/frozen_deps/Cryptodome/Hash/SHA3_256.pyi b/frozen_deps/Cryptodome/Hash/SHA3_256.pyi index c1a07fa..88436bd 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_256.pyi +++ b/frozen_deps/Cryptodome/Hash/SHA3_256.pyi @@ -4,13 +4,16 @@ Buffer = Union[bytes, bytearray, memoryview] class SHA3_256_Hash(object): digest_size: int + block_size: int oid: str def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... def update(self, data: Buffer) -> SHA3_256_Hash: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... - def new(self) -> SHA3_256_Hash: ... + def copy(self) -> SHA3_256_Hash: ... + def new(self, data: Optional[Buffer]) -> SHA3_256_Hash: ... def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_256_Hash: ... digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_384.py b/frozen_deps/Cryptodome/Hash/SHA3_384.py index e6baf3f..26eeb79 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_384.py +++ b/frozen_deps/Cryptodome/Hash/SHA3_384.py @@ -24,7 +24,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -46,14 +46,18 @@ class SHA3_384_Hash(object): # ASN.1 Object ID oid = "2.16.840.1.101.3.4.2.9" + # Input block size for HMAC + block_size = 104 + def __init__(self, data, update_after_digest): self._update_after_digest = update_after_digest self._digest_done = False + self._padding = 0x06 state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(self.digest_size * 2), - 0x06) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHA-3/384" % result) @@ -93,7 +97,8 @@ class SHA3_384_Hash(object): bfr = create_string_buffer(self.digest_size) result = _raw_keccak_lib.keccak_digest(self._state.get(), bfr, - c_size_t(self.digest_size)) + c_size_t(self.digest_size), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while instantiating SHA-3/384" % result) @@ -111,10 +116,34 @@ class SHA3_384_Hash(object): return "".join(["%02x" % bord(x) for x in self.digest()]) - def new(self): + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :return: A hash object of the same type + """ + + clone = self.new() + result = _raw_keccak_lib.keccak_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA3-384" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA3-256 hash object.""" + + return type(self)(data, self._update_after_digest) + + + def new(self, data=None): """Create a fresh SHA3-384 hash object.""" - return type(self)(None, self._update_after_digest) + return type(self)(data, self._update_after_digest) def new(*args, **kwargs): @@ -145,3 +174,6 @@ def new(*args, **kwargs): # The size of the resulting hash in bytes. digest_size = SHA3_384_Hash.digest_size + +# Input block size for HMAC +block_size = 104 diff --git a/frozen_deps/Cryptodome/Hash/SHA3_384.pyi b/frozen_deps/Cryptodome/Hash/SHA3_384.pyi index d029ab6..98d00c6 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_384.pyi +++ b/frozen_deps/Cryptodome/Hash/SHA3_384.pyi @@ -4,13 +4,16 @@ Buffer = Union[bytes, bytearray, memoryview] class SHA3_384_Hash(object): digest_size: int + block_size: int oid: str def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... def update(self, data: Buffer) -> SHA3_384_Hash: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... - def new(self) -> SHA3_384_Hash: ... + def copy(self) -> SHA3_384_Hash: ... + def new(self, data: Optional[Buffer]) -> SHA3_384_Hash: ... def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_384_Hash: ... digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHA3_512.py b/frozen_deps/Cryptodome/Hash/SHA3_512.py index 676ce2f..99b1c37 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_512.py +++ b/frozen_deps/Cryptodome/Hash/SHA3_512.py @@ -24,7 +24,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -46,14 +46,18 @@ class SHA3_512_Hash(object): # ASN.1 Object ID oid = "2.16.840.1.101.3.4.2.10" + # Input block size for HMAC + block_size = 72 + def __init__(self, data, update_after_digest): self._update_after_digest = update_after_digest self._digest_done = False + self._padding = 0x06 state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(self.digest_size * 2), - 0x06) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHA-3/512" % result) @@ -94,7 +98,8 @@ class SHA3_512_Hash(object): bfr = create_string_buffer(self.digest_size) result = _raw_keccak_lib.keccak_digest(self._state.get(), bfr, - c_size_t(self.digest_size)) + c_size_t(self.digest_size), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while instantiating SHA-3/512" % result) @@ -112,10 +117,28 @@ class SHA3_512_Hash(object): return "".join(["%02x" % bord(x) for x in self.digest()]) - def new(self): - """Create a fresh SHA3-512 hash object.""" + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :return: A hash object of the same type + """ + + clone = self.new() + result = _raw_keccak_lib.keccak_copy(self._state.get(), + clone._state.get()) + if result: + raise ValueError("Error %d while copying SHA3-512" % result) + return clone + + def new(self, data=None): + """Create a fresh SHA3-521 hash object.""" - return type(self)(None, self._update_after_digest) + return type(self)(data, self._update_after_digest) def new(*args, **kwargs): @@ -146,3 +169,6 @@ def new(*args, **kwargs): # The size of the resulting hash in bytes. digest_size = SHA3_512_Hash.digest_size + +# Input block size for HMAC +block_size = 72 diff --git a/frozen_deps/Cryptodome/Hash/SHA3_512.pyi b/frozen_deps/Cryptodome/Hash/SHA3_512.pyi index 2c5403b..cdeec16 100644 --- a/frozen_deps/Cryptodome/Hash/SHA3_512.pyi +++ b/frozen_deps/Cryptodome/Hash/SHA3_512.pyi @@ -4,13 +4,16 @@ Buffer = Union[bytes, bytearray, memoryview] class SHA3_512_Hash(object): digest_size: int + block_size: int oid: str def __init__(self, data: Optional[Buffer], update_after_digest: bool) -> None: ... def update(self, data: Buffer) -> SHA3_512_Hash: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... - def new(self) -> SHA3_512_Hash: ... + def copy(self) -> SHA3_512_Hash: ... + def new(self, data: Optional[Buffer]) -> SHA3_512_Hash: ... def new(__data: Buffer = ..., update_after_digest: bool = ...) -> SHA3_512_Hash: ... digest_size: int +block_size: int diff --git a/frozen_deps/Cryptodome/Hash/SHAKE128.py b/frozen_deps/Cryptodome/Hash/SHAKE128.py index be2b22e..5bde2b6 100644 --- a/frozen_deps/Cryptodome/Hash/SHAKE128.py +++ b/frozen_deps/Cryptodome/Hash/SHAKE128.py @@ -34,7 +34,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -54,13 +54,14 @@ class SHAKE128_XOF(object): state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(32), - 0x1F) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHAKE128" % result) self._state = SmartPointer(state.get(), _raw_keccak_lib.keccak_destroy) self._is_squeezing = False + self._padding = 0x1F if data: self.update(data) @@ -101,7 +102,8 @@ class SHAKE128_XOF(object): bfr = create_string_buffer(length) result = _raw_keccak_lib.keccak_squeeze(self._state.get(), bfr, - c_size_t(length)) + c_size_t(length), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while extracting from SHAKE128" % result) diff --git a/frozen_deps/Cryptodome/Hash/SHAKE256.py b/frozen_deps/Cryptodome/Hash/SHAKE256.py index 46040e1..8c37f6a 100644 --- a/frozen_deps/Cryptodome/Hash/SHAKE256.py +++ b/frozen_deps/Cryptodome/Hash/SHAKE256.py @@ -34,7 +34,7 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) from Cryptodome.Hash.keccak import _raw_keccak_lib @@ -54,13 +54,15 @@ class SHAKE256_XOF(object): state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(64), - 0x1F) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating SHAKE256" % result) self._state = SmartPointer(state.get(), _raw_keccak_lib.keccak_destroy) self._is_squeezing = False + self._padding = 0x1F + if data: self.update(data) @@ -101,7 +103,8 @@ class SHAKE256_XOF(object): bfr = create_string_buffer(length) result = _raw_keccak_lib.keccak_squeeze(self._state.get(), bfr, - c_size_t(length)) + c_size_t(length), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while extracting from SHAKE256" % result) diff --git a/frozen_deps/Cryptodome/Hash/TupleHash128.py b/frozen_deps/Cryptodome/Hash/TupleHash128.py new file mode 100644 index 0000000..5c910e4 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/TupleHash128.py @@ -0,0 +1,138 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bord, is_bytes, tobytes + +from . import cSHAKE128 +from .cSHAKE128 import _encode_str, _right_encode + + +class TupleHash(object): + """A Tuple hash object. + Do not instantiate directly. + Use the :func:`new` function. + """ + + def __init__(self, custom, cshake, digest_size): + + self.digest_size = digest_size + + self._cshake = cshake._new(b'', custom, b'TupleHash') + self._digest = None + + def update(self, data): + """Authenticate the next byte string in the tuple. + + Args: + data (bytes/bytearray/memoryview): The next byte string. + """ + + if self._digest is not None: + raise TypeError("You cannot call 'update' after 'digest' or 'hexdigest'") + + if not is_bytes(data): + raise TypeError("You can only call 'update' on bytes") + + self._cshake.update(_encode_str(tobytes(data))) + + return self + + def digest(self): + """Return the **binary** (non-printable) digest of the tuple of byte strings. + + :return: The hash digest. Binary form. + :rtype: byte string + """ + + if self._digest is None: + self._cshake.update(_right_encode(self.digest_size * 8)) + self._digest = self._cshake.read(self.digest_size) + + return self._digest + + def hexdigest(self): + """Return the **printable** digest of the tuple of byte strings. + + :return: The hash digest. Hexadecimal encoded. + :rtype: string + """ + + return "".join(["%02x" % bord(x) for x in tuple(self.digest())]) + + def new(self, **kwargs): + """Return a new instance of a TupleHash object. + See :func:`new`. + """ + + if "digest_bytes" not in kwargs and "digest_bits" not in kwargs: + kwargs["digest_bytes"] = self.digest_size + + return new(**kwargs) + + +def new(**kwargs): + """Create a new TupleHash128 object. + + Args: + digest_bytes (integer): + Optional. The size of the digest, in bytes. + Default is 64. Minimum is 8. + digest_bits (integer): + Optional and alternative to ``digest_bytes``. + The size of the digest, in bits (and in steps of 8). + Default is 512. Minimum is 64. + custom (bytes): + Optional. + A customization bytestring (``S`` in SP 800-185). + + :Return: A :class:`TupleHash` object + """ + + digest_bytes = kwargs.pop("digest_bytes", None) + digest_bits = kwargs.pop("digest_bits", None) + if None not in (digest_bytes, digest_bits): + raise TypeError("Only one digest parameter must be provided") + if (None, None) == (digest_bytes, digest_bits): + digest_bytes = 64 + if digest_bytes is not None: + if digest_bytes < 8: + raise ValueError("'digest_bytes' must be at least 8") + else: + if digest_bits < 64 or digest_bits % 8: + raise ValueError("'digest_bytes' must be at least 64 " + "in steps of 8") + digest_bytes = digest_bits // 8 + + custom = kwargs.pop("custom", b'') + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return TupleHash(custom, cSHAKE128, digest_bytes) diff --git a/frozen_deps/Cryptodome/Hash/TupleHash128.pyi b/frozen_deps/Cryptodome/Hash/TupleHash128.pyi new file mode 100644 index 0000000..3b1e81e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/TupleHash128.pyi @@ -0,0 +1,22 @@ +from typing import Any, Union +from types import ModuleType + +Buffer = Union[bytes, bytearray, memoryview] + +class TupleHash(object): + digest_size: int + def __init__(self, + custom: bytes, + cshake: ModuleType, + digest_size: int) -> None: ... + def update(self, data: Buffer) -> TupleHash: ... + def digest(self) -> bytes: ... + def hexdigest(self) -> str: ... + def new(self, + digest_bytes: int = ..., + digest_bits: int = ..., + custom: int = ...) -> TupleHash: ... + +def new(digest_bytes: int = ..., + digest_bits: int = ..., + custom: int = ...) -> TupleHash: ... diff --git a/frozen_deps/Cryptodome/Hash/TupleHash256.py b/frozen_deps/Cryptodome/Hash/TupleHash256.py new file mode 100644 index 0000000..9b4fba0 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/TupleHash256.py @@ -0,0 +1,73 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from . import cSHAKE256 +from .TupleHash128 import TupleHash + + +def new(**kwargs): + """Create a new TupleHash256 object. + + Args: + digest_bytes (integer): + Optional. The size of the digest, in bytes. + Default is 64. Minimum is 8. + digest_bits (integer): + Optional and alternative to ``digest_bytes``. + The size of the digest, in bits (and in steps of 8). + Default is 512. Minimum is 64. + custom (bytes): + Optional. + A customization bytestring (``S`` in SP 800-185). + + :Return: A :class:`TupleHash` object + """ + + digest_bytes = kwargs.pop("digest_bytes", None) + digest_bits = kwargs.pop("digest_bits", None) + if None not in (digest_bytes, digest_bits): + raise TypeError("Only one digest parameter must be provided") + if (None, None) == (digest_bytes, digest_bits): + digest_bytes = 64 + if digest_bytes is not None: + if digest_bytes < 8: + raise ValueError("'digest_bytes' must be at least 8") + else: + if digest_bits < 64 or digest_bits % 8: + raise ValueError("'digest_bytes' must be at least 64 " + "in steps of 8") + digest_bytes = digest_bits // 8 + + custom = kwargs.pop("custom", b'') + + if kwargs: + raise TypeError("Unknown parameters: " + str(kwargs)) + + return TupleHash(custom, cSHAKE256, digest_bytes) diff --git a/frozen_deps/Cryptodome/Hash/TupleHash256.pyi b/frozen_deps/Cryptodome/Hash/TupleHash256.pyi new file mode 100644 index 0000000..82d943f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/TupleHash256.pyi @@ -0,0 +1,5 @@ +from .TupleHash128 import TupleHash + +def new(digest_bytes: int = ..., + digest_bits: int = ..., + custom: int = ...) -> TupleHash: ... diff --git a/frozen_deps/Cryptodome/Hash/_BLAKE2b.abi3.so b/frozen_deps/Cryptodome/Hash/_BLAKE2b.abi3.so Binary files differnew file mode 100755 index 0000000..dfdf331 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_BLAKE2b.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_BLAKE2s.abi3.so b/frozen_deps/Cryptodome/Hash/_BLAKE2s.abi3.so Binary files differnew file mode 100755 index 0000000..26e69e8 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_BLAKE2s.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_MD2.abi3.so b/frozen_deps/Cryptodome/Hash/_MD2.abi3.so Binary files differnew file mode 100755 index 0000000..576ba1e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_MD2.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_MD4.abi3.so b/frozen_deps/Cryptodome/Hash/_MD4.abi3.so Binary files differnew file mode 100755 index 0000000..0afc5ca --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_MD4.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_MD5.abi3.so b/frozen_deps/Cryptodome/Hash/_MD5.abi3.so Binary files differnew file mode 100755 index 0000000..38caf8d --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_MD5.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_RIPEMD160.abi3.so b/frozen_deps/Cryptodome/Hash/_RIPEMD160.abi3.so Binary files differnew file mode 100755 index 0000000..2c02e71 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_RIPEMD160.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_SHA1.abi3.so b/frozen_deps/Cryptodome/Hash/_SHA1.abi3.so Binary files differnew file mode 100755 index 0000000..2d86b06 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_SHA1.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_SHA224.abi3.so b/frozen_deps/Cryptodome/Hash/_SHA224.abi3.so Binary files differnew file mode 100755 index 0000000..c462c9b --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_SHA224.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_SHA256.abi3.so b/frozen_deps/Cryptodome/Hash/_SHA256.abi3.so Binary files differnew file mode 100755 index 0000000..c51c162 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_SHA256.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_SHA384.abi3.so b/frozen_deps/Cryptodome/Hash/_SHA384.abi3.so Binary files differnew file mode 100755 index 0000000..4a4237e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_SHA384.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_SHA512.abi3.so b/frozen_deps/Cryptodome/Hash/_SHA512.abi3.so Binary files differnew file mode 100755 index 0000000..ff9a01f --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_SHA512.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/__init__.py b/frozen_deps/Cryptodome/Hash/__init__.py index 719cd8d..4bda084 100644 --- a/frozen_deps/Cryptodome/Hash/__init__.py +++ b/frozen_deps/Cryptodome/Hash/__init__.py @@ -19,4 +19,6 @@ # =================================================================== __all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', - 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC', 'Poly1305'] + 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC', 'Poly1305', + 'cSHAKE128', 'cSHAKE256', 'KMAC128', 'KMAC256', + 'TupleHash128', 'TupleHash256', 'KangarooTwelve'] diff --git a/frozen_deps/Cryptodome/Hash/_ghash_clmul.abi3.so b/frozen_deps/Cryptodome/Hash/_ghash_clmul.abi3.so Binary files differnew file mode 100755 index 0000000..248bdb7 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_ghash_clmul.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_ghash_portable.abi3.so b/frozen_deps/Cryptodome/Hash/_ghash_portable.abi3.so Binary files differnew file mode 100755 index 0000000..292f45d --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_ghash_portable.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_keccak.abi3.so b/frozen_deps/Cryptodome/Hash/_keccak.abi3.so Binary files differnew file mode 100755 index 0000000..b251995 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_keccak.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/_poly1305.abi3.so b/frozen_deps/Cryptodome/Hash/_poly1305.abi3.so Binary files differnew file mode 100755 index 0000000..e8da59e --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/_poly1305.abi3.so diff --git a/frozen_deps/Cryptodome/Hash/cSHAKE128.py b/frozen_deps/Cryptodome/Hash/cSHAKE128.py new file mode 100644 index 0000000..7c2f30a --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/cSHAKE128.py @@ -0,0 +1,187 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util.py3compat import bchr + +from Cryptodome.Util._raw_api import (VoidPointer, SmartPointer, + create_string_buffer, + get_raw_buffer, c_size_t, + c_uint8_ptr, c_ubyte) + +from Cryptodome.Util.number import long_to_bytes + +from Cryptodome.Hash.keccak import _raw_keccak_lib + + +def _left_encode(x): + """Left encode function as defined in NIST SP 800-185""" + + assert (x < (1 << 2040) and x >= 0) + + # Get number of bytes needed to represent this integer. + num = 1 if x == 0 else (x.bit_length() + 7) // 8 + + return bchr(num) + long_to_bytes(x) + + +def _right_encode(x): + """Right encode function as defined in NIST SP 800-185""" + + assert (x < (1 << 2040) and x >= 0) + + # Get number of bytes needed to represent this integer. + num = 1 if x == 0 else (x.bit_length() + 7) // 8 + + return long_to_bytes(x) + bchr(num) + + +def _encode_str(x): + """Encode string function as defined in NIST SP 800-185""" + + bitlen = len(x) * 8 + if bitlen >= (1 << 2040): + raise ValueError("String too large to encode in cSHAKE") + + return _left_encode(bitlen) + x + + +def _bytepad(x, length): + """Zero pad byte string as defined in NIST SP 800-185""" + + to_pad = _left_encode(length) + x + + # Note: this implementation works with byte aligned strings, + # hence no additional bit padding is needed at this point. + npad = (length - len(to_pad) % length) % length + + return to_pad + b'\x00' * npad + + +class cSHAKE_XOF(object): + """A cSHAKE hash object. + Do not instantiate directly. + Use the :func:`new` function. + """ + + def __init__(self, data, custom, capacity, function): + state = VoidPointer() + + if custom or function: + prefix_unpad = _encode_str(function) + _encode_str(custom) + prefix = _bytepad(prefix_unpad, (1600 - capacity)//8) + self._padding = 0x04 + else: + prefix = None + self._padding = 0x1F # for SHAKE + + result = _raw_keccak_lib.keccak_init(state.address_of(), + c_size_t(capacity//8), + c_ubyte(24)) + if result: + raise ValueError("Error %d while instantiating cSHAKE" + % result) + self._state = SmartPointer(state.get(), + _raw_keccak_lib.keccak_destroy) + self._is_squeezing = False + + if prefix: + self.update(prefix) + + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Args: + data (byte string/byte array/memoryview): The next chunk of the message being hashed. + """ + + if self._is_squeezing: + raise TypeError("You cannot call 'update' after the first 'read'") + + result = _raw_keccak_lib.keccak_absorb(self._state.get(), + c_uint8_ptr(data), + c_size_t(len(data))) + if result: + raise ValueError("Error %d while updating %s state" + % (result, self.name)) + return self + + def read(self, length): + """ + Compute the next piece of XOF output. + + .. note:: + You cannot use :meth:`update` anymore after the first call to + :meth:`read`. + + Args: + length (integer): the amount of bytes this method must return + + :return: the next piece of XOF output (of the given length) + :rtype: byte string + """ + + self._is_squeezing = True + bfr = create_string_buffer(length) + result = _raw_keccak_lib.keccak_squeeze(self._state.get(), + bfr, + c_size_t(length), + c_ubyte(self._padding)) + if result: + raise ValueError("Error %d while extracting from %s" + % (result, self.name)) + + return get_raw_buffer(bfr) + + +def _new(data, custom, function): + # Use Keccak[256] + return cSHAKE_XOF(data, custom, 256, function) + + +def new(data=None, custom=None): + """Return a fresh instance of a cSHAKE128 object. + + Args: + data (bytes/bytearray/memoryview): + Optional. + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + custom (bytes): + Optional. + A customization bytestring (``S`` in SP 800-185). + + :Return: A :class:`cSHAKE_XOF` object + """ + + # Use Keccak[256] + return cSHAKE_XOF(data, custom, 256, b'') diff --git a/frozen_deps/Cryptodome/Hash/cSHAKE128.pyi b/frozen_deps/Cryptodome/Hash/cSHAKE128.pyi new file mode 100644 index 0000000..1452fea --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/cSHAKE128.pyi @@ -0,0 +1,14 @@ +from typing import Union, Optional + +Buffer = Union[bytes, bytearray, memoryview] + +class cSHAKE_XOF(object): + def __init__(self, + data: Optional[Buffer] = ..., + function: Optional[bytes] = ..., + custom: Optional[bytes] = ...) -> None: ... + def update(self, data: Buffer) -> cSHAKE_XOF: ... + def read(self, length: int) -> bytes: ... + +def new(data: Optional[Buffer] = ..., + custom: Optional[Buffer] = ...) -> cSHAKE_XOF: ... diff --git a/frozen_deps/Cryptodome/Hash/cSHAKE256.py b/frozen_deps/Cryptodome/Hash/cSHAKE256.py new file mode 100644 index 0000000..a5b8701 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/cSHAKE256.py @@ -0,0 +1,56 @@ +# =================================================================== +# +# Copyright (c) 2021, Legrandin <[email protected]> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +from Cryptodome.Util._raw_api import c_size_t +from Cryptodome.Hash.cSHAKE128 import cSHAKE_XOF + + +def _new(data, custom, function): + # Use Keccak[512] + return cSHAKE_XOF(data, custom, 512, function) + + +def new(data=None, custom=None): + """Return a fresh instance of a cSHAKE256 object. + + Args: + data (bytes/bytearray/memoryview): + The very first chunk of the message to hash. + It is equivalent to an early call to :meth:`update`. + Optional. + custom (bytes): + Optional. + A customization bytestring (``S`` in SP 800-185). + + :Return: A :class:`cSHAKE_XOF` object + """ + + # Use Keccak[512] + return cSHAKE_XOF(data, custom, 512, b'') diff --git a/frozen_deps/Cryptodome/Hash/cSHAKE256.pyi b/frozen_deps/Cryptodome/Hash/cSHAKE256.pyi new file mode 100644 index 0000000..b910bb6 --- /dev/null +++ b/frozen_deps/Cryptodome/Hash/cSHAKE256.pyi @@ -0,0 +1,8 @@ +from typing import Union, Optional + +from Cryptodome.Hash.cSHAKE128 import cSHAKE_XOF + +Buffer = Union[bytes, bytearray, memoryview] + +def new(data: Optional[Buffer] = ..., + custom: Optional[Buffer] = ...) -> cSHAKE_XOF: ... diff --git a/frozen_deps/Cryptodome/Hash/keccak.py b/frozen_deps/Cryptodome/Hash/keccak.py index 9ae8ec5..f2af202 100644 --- a/frozen_deps/Cryptodome/Hash/keccak.py +++ b/frozen_deps/Cryptodome/Hash/keccak.py @@ -34,21 +34,27 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer, SmartPointer, create_string_buffer, get_raw_buffer, c_size_t, - c_uint8_ptr) + c_uint8_ptr, c_ubyte) _raw_keccak_lib = load_pycryptodome_raw_lib("Cryptodome.Hash._keccak", """ int keccak_init(void **state, size_t capacity_bytes, - uint8_t padding_byte); + uint8_t rounds); int keccak_destroy(void *state); int keccak_absorb(void *state, const uint8_t *in, size_t len); int keccak_squeeze(const void *state, uint8_t *out, - size_t len); - int keccak_digest(void *state, uint8_t *digest, size_t len); + size_t len, + uint8_t padding); + int keccak_digest(void *state, + uint8_t *digest, + size_t len, + uint8_t padding); + int keccak_copy(const void *src, void *dst); + int keccak_reset(void *state); """) class Keccak_Hash(object): @@ -66,11 +72,12 @@ class Keccak_Hash(object): self._update_after_digest = update_after_digest self._digest_done = False + self._padding = 0x01 state = VoidPointer() result = _raw_keccak_lib.keccak_init(state.address_of(), c_size_t(self.digest_size * 2), - 0x01) + c_ubyte(24)) if result: raise ValueError("Error %d while instantiating keccak" % result) self._state = SmartPointer(state.get(), @@ -107,7 +114,8 @@ class Keccak_Hash(object): bfr = create_string_buffer(self.digest_size) result = _raw_keccak_lib.keccak_digest(self._state.get(), bfr, - c_size_t(self.digest_size)) + c_size_t(self.digest_size), + c_ubyte(self._padding)) if result: raise ValueError("Error %d while squeezing keccak" % result) |