rust-lang / portable-simd

The testing ground for the future of portable SIMD in Rust
Apache License 2.0
897 stars 81 forks source link

ChaCha20 as a possible addition to examples area #328

Closed thor314 closed 1 year ago

thor314 commented 1 year ago

I wrote a portable-simd enabled implementation of the chacha20 stream cipher, as a partial rewrite of Rust-Crypto to play around with portable simd and const generic techniques. It might be a useful base for a short example; the cipher is extremely simple, but also documents an application of bit-rotation, for if and when #216 is resolved.

My implementation: https://github.com/thor314/tkcrypto/blob/main/src/chacha.rs#L217 Ported from: https://github.com/RustCrypto/stream-ciphers/tree/master/chacha20/src/backends

If this seems a worthwhile example, I'll repackage the example with further comments and submit a PR.

thomcc commented 1 year ago

but also documents an application of bit-rotation, for if and when https://github.com/rust-lang/portable-simd/issues/216 is resolved

I believe that issue isn't about bit rotation, but lane rotation.

thomcc commented 1 year ago

Bit rotation for integers (as is needed for chacha) would be reasonable — AFAIK it's only really supported by the AMD's XOP instruction set extension (admittedly that's a deprecated), but it is a method integers have, so I'm honestly a little surprised we don't already have something here.

programmerjake commented 1 year ago

Bit rotation for integers (as is needed for chacha) would be reasonable — AFAIK it's only really supported by the AMD's XOP instruction set extension (admittedly that's a deprecated), but it is a method integers have, so I'm honestly a little surprised we don't already have something here.

bit rotation of vectors can be done using vprolw on avx512, or by shifting and or-ing.

bit rotation of vectors is also supported in PowerISA (both in VMX/AltiVec and in SimpleV).

calebzulawski commented 1 year ago

Are bits generally rotated independently in each lane, or all together by the same amount? Just curious--I'm not sure this actually matters for the API, since independent rotation can be emulated with select.

programmerjake commented 1 year ago

Are bits generally rotated independently in each lane, or all together by the same amount? Just curious--I'm not sure this actually matters for the API, since independent rotation can be emulated with select.

independent rotation amounts are common in cryptography

thomcc commented 1 year ago

All lanes are rotated by the same amount for chacha.

thor314 commented 1 year ago

yep that's correct. I didn't see an api for bit-rotation, so I converted back into an array for that operation, though as programmerjake mentioned, there are specific instructions for bit rotation on architectures like AVX. The RustCrypto library uses a different trick though, involving _mm256_shuffle_epi8. https://github.com/RustCrypto/stream-ciphers/blob/master/chacha20/src/backends/avx2.rs#L227

thomcc commented 1 year ago

Yes, the shuffle works for the part of the algorithm that needs rotation by a 16 and by 8, but other parts require rotation by 12 bits, and by 7 bits (it's 16, 12, 8, 7). In those cases, the RustCrypto implementation uses shift and or (well, xor).

In any case, as to the comment about this being a potential addition to our examples: while it's a simple algorithm (and one I've implemented myself multiple times), I don't think we want to maintain any cryptography in our examples.

programmerjake commented 1 year ago

bitwise rotation is tracked by #14