crypto_poly1305_auth,
crypto_poly1305_init,
crypto_poly1305_update,
crypto_poly1305_final —
Poly1305 one-time message authentication
codes
#include
<monocypher.h>
void
crypto_poly1305_auth(
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,
const uint8_t mac[16]);
Monocypher provides both a direct interface and an incremental interface for
Poly1305, which is used to generate a one-time message authentication code
(MAC).
Poly1305 is easy to mess up. Using it
directly is likely to lead to mistakes.
Be careful when using this function. The requirements for a Poly1305 key are
stringent:
- It must be secret: the attacker cannot be allowed to
guess that key.
- It must be shared: the recipient must know this key.
Without it, the integrity of the message cannot be verified.
- It must never be reused.
That would allow the attacker to recover the key then forge messages,
destroying any security.
You cannot use the session key for this: it is secret and shared, but it is
reused. If you use it, the attacker will recover
it as soon as the second message is sent, and will break all security.
You cannot use a random number: if you do not send it over the network, it will
not be shared, and the recipient will be unable to check the MAC. If you do,
it will not be secret, and the attacker will be able to forge messages.
The only practical source for the authentication key is a chunk of the
encryption stream used to encrypt the message. However, you must ensure you do
not reuse that part of the stream to encrypt the message itself: the attacker
could guess the stream by guessing the message, and forge messages afterwards.
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 bits of that stream as your authentication key, then use the
rest of the stream to encrypt your message. Check
out the source code of
crypto_aead_lock(3monocypher)
to see how it is done.
The direct interface consists of the
crypto_poly1305_auth() function produces a
message authentication code for the given message and authentication key. The
mac and the
message arguments may overlap.
The indirect interface consists of the
crypto_poly1305_init(),
crypto_poly1305_update(), and
crypto_poly1305_final() functions. The
crypto_poly1305_init() function initialises a
context, and the
crypto_poly1305_update()
function authenticates the message chunk by chunk. Once the message is
entirely processed, the
crypto_poly1305_final()
function yields the message authentication code.
Use
crypto_verify16(3monocypher)
to compare the MAC received to the output
mac.
These functions return nothing. They cannot fail.
crypto_blake2b(3monocypher),
crypto_lock(3monocypher),
crypto_verify16(3monocypher),
intro(3monocypher)
Using Poly1305 correctly is very difficult. Please 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),
which contains information on how to use Blake2b to generate message
authentication codes.
These functions implement Poly1305.