Authenticated Encryption

Authenticated Encryption allows you to make sure that the received ciphertext hasn’t been tampered with by attaching and verifying a MAC (Message Authentication Code) along with the encrypted ciphertext.

from monocypher.utils import random
from monocypher.secret import SecretBox

key = random(SecretBox.KEY_SIZE)
box = SecretBox(key)
# Automatically generated nonce, similar to Box
ciphertext = box.encrypt(b'my message')

# send ciphertext to someone else

# later on ... (key must be the same!)
box = SecretBox(key)
assert box.decrypt(ciphertext) == b'my message'

Reference

class monocypher.secret.SecretBox(key)

Encrypts messages using XChacha20, and authenticates them using Poly1305. The key parameter can be produced in different ways, e.g. via key exchange (e.g. Box), or password key derivation (argon2i()).

Parameters:

key – A bytes object of length KEY_SIZE.

encode()

Returns the encryption key as bytes.

Return type:

bytes

KEY_SIZE = 32

Length of a valid key in bytes.

MAC_SIZE = 16

Length of a valid MAC in bytes.

NONCE_SIZE = 24

Length of a valid nonce in bytes.

decrypt(ciphertext, nonce=None)

Wrapper around decrypt_raw() that decrypts the given ciphertext, using the given nonce if supplied; otherwise it is extracted from the ciphertext. The MAC should be part of the ciphertext (see the encryption format in EncryptedMessage).

Parameters:
  • ciphertext – A bytes-like object or EncryptedMessage.

  • nonce – Optional nonce if it isn’t included in the ciphertext.

Return type:

bytes

decrypt_raw(ciphertext, nonce, mac)

Decrypt the given ciphertext, nonce, and mac. If the decryption is successful, the plaintext message is returned. Otherwise a CryptoError is raised.

Parameters:
  • ciphertext – Detached ciphertext to decrypt (bytes).

  • nonce – The nonce, a bytes object of length NONCE_SIZE.

  • mac – The MAC, a bytes object of length MAC_SIZE.

Return type:

bytes

encrypt(msg, nonce=None)

Encrypt the given message msg, optionally with a specified nonce. If the given nonce is None, then it is automatically generated. See EncryptedMessage for details on how the encrypted message is encoded.

Parameters:
  • msg – Message to encrypt (a bytes-like object).

  • nonce – Optional bytes object of length NONCE_SIZE.

Return type:

EncryptedMessage

class monocypher.secret.EncryptedMessage

A bytes subclass representing an encrypted message. By default, monocypher-python represents encrypted and authenticated messages as nonce + mac + ciphertext, i.e.:

>>> msg = sbox.encrypt(b'...')
>>> msg == msg.nonce + msg.detached_mac + msg.detached_ciphertext
True
property ciphertext

Returns the concatenated mac and ciphertext. This is equivalent to concatenating detached_mac and detached_ciphertext. This can be passed to SecretBox.decrypt() separately from nonce:

>>> msg = sbox.encrypt(b'...')
>>> sbox.decrypt(msg.ciphertext, msg.nonce)
b'...'
Return type:

bytes

property detached_ciphertext

Returns the detached ciphertext. This is different from ciphertext, since the former returns the mac and the encryption. Just sending this (e.g. to save space) is not recommended since you will not be sure if the encryption has been tampered with.

Return type:

bytes

property detached_mac

Returns the detached mac.

Return type:

bytes

property nonce

Returns the nonce.

Return type:

bytes

exception monocypher.secret.CryptoError

Extras

The SecretBox class, and by extension Box implements equality (between objects of the same type) and conversion to bytes, as well as hashing:

>>> key = random(SecretBox.KEY_SIZE)
>>> sbox = SecretBox(key)
>>> sbox == SecretBox(key)
False
>>> bytes(sbox) == key
True
>>> hash(sbox)
...

Implementation

SecretBox uses the crypto_lock functions from Monocypher, which implement RFC 8439 (ChaCha20 and Poly1305 for IETF Protocols), using XChaCha20 instead of ChaCha20.