froydnj/ironclad — pull request #23 by eadmund (2012-08-23 02:39:39+00:00)
Title: Authenticated encryption interface

I'm adopting GitHub's workflow (c.f. [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html)) for this branch: rather than submitting a pull request which is ready to be pulled, I'm proposing that we use this pull request to discuss implementation issues. Let me know if you think that this is a useful mechanism.

Authenticated encryption has two operations: encrypt-and-generate-authentication-tag and decrypt-and-authenticate. It occurred to me that ENCRYPT and DECRYPT could retain the exact same signature as with ordinary symmetric encryption, with an additional TAG method on the cipher object itself. To encrypt, one would execute:

```common-lisp
(let ((cipher (make-authenticated-cipher ...)))
(encrypt cipher plaintext ciphertext...)
(values ciphertext (tag cipher)))
```

And to decrypt one would execute:

```common-lisp
(let ((cipher (make-authenticated-cipher ...)))
(setf (tag cipher) tag)
(decrypt cipher ciphertext plaintext ...)
ciphertext)
```

Where DECRYPT throws a condition when the authentication fails.

In order for this to work, ENCRYPT and DECRYPT could become generic functions, with the CIPHERS module implementing the symmetric version and the AUTH-ENC implementing the authenticated encryption version.

Alternatively there could be separate AUTHENTICATED-ENCRYPT and AUTHENTICATED-DECRYPT, but that seems a bit ugly to me.

What do you think?