Opaque tag representing the hash state struct crypto_secretstream_xchacha20poly1305_state used by the C API.
To use a CryptoSecretStreamXChaCha20Poly1305State, use withCryptoSecretStreamXChaCha20Poly1305State.
:: a typeCtrl KGHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27
Modulelibsodium-bindings-0.0.1.1Haskell2010
This high-level API encrypts a sequence of messages, or a single message split into an arbitrary number of chunks, using a secret key, with the following properties:
Messages cannot be truncated, removed, reordered, duplicated or modified without this being detected by the decryption functions.
The same sequence encrypted twice will produce different ciphertexts.
An authentication tag is added to each encrypted message: stream corruption will be detected early, without having to read the stream until the end.
Each message can include additional data (ex: timestamp, protocol version) in the computation of the authentication tag.
Messages can have different sizes.
There are no practical limits to the total length of the stream, or to the total number of individual messages.
Ratcheting: at any point in the stream, it is possible to "forget" the secret key used to encrypt the previous messages, and switch to a new key.
An encrypted stream starts with a short header, whose size is cryptoSecretStreamXChaCha20Poly1305HeaderBytes bytes. That header must be sent/stored before the sequence of encrypted messages, as it is required to decrypt the stream. The header content doesn't have to be secret and decryption with a different header would fail.
A tag is attached to each message. That tag can be any of:
0, or cryptoSecretStreamXChaCha20Poly1305TagMessage: the most common tag, that doesn't add any information about the nature of the message.
cryptoSecretStreamXChaCha20Poly1305TagFinal: indicates that the message marks the end of the stream, and erases the secret key used to encrypt the previous sequence.
cryptoSecretStreamXChaCha20Poly1305TagPush: indicates that the message marks the end of a set of messages, but not the end of the stream. For example, a huge JSON string sent as multiple chunks can use this tag to indicate to the application that the string is complete and that it can be decoded. But the stream itself is not closed, and more data may follow.
cryptoSecretStreamXChaCha20Poly1305TagRekey: "forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.
A typical encrypted stream simply attaches 0 as a tag to all messages, except the last one which is tagged as cryptoSecretStreamXChaCha20Poly1305TagFinal.
Note that tags are encrypted; encrypted streams do not reveal any information about sequence boundaries (cryptoSecretStreamXChaCha20Poly1305TagPush and cryptoSecretStreamXChaCha20Poly1305TagRekey tags).
For each message, additional data can be included in the computation of the authentication tag. With this API, additional data is rarely required, and most applications can just use nullPtr and a length of 0 instead.
Opaque tag representing the hash state struct crypto_secretstream_xchacha20poly1305_state used by the C API.
To use a CryptoSecretStreamXChaCha20Poly1305State, use withCryptoSecretStreamXChaCha20Poly1305State.
Allocate an opaque CryptoSecretStreamXChaCha20Poly1305State of size cryptoSecretStreamXChaCha20Poly1305StateBytes.
⚠️ Do not leak the CryptoSecretStreamXChaCha20Poly1305State outside of the lambda, otherwise you will point at deallocated memory!
Create a random secret key to encrypt a stream, and store it into the parameter
Note that using this function is not required to obtain a suitable key: the secretstream API can use any secret key whose size is cryptoSecretStreamXChaCha20Poly1305KeyBytes bytes.
cryptoSecretStreamXChaCha20Poly1305InitPush :: Ptr CryptoSecretStreamXChaCha20Poly1305StateCryptographic state
-> Ptr CUCharHeader buffer, must be of size cryptoSecretStreamXChaCha20Poly1305HeaderBytes.
-> Ptr CUCharBuffer holding the secret key. Must be of size cryptoSecretStreamXChaCha20Poly1305KeyBytes.
-> IO CIntReturns 0 on success, -1 on error.
Initialise the cryptographic state using the secret key, then stores the stream header into the header buffer
cryptoSecretStreamXChaCha20Poly1305Push :: Ptr CryptoSecretStreamXChaCha20Poly1305StateCryptographic state
-> Ptr CUCharBuffer that receives the cipher text.
-> Ptr CULLongIf this pointer is not nullPtr, it will store the length of the cipher text.
It is guaranteed to be always (messageLength + cryptoSecretStreamXChaCha20Poly1305ABytes ).
-> Ptr CUCharPointer to the message to encrypt
-> CULLongLength of the message (messageLength).
-> Ptr CUCharAdditional, optional data that can be included in the computation. Can be nullPtr if you have nothing to add.
-> CULLongLength of the additional, optional data. Can be 0 if you have nothing to add.
-> CUCharTag for the cipher text.
-> IO CIntReturns 0 on success, -1 on error.
Encrypt a message using a cryptographic state and a tag.
Additional data can be optionally provided. The maximum length of an individual message is cryptoSecretStreamXChaCha20Poly1305MessageBytesMax bytes (~ 256 GB).
cryptoSecretStreamXChaCha20Poly1305InitPull :: Ptr CryptoSecretStreamXChaCha20Poly1305StateCryptographic state
-> Ptr CUCharHeader buffer, must be of size cryptoSecretStreamXChaCha20Poly1305HeaderBytes.
-> Ptr CUCharBuffer holding the secret key. Must be of size cryptoSecretStreamXChaCha20Poly1305KeyBytes.
-> IO CIntReturns 0 on success, -1 if the header is invalid.
Initialise the cryptographic state using the secret key and a header. The secret key will not be required any more for subsequent operations
cryptoSecretStreamXChaCha20Poly1305Pull :: Ptr CryptoSecretStreamXChaCha20Poly1305StateCryptographic state.
-> Ptr CUCharBuffer that will hold the decrypted message.
-> Ptr CULLongIf this pointer is not nullPtr, it will store the length of the message.
It is guaranteed to be always (cipherTextLength - cryptoSecretStreamXChaCha20Poly1305ABytes ).
-> Ptr CUCharIf this pointer is not nullPtr, the tag attached to the message is stored in that buffer.
-> Ptr CUCharCipher text to be decrypted.
-> CULLongLength in bytes of the cipher text.
-> Ptr CUCharAdditional, optional data that was bundled with the cipher text will be put there. Can be nullPtr if you know that nothing was added.
-> CULLongLength of the additional, optional data. Can be 0 if you have nothing to add.
-> IO CIntReturn 0 on success, -1 if the ciphertext appears to be invalid.
Decrypt a message chunk.
Applications will typically call this function in a loop, until a message with the cryptoSecretStreamXChaCha20Poly1305TagFinal tag is found.
cryptoSecretStreamXChaCha20Poly1305Rekey :: Ptr CryptoSecretStreamXChaCha20Poly1305StateCryptographic state.
-> IO ()Rekeying happens automatically and transparently, before the internal counter of the underlying cipher wraps. Therefore, streams can be arbitrary large.
Optionally, applications for which forward secrecy is critical can attach the cryptoSecretStreamXChaCha20Poly1305TagRekey tag to a message in order to trigger an explicit rekeying.
The decryption API will automatically update the secret key if this tag is found attached to a message. Explicit rekeying can also be performed without adding a tag, by calling this function.
This updates the state, but doesn't add any information about the secret key change to the stream. If this function is used to create an encrypted stream, the decryption process must call that function at the exact same stream location.
Size of the secret key
Size of the encryption header
Size of an opaque CryptoSecretStreamXChaCha20Poly1305State
Size of an authentication tag in bytes
Maximum length of an invidual message in bytes (~ 256 GB)
Most common tag, add no information about the nature of the message
Indicates that the message marks the end of a set of messages, but not the end of the stream
"forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.
Marks the end of the stream, and erases the secret key used to encrypt the previous sequence.