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.
#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! */
}
#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);
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.
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.
crypto_onetimeauth_BYTES
crypto_onetimeauth_KEYBYTES
crypto_onetimeauth_state