# One-time authentication

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 an inauthentic message.

Poly1305 keys have to be:

* secret. An attacker can compute a valid authentication tag for any message, for any given key. The security of Poly1305 relies on the fact that attackers don’t know the key being used to compute the tag. This implies that they have to be:
* unpredictable. Do not use timestamps or counters.
* unique. Never reuse a key. A new key is required for every single message. The key can be recovered if two messages are authenticated with the same key.

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

```c
#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

```c
#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

```c
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).

```c
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

```c
int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
                            const unsigned char *key);
```

```c
int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
                              const unsigned char *in,
                              unsigned long long inlen);
```

```c
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()`.

```c
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

* `crypto_onetimeauth_BYTES`
* `crypto_onetimeauth_KEYBYTES`

## Data types

* `crypto_onetimeauth_state`

## Algorithm details

* Poly1305
