-
Notifications
You must be signed in to change notification settings - Fork 230
[WIP] cipher: split Encrypt/EncryptPar and Decrypt/DecryptPar #354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Closes #349 Adds `Encrypt` and `Decrypt` traits which can be used in cases where e.g. only the encryption portion of a block cipher is used, as in CTR mode. This PR does not otherwise attempt to add things like a blanket impl.
Adds traits explicitly for parallel encryption/decryption, and blanket impls of the `Encrypt`/`Decrypt` traits for `EncryptPar`/`DecryptPar`. This makes the slice-based methods the primary user-facing API, and with it eliminating the need to worry about the `ParBlocks` associated type where it doesn't matter.
83c64d4 to
ebfffdc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about usefulness of such split. If the main concern is a possible runtime variability of ParBlocks, I think it will be better to move from the associated constant. One option is to provide a method which would return a recommended number of parallel blocks as was proposed earlier. Another one is to introduce methods which could like this:
fn encrypt_block_chunk<'a>(&self, blocks: &'a mut [Block]) -> (&'a [Block], &'a mut [Block]);The idea is that it will return processed blocks on the left and unprocessed leftovers on the right. For example it could be helpful for one-pass implementations of AEAD construct. For efficiency sake we could mandate that it will do parallel processing only, so if the left slice is empty, users should use encrypt_block(s) on leftovers. I am not sure how well it will work in practice so some tweaks may be needed.
|
The main goal is to encapsulate parallelism as an implementation detail and avoid dealing with it where it's irrelevant. Most (12 out of 16) of the crates in https://github.com/rustcrypto/block-ciphers declare For similar reasons we omitted Also now that you mention it, it does also simplify making runtime adapters to different backing cipher implementations.
I think it's nice to have an associated parallel buffer type accessible when possible, especially for things like interleaving encryption and universal hash operations in parallel. It might make sense to make that into a more fully fledged associated type which could e.g. wrap Those are things we can't explore without some kind of associated type, though. |
Saving one line per crate does not look like a good motivation for introducing two traits. Also note that we have to specify Making it easier to keep block data in registers is a separate issue, which is probably better discussed in the linked issue. |
|
Ok, will close this for now |
|
@newpavlov I encountered a reason why I think it might be nice to revive this, or at least a problem I'd like to generally solve one way or another. The problem occurs when trying to write a bound like this: where B: BlockCipher<BlockSize = U16>These exist in several places, including In each of these cases, So in each case, to bound on the block size, you actually have to write: where
B: BlockCipher<BlockSize = U16>,
B::ParBlocks: ArrayLength<GenericArray<u8, U16>>,This feels like an implementation detail leaking out which could otherwise be hidden. |
|
Yes, it's quite unfortunate, but I don't think it's a good motivation for introducing those traits. I would like to keep API which will require minimal changes when migrated to const generics and AFAIK with them the problematic bounds will not be longer needed. |
|
Closing this out in favor of a more general and ambitious proposal: #444 |
This PR is based on #352, which should get merged first.
Adds traits explicitly for parallel encryption/decryption, and blanket impls of the
Encrypt/Decrypttraits forEncryptPar/DecryptPar.This makes the slice-based methods the primary user-facing API, and with it eliminating the need to worry about the
ParBlocksassociated type where it doesn't matter.