# Poly1305

Poly1305 is a fast Carter-Wegman MAC algorithm created by Daniel J. Bernstein. It requires a 32-byte secret key, a 16-byte nonce, and a symmetric cipher. The MAC tag is always 16 bytes long.

Originally, Poly1305 was defined in combination with AES, but it is now most frequently seen used in combination with ChaCha20 and XChaCha20.

This is an example showing how to generate a MAC tag (note how the nonce is automatically generated at random):

    >>> from Crypto.Hash import Poly1305
    >>> from Crypto.Cipher import AES
    >>>
    >>> secret = b'Thirtytwo very very secret bytes'
    >>> mac = Poly1305.new(key=secret, cipher=AES)
    >>> mac.update(b'Hello')
    >>> print("Nonce: ", mac.nonce.hex())
    >>> print("MAC:   ", mac.hexdigest())

This is an example showing how to validate the MAC above:

    >>> from Crypto.Hash import Poly1305
    >>> from Crypto.Cipher import AES
    >>> from binascii import unhexlify
    >>>
    >>> # We have received a message 'msg' together
    >>> # with its MAC 'mac_tag_hex' and the nonce 'nonce_hex'
    >>>
    >>> secret = b'Thirtytwo very very secret bytes'
    >>> nonce = unhexlify(nonce_hex)
    >>> mac = Poly1305.new(key=secret, nonce=nonce, cipher=AES, data=msg)
    >>> try:
    >>>   mac.hexverify(mac_tag_hex)
    >>>   print("The message '%s' is authentic" % msg)
    >>> except ValueError:
    >>>   print("The message or the key is wrong")

Note that you can get the MAC tag in one line:

    >>> binary_tag = Poly1305.new(key=secret, cipher=AES, data=b'Hello').digest()

Or, for a hexadecimal string:

    >>> hex_tag = Poly1305.new(key=secret, cipher=AES, data=b'Hello').hexdigest()

Equivalently, you can verify a tag with a single line:

    >>> Poly1305.new(key=secret, cipher=AES, data=b'Hello').verify(binary_tag)

or:

    >>> Poly1305.new(key=secret, cipher=AES, data=b'Hello').hexverify(hex_tag)

class Crypto.Hash.Poly1305.Poly1305_MAC(r, s, data)

  An Poly1305 MAC object. Do not instantiate directly. Use the `new()` function.

  Variables:

    digest_size (integer) – the size in bytes of the resulting MAC tag

  digest()

    Return the binary (non-printable) MAC tag of the message authenticated so far.

    Returns:

      The MAC tag digest, computed over the data processed so far. Binary form.

    Return type:

      byte string

  hexdigest()

    Return the printable MAC tag of the message authenticated so far.

    Returns:

      The MAC tag, computed over the data processed so far. Hexadecimal encoded.

    Return type:

      string

  hexverify(hex_mac_tag)

    Verify that a given printable MAC (computed by another party) is valid.

    Parameters:

      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.

  update(data)

    Authenticate the next chunk of message.

    Parameters:

      data (byte string/byte array/memoryview) – The next chunk of data

  verify(mac_tag)

    Verify that a given binary MAC (computed by another party) is valid.

    Parameters:

      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.

Crypto.Hash.Poly1305.new(**kwargs)

  Create a new Poly1305 MAC object.

  Parameters:

    - key (bytes/bytearray/memoryview) – The 32-byte key for the Poly1305 object.

    - cipher (module from `Crypto.Cipher`) – The cipher algorithm to use for deriving the Poly1305 key pair (r, s). It can only be `Crypto.Cipher.AES` or `Crypto.Cipher.ChaCha20`.

    - nonce (bytes/bytearray/memoryview) – Optional. The non-repeatable value to use for the MAC of this message. It must be 16 bytes long for `AES` and 8 or 12 bytes for `ChaCha20`. If not passed, a random nonce is created; you will find it in the `nonce` attribute of the new object.

    - data (bytes/bytearray/memoryview) – Optional. The very first chunk of the message to authenticate. It is equivalent to an early call to `update()`.

  Returns:

    A `Poly1305_MAC` object