Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hashes.py 5.0KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. # This file is dual licensed under the terms of the Apache License, Version
  2. # 2.0, and the BSD License. See the LICENSE file in the root of this repository
  3. # for complete details.
  4. from __future__ import annotations
  5. import abc
  6. import typing
  7. from cryptography.hazmat.bindings._rust import openssl as rust_openssl
  8. __all__ = [
  9. "HashAlgorithm",
  10. "HashContext",
  11. "Hash",
  12. "ExtendableOutputFunction",
  13. "SHA1",
  14. "SHA512_224",
  15. "SHA512_256",
  16. "SHA224",
  17. "SHA256",
  18. "SHA384",
  19. "SHA512",
  20. "SHA3_224",
  21. "SHA3_256",
  22. "SHA3_384",
  23. "SHA3_512",
  24. "SHAKE128",
  25. "SHAKE256",
  26. "MD5",
  27. "BLAKE2b",
  28. "BLAKE2s",
  29. "SM3",
  30. ]
  31. class HashAlgorithm(metaclass=abc.ABCMeta):
  32. @property
  33. @abc.abstractmethod
  34. def name(self) -> str:
  35. """
  36. A string naming this algorithm (e.g. "sha256", "md5").
  37. """
  38. @property
  39. @abc.abstractmethod
  40. def digest_size(self) -> int:
  41. """
  42. The size of the resulting digest in bytes.
  43. """
  44. @property
  45. @abc.abstractmethod
  46. def block_size(self) -> typing.Optional[int]:
  47. """
  48. The internal block size of the hash function, or None if the hash
  49. function does not use blocks internally (e.g. SHA3).
  50. """
  51. class HashContext(metaclass=abc.ABCMeta):
  52. @property
  53. @abc.abstractmethod
  54. def algorithm(self) -> HashAlgorithm:
  55. """
  56. A HashAlgorithm that will be used by this context.
  57. """
  58. @abc.abstractmethod
  59. def update(self, data: bytes) -> None:
  60. """
  61. Processes the provided bytes through the hash.
  62. """
  63. @abc.abstractmethod
  64. def finalize(self) -> bytes:
  65. """
  66. Finalizes the hash context and returns the hash digest as bytes.
  67. """
  68. @abc.abstractmethod
  69. def copy(self) -> HashContext:
  70. """
  71. Return a HashContext that is a copy of the current context.
  72. """
  73. Hash = rust_openssl.hashes.Hash
  74. HashContext.register(Hash)
  75. class ExtendableOutputFunction(metaclass=abc.ABCMeta):
  76. """
  77. An interface for extendable output functions.
  78. """
  79. class SHA1(HashAlgorithm):
  80. name = "sha1"
  81. digest_size = 20
  82. block_size = 64
  83. class SHA512_224(HashAlgorithm): # noqa: N801
  84. name = "sha512-224"
  85. digest_size = 28
  86. block_size = 128
  87. class SHA512_256(HashAlgorithm): # noqa: N801
  88. name = "sha512-256"
  89. digest_size = 32
  90. block_size = 128
  91. class SHA224(HashAlgorithm):
  92. name = "sha224"
  93. digest_size = 28
  94. block_size = 64
  95. class SHA256(HashAlgorithm):
  96. name = "sha256"
  97. digest_size = 32
  98. block_size = 64
  99. class SHA384(HashAlgorithm):
  100. name = "sha384"
  101. digest_size = 48
  102. block_size = 128
  103. class SHA512(HashAlgorithm):
  104. name = "sha512"
  105. digest_size = 64
  106. block_size = 128
  107. class SHA3_224(HashAlgorithm): # noqa: N801
  108. name = "sha3-224"
  109. digest_size = 28
  110. block_size = None
  111. class SHA3_256(HashAlgorithm): # noqa: N801
  112. name = "sha3-256"
  113. digest_size = 32
  114. block_size = None
  115. class SHA3_384(HashAlgorithm): # noqa: N801
  116. name = "sha3-384"
  117. digest_size = 48
  118. block_size = None
  119. class SHA3_512(HashAlgorithm): # noqa: N801
  120. name = "sha3-512"
  121. digest_size = 64
  122. block_size = None
  123. class SHAKE128(HashAlgorithm, ExtendableOutputFunction):
  124. name = "shake128"
  125. block_size = None
  126. def __init__(self, digest_size: int):
  127. if not isinstance(digest_size, int):
  128. raise TypeError("digest_size must be an integer")
  129. if digest_size < 1:
  130. raise ValueError("digest_size must be a positive integer")
  131. self._digest_size = digest_size
  132. @property
  133. def digest_size(self) -> int:
  134. return self._digest_size
  135. class SHAKE256(HashAlgorithm, ExtendableOutputFunction):
  136. name = "shake256"
  137. block_size = None
  138. def __init__(self, digest_size: int):
  139. if not isinstance(digest_size, int):
  140. raise TypeError("digest_size must be an integer")
  141. if digest_size < 1:
  142. raise ValueError("digest_size must be a positive integer")
  143. self._digest_size = digest_size
  144. @property
  145. def digest_size(self) -> int:
  146. return self._digest_size
  147. class MD5(HashAlgorithm):
  148. name = "md5"
  149. digest_size = 16
  150. block_size = 64
  151. class BLAKE2b(HashAlgorithm):
  152. name = "blake2b"
  153. _max_digest_size = 64
  154. _min_digest_size = 1
  155. block_size = 128
  156. def __init__(self, digest_size: int):
  157. if digest_size != 64:
  158. raise ValueError("Digest size must be 64")
  159. self._digest_size = digest_size
  160. @property
  161. def digest_size(self) -> int:
  162. return self._digest_size
  163. class BLAKE2s(HashAlgorithm):
  164. name = "blake2s"
  165. block_size = 64
  166. _max_digest_size = 32
  167. _min_digest_size = 1
  168. def __init__(self, digest_size: int):
  169. if digest_size != 32:
  170. raise ValueError("Digest size must be 32")
  171. self._digest_size = digest_size
  172. @property
  173. def digest_size(self) -> int:
  174. return self._digest_size
  175. class SM3(HashAlgorithm):
  176. name = "sm3"
  177. digest_size = 32
  178. block_size = 64