Skip to content
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

cipher: experimental design #589

Closed
wants to merge 6 commits into from
Closed

cipher: experimental design #589

wants to merge 6 commits into from

Conversation

newpavlov
Copy link
Member

@newpavlov newpavlov commented Apr 10, 2021

It's still rough around edges, but I think it's sufficient to demonstrate main ideas:

  • Use custom fat pointer types to solve both buffer-to-buffer and in-place use-cases simultaneously without code duplication. I believe the types are safe, but it's worth to double-check them.
  • Use callbacks to work around potentially varying at runtime number of parallely processed blocks. Since closures get inlined, compiler should be able to perform necessary optimizations.
  • BlockEncryptMut/BlockDecryptMut traits now used for both block modes and hardware accelerators. BlockCipher marker trait is introduced to distinguish between them.
  • crypto_common::BlockProcessing trait is now used for all traits which work over bytes. In future I think we may add aligment information to it (i.e. Block no longer will be a simple byte array).
  • The proc closures allow us to add "hooks" which can access pre- and post-encryption data, not only it's quite useful for block modes, but also should allow us to support both EtM and MtE modes. Users will not deal with these closures directly, later I will add convenience blanket methods.
  • Composition of primitives in this model is done at block level. This means that it's required that composed primitives should work with the same block size. It's an unfortunate restriction, but I couldn't find a good way around it. We could compose high-level wrappers, but it will be the less efficient "two-pass" approach.
  • User-facing high-level traits will be implemented by wrappers around block-level traits. As a side effect it will lead to unification of buffer-handling logic for stream ciphers.
  • The separate trait for async stream ciphers is replaced by a simple marker trait. I plan to introduce a wrapper with byte-level inherent methods. Since only CFB modes represent this family of algorithms, I think we probably don't need a generalization over it.

See the block-ciphers PR to see how these changes work in dependent crates.

Open questions:

  • Should we replace impl InOutVal<Block<Self>> with impl Into<InOutVal<'_, '_, Block<Self>>>, where in the latter case InOutVal is a struct containing two potentially equal pointers (i.e. it's essentially InOutBuf, but with len equal to 1)? In the former case, due to inlining compiler may generate two separate variants of a cipher (in-place and buffer-to-buffer), while in the former it may result in some optimizations being omitted (i.e. in the in-place case program may pass two pointers instead of one and perform the same pointer arithmetic twice).

@tarcieri
Copy link
Member

Started reviewing this PR. I think there's a lot of interesting/good stuff which addresses some longstanding problems and it will take me awhile to wrap my brain around.

One general nit: it looks like this PR removes all of the extant aliases for key types (e.g. CipherKey and BlockCipherKey)

Any reason for that? I think that helps usability a lot, and also will ease a future migration from GenericArray to const generics.

@newpavlov
Copy link
Member Author

Closing in favor of #727.

@newpavlov newpavlov closed this Aug 30, 2021
@newpavlov newpavlov deleted the experimental_design branch August 30, 2021 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants