crypton-2.2.5: Cryptography Primitives
LicenseBSD-style
MaintainerKazu Yamamoto <kazu@iij.ad.jp>
Stabilityexperimental
PortabilityGood
Safe HaskellNone
LanguageHaskell2010

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

Documentation

data Context Source #

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.

Instances

Instances details
NFData Context Source # 
Instance details

Defined in Crypto.Cipher.ChaCha.Poly1305

Methods

rnf :: Context -> () #

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.