CRYPTO_POLY1305_AUTH(3MONOCYPHER) 3MONOCYPHER CRYPTO_POLY1305_AUTH(3MONOCYPHER)

NAME

crypto_poly1305, crypto_poly1305_init, crypto_poly1305_update, crypto_poly1305_finalPoly1305 one-time message authentication codes

SYNOPSIS

#include <monocypher.h>
void
crypto_poly1305(uint8_t mac[16], const uint8_t *message, size_t message_size, const uint8_t key[32]);
void
crypto_poly1305_init(crypto_poly1305_ctx *ctx, const uint8_t key[32]);
void
crypto_poly1305_update(crypto_poly1305_ctx *ctx, const uint8_t *message, size_t message_size);
void
crypto_poly1305_final(crypto_poly1305_ctx *ctx, uint8_t mac[16]);

DESCRIPTION

Poly1305 is a one-time message authentication code. "One-time" means the authentication key can be used only once. This makes Poly1305 easy to misuse. On the other hand, Poly1305 is fast, and provably secure if used correctly.
Poly1305 is a low-level primitive. Consider using authenticated encryption, implemented by crypto_lock(3monocypher).
The arguments are:
 
 
mac
The authentication code.
 
 
key
The secret authentication key. Use only once per message. Do not use the session key to authenticate messages. It should be wiped with crypto_wipe(3monocypher) after use.
 
 
message
The message to authenticate. May overlap with the mac argument.
 
 
message_size
Length of message, in bytes.

Direct interface

crypto_poly1305() produces a message authentication code for the given message and authentication key. To verify the integrity of a message, use crypto_verify16(3monocypher) to compare the received MAC to the output mac.

Incremental interface

crypto_poly1305_init() initialises a context. key should be wiped once the context is initialised. Then, crypto_poly1305_update() authenticates the message chunk by chunk. Once the message is entirely processed, crypto_poly1305_final() yields the message authentication code.

RETURN VALUES

These functions return nothing. They cannot fail.

EXAMPLES

To authenticate a message:
const uint8_t msg[500]; /* Message to authenticate           */ 
const uint8_t key[ 32]; /* Random secret key (use only once) */ 
uint8_t       mac[ 16]; /* Message authentication code (MAC) */ 
crypto_poly1305(mac, msg, 500, key); 
/* Wipe the key */ 
crypto_wipe(key, 32);
To verify the above message:
const uint8_t msg     [500]; /* Message to verify */ 
const uint8_t key     [ 32]; /* The above key     */ 
const uint8_t mac     [ 16]; /* The above MAC     */ 
uint8_t       real_mac[ 16]; /* The actual MAC    */ 
crypto_poly1305(real_mac, msg, 500, key); 
/* Wipe the key */ 
crypto_wipe(key, 32); 
if (crypto_verify16(mac, real_mac)) { 
    /* Corrupted message, abort processing */ 
} else { 
    /* Genuine message */ 
} 
/* The real mac is secret.  Wipe it */ 
crypto_wipe(real_mac, 16);
Incremental authentication:
const uint8_t msg[500]; /* Message to authenticate           */ 
const uint8_t key[ 32]; /* Random secret key (use only once) */ 
uint8_t       mac[ 16]; /* Message authentication code (MAC) */ 
crypto_poly1305_ctx ctx; 
crypto_poly1305_init(&ctx, key); 
/* Wipe the key */ 
crypto_wipe(key, 32); 
for (int i = 0; i < 500; i += 100) { 
    crypto_poly1305_update(&ctx, msg, 100); 
} 
crypto_poly1305_final(&ctx, mac);

SEE ALSO

crypto_blake2b(3monocypher), crypto_lock(3monocypher), crypto_verify16(3monocypher), intro(3monocypher)

STANDARDS

These functions implement Poly1305, described in RFC 7539.

SECURITY CONSIDERATIONS

User error

Poly1305 is difficult to use correctly. Do not use it unless you are absolutely sure what you are doing. Use authenticated encryption instead; see crypto_lock(3monocypher). If you are absolutely certain you do not want encryption, refer to crypto_blake2b(3monocypher) on how to use Blake2b to generate message authentication codes.
If you still want to use Poly1305, keep in mind that it is very easy to make mistakes that destroy all security. The requirements for the key are stringent: it must be secret, shared, and unique. The attacker must not be able to guess the key; it must be shared with the recipient to allow verification; and it must be used only once. If it is ever reused, the attacker can easily recover it and then forge arbitrary messages.
Session keys cannot be used for this. They are shared and secret, but would be reused when sending multiple messages. Random numbers cannot be used either as there is no reasonable way to share them with the recipient without also revealing them to the attacker.
The only practical source for the authentication key is a chunk of the encryption stream used to encrypt the message. That chunk must be dedicated to the authentication key: if it is reused to encrypt the message itself, the attacker may recover that chunk by guessing the message, then forge arbitrary messages.
To get this right, you need a session key, a unique nonce, and a stream cipher. Generate a stream with the session key and nonce. Take the first 32 bytes of that stream as your authentication key, then use the rest of the stream to encrypt your message. This is the approach used by crypto_aead_lock(3monocypher).

Protection against side channels

Use crypto_verify16(3monocypher) to compare message authentication codes. Avoid standard buffer comparison functions. They may not run in constant time, enabling an attacker to exploit timing attacks to recover the MAC.
The authentication key should be wiped with crypto_wipe(3monocypher) after use.
The incremental interface automatically wipes its context when finished so users do not need to do it themselves.
December 28, 2017 Linux 4.4.0-116-generic