poly1305.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  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 cryptography import utils
  5. from cryptography.exceptions import (
  6. AlreadyFinalized,
  7. UnsupportedAlgorithm,
  8. _Reasons,
  9. )
  10. class Poly1305(object):
  11. def __init__(self, key: bytes):
  12. from cryptography.hazmat.backends.openssl.backend import backend
  13. if not backend.poly1305_supported():
  14. raise UnsupportedAlgorithm(
  15. "poly1305 is not supported by this version of OpenSSL.",
  16. _Reasons.UNSUPPORTED_MAC,
  17. )
  18. self._ctx = backend.create_poly1305_ctx(key)
  19. def update(self, data: bytes) -> None:
  20. if self._ctx is None:
  21. raise AlreadyFinalized("Context was already finalized.")
  22. utils._check_byteslike("data", data)
  23. self._ctx.update(data)
  24. def finalize(self) -> bytes:
  25. if self._ctx is None:
  26. raise AlreadyFinalized("Context was already finalized.")
  27. mac = self._ctx.finalize()
  28. self._ctx = None
  29. return mac
  30. def verify(self, tag: bytes) -> None:
  31. utils._check_bytes("tag", tag)
  32. if self._ctx is None:
  33. raise AlreadyFinalized("Context was already finalized.")
  34. ctx, self._ctx = self._ctx, None
  35. ctx.verify(tag)
  36. @classmethod
  37. def generate_tag(cls, key: bytes, data: bytes) -> bytes:
  38. p = Poly1305(key)
  39. p.update(data)
  40. return p.finalize()
  41. @classmethod
  42. def verify_tag(cls, key: bytes, data: bytes, tag: bytes) -> None:
  43. p = Poly1305(key)
  44. p.update(data)
  45. p.verify(tag)