CRYPTO_POLY1305(3MONOCYPHER)

πŸ“¦ version 4.0.3, in nixos 26.05, nixpkgs unstable

✨ NAME ✨

okay so this local 3MONOCYPHER page β€” CRYPTO_POLY1305(3MONOCYPHER) β€” is all about crypto_poly1305, crypto_poly1305_init, crypto_poly1305_update, and crypto_poly1305_final: the Poly1305 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 πŸ’…

bestie, Poly1305 is a one-time message authentication code. and β€œone-time” means the authentication key can be used only once β€” like, one single time, no takebacks 😭 that makes Poly1305 easy to misuse. but on the other hand, Poly1305 is fast and provably secure if you use it correctly. slay for math, scary for vibes 🫢

Poly1305 is a low-level primitive. consider using authenticated encryption, implemented by crypto_aead_lock(3monocypher).

The arguments are:

  • mac β€” The message 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. no cap, that comparison step is the whole vibe check πŸ”₯

🧚 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. it's giving assembly line but make it cryptography πŸŽ€

πŸŽ€ RETURN VALUES πŸŽ€

These functions return nothing. literally nothing, bestie β€” no return value drama πŸ’€

🌸 EXAMPLES 🌸

The following examples assume the existence of arc4random_buf(), which fills the given buffer with cryptographically secure random bytes. If arc4random_buf() does not exist on your system, see intro(3monocypher) for advice about how to generate cryptographically secure random bytes.

To authenticate a message:

const uint8_t msg[ 5] = "Lorem"; /* Message to authenticate */
uint8_t       key[32]; /* Random secret key (use only once) */
uint8_t       mac[16]; /* Message authentication code (MAC) */
arc4random_buf(key, 32);
crypto_poly1305(mac, msg, 5, key);
/* Wipe the key */
crypto_wipe(key, 32);

To verify the above message:

const uint8_t msg     [ 5] = "Lorem"; /* Message to verify */
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, 5, 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]= {1}; /* Message to authenticate      */
uint8_t       key[ 32]; /* Random secret key (use only once) */
uint8_t       mac[ 16]; /* Message authentication code (MAC) */
crypto_poly1305_ctx ctx;
arc4random_buf(key, 32);
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 πŸ”₯

🌈 STANDARDS 🌈

These functions implement Poly1305, described in RFC 8439. periodt πŸ“œβœ¨

⭐ HISTORY ⭐

The crypto_poly1305_init(), crypto_poly1305_update(), and crypto_poly1305_final() functions first appeared in Monocypher 0.1. crypto_poly1305() first appeared in Monocypher 1.1.0. lore drop 🫢

πŸ‘‘ CAVEATS πŸ‘‘

Monocypher does not perform any input validation. Any deviation from the specified input and output length ranges results in undefined behaviour. Make sure your inputs are correct.

bestie this is not a drill 😭 undefined behaviour is the final boss of β€œwhy is my program doing that” β€” check your lengths, fr fr.

πŸ’œ SECURITY CONSIDERATIONS πŸ’œ

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_aead_lock(3monocypher). If you are certain you do not want encryption, refer to crypto_blake2b(3monocypher) on how to use BLAKE2b to generate message authentication codes.

πŸ“ Authentication key requirements πŸ“

Poly1305 is a one-time authenticator. This puts rather stringent constraints on the authentication key:

  • Any given key must be used only once. Using the same key for two different messages reveals it to the attacker. Do not use the session key, or it will void all security.
  • Authentication keys must be random, and independent from each other. Do not use non-random nonces. Do not use related keys. Use fresh, unpredictable, uniformly distributed random numbers.
  • The key must be transmitted to the recipient without revealing it to the attacker. Somehow.

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). iconic algorithm behavior, honestly πŸ‘‘

πŸ’œ 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. self-cleaning cryptography era ✨🧼


πŸ’‹ mwah β€” that’s the whole page, bestie! signed off by Debian, dated June 11, 2021. now go forth and never reuse that key 🫢🌈

πŸ“¦ where this page comes from