Skip to main content

Python wrapper for Poly1305aes HMAC

Project description


Python extension module wrapping poly1305aes by Daniel Bernstein

This module is a simple wrapper around the poly1305aes HMAC algorithm by Daniel J. Bernstein (

What is a HMAC (Hash-based Message Authentication Code)?

From wikipedia (

In cryptography, a keyed-hash message authentication code (HMAC) is a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret cryptographic key. As with any MAC, it may be used to simultaneously verify both the data integrity and the authentication of a message. Any cryptographic hash function, such as MD5 or SHA-1, may be used in the calculation of an HMAC; the resulting MAC algorithm is termed HMAC-MD5 or HMAC-SHA1 accordingly. The cryptographic strength of the HMAC depends upon the cryptographic strength of the underlying hash function, the size of its hash output, and on the size and quality of the key.

What is poly1305?


Poly1305-AES is a state-of-the-art secret-key message-authentication code suitable for a wide variety of applications. Poly1305-AES computes a 16-byte authenticator of a message of any length, using a 16-byte nonce (unique message number) and a 32-byte secret key. Attackers can’t modify or forge messages if the message sender transmits an authenticator along with each message and the message receiver checks each authenticator.

Poly1305-AES has several useful features:

  • Guaranteed security if AES is secure. There’s a theorem guaranteeing that the security gap is extremely small (n/2^(102) per forgery attempt for 16n-byte messages) even for long-term keys (2^64 messages). The only way for an attacker to break Poly1305-AES is to break AES.
  • Cipher replaceability. If anything does go wrong with AES, users can switch from Poly1305-AES to Poly1305-AnotherFunction, with an identical security guarantee.
  • Extremely high speed. My Poly1305-AES software takes just 3843 Athlon cycles, 5361 Pentium III cycles, 5464 Pentium 4 cycles, 4611 Pentium M cycles, 8464 PowerPC 7410 cycles, 5905 PowerPC RS64 IV cycles, 5118 UltraSPARC II cycles, or 5601 UltraSPARC III cycles to verify an authenticator on a 1024-byte message. Poly1305-AES offers consistent high speed, not just high speed for one favored CPU.
  • Low per-message overhead. My Poly1305-AES software takes just 1232 Pentium 4 cycles, 1264 PowerPC 7410 cycles, or 1077 UltraSPARC III cycles to verify an authenticator on a 64-byte message. Poly1305-AES offers consistent high speed, not just high speed for long messages. Most competing functions are designed for long messages and don’t pay attention to short-packet performance.
  • Key agility. Poly1305-AES can fit thousands of simultaneous keys into cache, and remains fast even when keys are out of cache. Poly1305-AES offers consistent high speed, not just high speed for single-key benchmarks. Almost all competing functions use a large table for each key; as the number of keys grows, those functions miss the cache and slow down dramatically.
  • Parallelizability and incrementality. Poly1305-AES can take advantage of additional hardware to reduce the latency for long messages, and can be recomputed at low cost for a small modification of a long message.
  • No intellectual-property claims. I am not aware of any patents or patent applications relevant to Poly1305-AES.
  • Guaranteed security, cipher replaceability, and parallelizability are provided by the standard polynomial-evaluation Wegman-Carter-MAC framework. Within that framework, hash127-AES achieved extremely high speed at the expense of a large table for each key.
  • The big advantage of Poly1305-AES is key agility: extremely high speed without any key expansion. Other standard MACs are slower and less secure than Poly1305-AES. Specifically, HMAC-MD5 is slower and doesn’t have a comparable security guarantee; CBC-MAC-AES is much slower and has a weaker security guarantee. Both HMAC-MD5 and CBC-MAC-AES are breakable within 2^64 messages.


Following D.J. Bernstein’s code license, this code is also released into the public domain. See LICENSE file.

The ‘c’ directory contains the unmodified source code for poly1305aes from


from poly1305_aes import (
    get_key, authenticate, verify
msg = 'Hello world'
kr = get_key()
auth = authenticate(kr, msg)

bad_kr = get_key()
bad_auth = authenticate(kr, msg + '1')
bad_msg = msg + '1'

print('Good: %s\nBad auth: %s\nBad kr: %s\nBad msg: %s' % (
    str(verify(auth, kr, msg)),
    str(verify(bad_auth, kr, msg)),
    str(verify(auth, bad_kr, msg)),
    str(verify(auth, kr, bad_msg))

Alternately, run the test script that is shipped:

python -m poly1305_aes.test

To run a simple benchmark:

python -m poly1305_aes.benchmark


Using pip:

pip install 'git+'


python install



  • Python: Tested on 2.7.6, 3.4.3, pypy 2.7.10 (pypy 4.0.1)
  • cffi >= 1.0.0
  • six - Python.h (libpython-dev on Debian-like systems)
  • gcc (build-essential on Debian-like systems)


Dan Bernsteins code contains optimizations for:

  • x86 (Intel)
  • x86 (Pentium Pro)
  • x86 (Athlon)
  • UltraSparc II and III
  • PowerPC, PPC64

My code only supports generic x86. To support the additional platforms will require:

  • Detect CPU type accurately
  • Change c_src_files in based on CPU type
  • Change c_hdr in based on CPU type
  • Change get_key(), authenticate() and verify() to call different functions in shared
  • Test on the different CPUs (I only have access to x86!)

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

poly1305_aes-0.13.39.tar.gz (216.6 kB view hashes)

Uploaded source

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page