Cobblestone (streaming symmetric encryption)

Cobblestone provides authenticated symmetric encryption of large messages — up to 4 PiB — as a stream, without ever holding the whole message in memory. It is an implementation of the C2SP chunked-encryption specification’s two named instantiations: Cobblestone-128 (SHA-512 and AES-128-GCM, the recommended choice) and Cobblestone-256 (SHA-512 and AES-256-GCM, for environments that mandate 256-bit keys).

>>> from cryptography.cobblestone import (
...     Cobblestone128Decryptor, Cobblestone128Encryptor
... )
>>> key = Cobblestone128Encryptor.generate_key()
>>> encryptor = Cobblestone128Encryptor(
...     key, context=b"example-app file encryption"
... )
>>> ciphertext = encryptor.update(b"a secret message")
>>> ciphertext += encryptor.finalize()
>>> decryptor = Cobblestone128Decryptor(
...     key, context=b"example-app file encryption"
... )
>>> decryptor.update(ciphertext) + decryptor.finalize()
b'a secret message'
class cryptography.cobblestone.Cobblestone128Encryptor(key, context)

Added in version 50.0.0.

Encrypts a single message under key with Cobblestone-128. Each instance must be used for exactly one message: call update() (or update_into()) any number of times, then call finalize() exactly once. The concatenation of the returned bytes is the ciphertext.

Parameters:
  • key (bytes-like) – A 16-byte key. This must be kept secret, and must be uniformly random (e.g. the output of generate_key() — never a password). A single key may be used to encrypt a practically unlimited number of messages.

  • context (bytes-like) – Application-provided context, bound to the ciphertext. Decryption fails unless the same value is passed to Cobblestone128Decryptor. It is not secret, may be empty, and is not part of the ciphertext, so it must be available to the decrypting party independently. It can be used for domain separation, e.g. b"myapp v2 backup encryption".

Raises:

ValueError – If key is not 16 bytes.

static generate_key()

Generates a fresh 16-byte key.

Return bytes:

A new key.

update(data)

Encrypts data. Data is internally buffered into 16 KiB chunks, so between 0 and len(data) + 16 KiB bytes of ciphertext are returned.

Parameters:

data (bytes-like) – The data to encrypt.

Return bytes:

The next portion of the ciphertext.

update_into(data, buf)

Encrypts data, writing the resulting ciphertext into buf, and returns the number of bytes written. This avoids allocating a new buffer for each call.

Parameters:
  • data (bytes-like) – The data to encrypt.

  • buf (bytes-like) – A writable buffer to write the ciphertext into. A buffer of len(data) + len(data) // 1024 + 16456 bytes is always large enough.

Return int:

The number of bytes written to buf.

Raises:

ValueError – If buf is too small.

finalize()

Encrypts the final chunk and returns the last portion of the ciphertext. This must always be called, and the instance cannot be used afterwards.

Return bytes:

The remainder of the ciphertext.

Raises:

cryptography.exceptions.AlreadyFinalized – If finalize has already been called.

class cryptography.cobblestone.Cobblestone128Decryptor(key, context)

Added in version 50.0.0.

Decrypts a single message encrypted by Cobblestone128Encryptor with the same key and context. Call update() (or update_into()) with the ciphertext any number of times, then call finalize() exactly once. The concatenation of the returned bytes is the plaintext.

Any returned plaintext is authenticated, but until finalize() returns successfully the message could still turn out to be truncated: an application acting on streamed plaintext before that point must be prepared to discard its work if a later call raises InvalidTag.

Once any method raises InvalidTag, the instance is permanently unusable and all further calls raise AlreadyFinalized.

Parameters:
  • key (bytes-like) – The 16-byte key the message was encrypted with.

  • context (bytes-like) – The context value the message was encrypted with.

Raises:

ValueError – If key is not 16 bytes.

update(data)

Processes data, which need not be aligned to any boundary, and returns the plaintext of all complete chunks that have been authenticated so far.

Parameters:

data (bytes-like) – The next portion of the ciphertext.

Return bytes:

The next portion of the plaintext.

Raises:

cryptography.exceptions.InvalidTag – If the ciphertext was encrypted with a different key or context, or has been modified.

update_into(data, buf)

Like update, but writes the plaintext into buf and returns the number of bytes written.

Parameters:
  • data (bytes-like) – The next portion of the ciphertext.

  • buf (bytes-like) – A writable buffer to write the plaintext into. A buffer of len(data) + 16400 bytes is always large enough.

Return int:

The number of bytes written to buf.

Raises:
  • ValueError – If buf is too small.

  • cryptography.exceptions.InvalidTag – If the ciphertext was encrypted with a different key or context, or has been modified. Note that in this case unauthenticated data may have been written to buf and must not be used.

finalize()

Decrypts and authenticates the final chunk, verifying that the entire message has been processed, and returns the final portion of the plaintext. This must always be called: a successful return is what guarantees the complete message was authentic and not truncated.

Return bytes:

The remainder of the plaintext.

Raises:
class cryptography.cobblestone.Cobblestone256Encryptor(key, context)

Added in version 50.0.0.

Exactly like Cobblestone128Encryptor, but implements Cobblestone-256: the key is 32 bytes and messages are encrypted with AES-256-GCM. Use this when a 256-bit key is mandated; otherwise Cobblestone-128 is recommended.

class cryptography.cobblestone.Cobblestone256Decryptor(key, context)

Added in version 50.0.0.

Exactly like Cobblestone128Decryptor, but decrypts messages produced by Cobblestone256Encryptor with a 32-byte key.