Secret-key single-message authentication using Poly1305

One-time authentication in Sodium uses Poly1305, a Wegman-Carter authenticator designed by D. J. Bernstein.

Poly1305 takes a 32-byte, one-time key and a message and produces a 16-byte tag that authenticates the message such that an attacker has a negligible chance of producing a valid tag for a inauthentic message.

Poly1305 keys have to be:

The standard way to use Poly1305 is to derive a dedicated subkey from a (key, nonce) tuple, for example by taking the first bytes generated by a stream cipher.

Due to its output size, Poly1305 is recommended for online protocols, exchanging many small messages, rather than for authenticating very large files.

Finally, Poly1305 is not a replacement for a hash function.

Single-part example

#define MESSAGE ((const unsigned char *) "Data to authenticate")
#define MESSAGE_LEN 20

unsigned char out[crypto_onetimeauth_BYTES];
unsigned char key[crypto_onetimeauth_KEYBYTES];

crypto_onetimeauth_keygen(key);
crypto_onetimeauth(out, MESSAGE, MESSAGE_LEN, key);

if (crypto_onetimeauth_verify(out, MESSAGE, MESSAGE_LEN, key) != 0) {
    /* message forged! */
}

Multi-part example

#define MESSAGE1 ((const unsigned char *) "Multi-part")
#define MESSAGE1_LEN 10
#define MESSAGE2 ((const unsigned char *) "data")
#define MESSAGE2_LEN 4

unsigned char out[crypto_onetimeauth_BYTES];
unsigned char key[crypto_onetimeauth_KEYBYTES];
crypto_onetimeauth_state state;

crypto_onetimeauth_keygen(key);

crypto_onetimeauth_init(&state, key);
crypto_onetimeauth_update(&state, MESSAGE1, MESSAGE1_LEN);
crypto_onetimeauth_update(&state, MESSAGE2, MESSAGE2_LEN);
crypto_onetimeauth_final(&state, out);

Usage

Single-part interface

int crypto_onetimeauth(unsigned char *out, const unsigned char *in,
                       unsigned long long inlen, const unsigned char *k);

The crypto_onetimeauth() function authenticates a message in whose length is inlen using a secret key k (crypto_onetimeauth_KEYBYTES bytes) and puts the authenticator into out (crypto_onetimeauth_BYTES bytes).

int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
                              unsigned long long inlen, const unsigned char *k);

The crypto_onetimeauth_verify() function verifies, in constant time, that h is a correct authenticator for the message in whose length is inlen bytes, using the secret key k.

It returns -1 if the verification fails, or 0 on success.

Multi-part (streaming) interface

int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
                            const unsigned char *key);
int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);
int crypto_onetimeauth_final(crypto_onetimeauth_state *state,
                             unsigned char *out);

The crypto_onetimeauth_init() function initializes a structure pointed by state using a key key.

A 16 bytes alignment is required for the address of state. The size of this value can be obtained using sizeof(crypto_onetimeauth_state), or crypto_onetimeauth_statebytes().

crypto_onetimeauth_update() can then be called more than one in order to compute the authenticator from sequential chunks of the message.

Finally, crypto_onetimeauth_final() puts the authenticator into out.

The state must be initialized with crypto_onetimeauth_init() before updating or finalizing it.

After crypto_onetimeauth_final() returns, the state should not be used any more, unless it is reinitialized using crypto_onetimeauth_init().

void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]);

The crypto_onetimeauth_keygen() function fills k with a random key. This convenience function was introduced in libsodium 1.0.12.

Constants

Data types

Algorithm details