Poly1305-AES using GMP and OpenSSL
D. J. Bernstein
Authenticators and signatures
A state-of-the-art message-authentication code
Poly1305-AES using GMP and OpenSSL
poly1305aes_test is an implementation of Poly1305-AES
that uses GMP for integer arithmetic and OpenSSL for AES.
I recommend against using poly1305aes_test
for anything other than tests;
my main reason for publishing it
is to help communicate the definition of Poly1305-AES.
Requirements:
poly1305aes_test
must be compiled with -lcrypto -lgmp.
The system must have
GMP 3 or later (for the mpz_tdiv_q_ui return value).
The system must also have
OpenSSL 0.9.7 or later (for AES_encrypt).
Here are the poly1305aes_test files:
Here are various tests:
- test-constanttime.c
checks, for various pairs of arrays,
that constanttime_isequal produces nonzero
exactly when memcmp produces zero.
Expected output: None.
- test-aes.c
prints the output of aes_openssl
for a standard selection of 400 inputs.
Expected output:
test-aes.out.
- test-poly1305aes.c
prints authenticators produced by poly1305aes_authenticate
for every message length from 0 bytes through 1000 bytes.
It also checks that poly1305aes_verify
accepts the authenticators,
and that poly1305aes_verify
does not accept various modified versions of the authenticators.
The keys, nonces, and messages are various functions
of previous authenticators.
Expected first 10010 lines of output (10 loops):
test-poly1305aes.out.
MD5 checksum of first 123456 lines of output:
707212358360ae459bc0ef293a5354e8.
MD5 checksum of first 1234567 lines of output:
3b2bc877e4e64efbfe39945ac102c768.
MD5 checksum of first 12345678 lines of output:
ef3831c8b2087ebf6844f2265e1da2c2.
MD5 checksum of first 123456789 lines of output:
5e29ea7450475dc419a0f95afde0cfdc.
MD5 checksum of complete output (1001000000 lines):
3ceb64843c00984c5c2b7897f499141b.
The most obvious difference between
poly1305aes_test
and a serious Poly1305-AES implementation such as
poly1305aes_sparc
is that a serious implementation is much faster.
poly1305aes_test_verify takes about
140000 UltraSPARC-III cycles (or 150000 Pentium-M cycles)
for a 1024-byte message,
for example,
and 14000 UltraSPARC-III cycles (or 11000 Pentium-M cycles)
for a 16-byte message;
poly1305aes_sparc_verify takes only about
5600 UltraSPARC-III cycles for a 1024-byte message
and only about 850 UltraSPARC-III cycles for a 16-byte message.
A less obvious difference between
poly1305aes_test
and a serious Poly1305-AES implementation
is that, inside poly1305aes_test,
GMP allocates memory and will kill the program if it fails.
It's hard to use GMP safely in a typical server that needs to keep running.
The only memory allocated by a serious implementation
is a small, constant, easily pre-provisioned amount of stack space.