| License | BSD-style |
|---|---|
| Maintainer | Kazu Yamamoto <kazu@iij.ad.jp> |
| Stability | experimental |
| Portability | Good |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.Cipher.ChaCha.Poly1305
Description
ChaCha20-Poly1305 (RFC 8439) a message at a time.
Crypto.Cipher.ChaChaPoly1305 takes a message in pieces: a state is started, the additional data appended, the body encrypted and the tag taken, each a step of its own. That is what a protocol wants when the message arrives in pieces, and it is eight foreign calls and the allocations between them when the message was already whole.
Here the whole message goes in one call.
The functions are the same shape as Crypto.Cipher.AES.GCM, so a protocol that offers both ciphers can hold them the same way.
Synopsis
- data Context
- newContext :: ByteArrayAccess key => key -> CryptoFailable Context
- encrypt :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArrayAccess ba, ByteArray output) => Context -> nonce -> aad -> ba -> Int -> CryptoFailable output
- decrypt :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArray ba) => Context -> nonce -> aad -> ba -> Int -> Maybe ba
- decryptWithTag :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArray ba) => Context -> nonce -> aad -> ba -> Int -> CryptoFailable (ba, AuthTag)
Documentation
A key, checked once.
ChaCha20-Poly1305 has nothing to precompute from a key: the one-time Poly1305 key comes from the nonce, so it differs for every message. This holds the thirty-two bytes and the knowledge that they are thirty-two, and exists so that the interface is the one Crypto.Cipher.AES.GCM has.
newContext :: ByteArrayAccess key => key -> CryptoFailable Context Source #
Take a key of 32 bytes. Any other length is reported as
CryptoError_KeySizeInvalid.
encrypt :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArrayAccess ba, ByteArray output) => Context -> nonce -> aad -> ba -> Int -> CryptoFailable output Source #
Encrypt one message. The result is the ciphertext with the tag after it,
which is the shape decrypt expects.
The nonce is the twelve bytes RFC 8439 defines; any other length gives
CryptoError_IvSizeInvalid. RFC 8439 requires a 16-byte tag.
decrypt :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArray ba) => Context -> nonce -> aad -> ba -> Int -> Maybe ba Source #
Decrypt one message, in the shape encrypt produced: the ciphertext with
its tag after it. The tag is compared here, every byte of it whatever the
answer, and a message whose tag does not match gives Nothing rather than
the plaintext.
Nothing also comes back when the input is shorter than the tag, or the
nonce is not twelve bytes.
decryptWithTag :: (ByteArrayAccess nonce, ByteArrayAccess aad, ByteArray ba) => Context -> nonce -> aad -> ba -> Int -> CryptoFailable (ba, AuthTag) Source #
Decrypt one message, the tag kept apart, and hand back the tag this end computed.
For a caller whose protocol carries the tag separately from the ciphertext,
so that decrypt -- which wants the two together and compares them itself
-- does not fit. Compare the two tags with ==; the Eq instance of
AuthTag is a constant-time comparison, and taking them apart to compare
the bytes is how this goes wrong.
Nothing here says whether the message is authentic. Until the comparison is made and has come out equal, what this returns is not plaintext, it is what the ciphertext turns into, and a caller must not act on it.