Challenge 18, CTR decryption
Implement CTR mode oracle
Test fix: Mask is calculated, not iterated naively
The previous test expected simple +1 rolled values, but the mask stages calculate the plaintext byte and then produce a new value for the stage.
So, wow, that was a lot of learning.
The mask itself isn't important. The mask can be calculated on the fly every time you want to create it (though caching would probably be an improvement) so that you don't need to guess the right bit flip to +1 the value; the plaintext value can be directly xor'd with the desired value because the operations I insert are commutative.
Also I picked a fairly roundabout way to implement the block breaker and mask.
Add a decryption method which accepts a mask
This makes it simpler to centralize the key data
Bugfix: zero-length padding is invalid.
Give a better response when invalid padding is found for the sake of challenges
Expand the traits available on oracles
I got overzealous when needing to expose the CBC IV.
I can't simply mark the IV as `pub`, since that allows external modification.
Challenge 16 fix
Ordering of encodings is important.
A working CBC padding attack :o
Implement DecryptionOracle trait
Improve testing to solve full-block padding
Using an enum is a clearer indication of error
So, the challenge-12 solution works for #14 too.
Small change, unchecked Result fix
Use u8 when padding block, per last change reasoning
The block lengths should be computable within u8's
Split out the padding validation
Split out randomness() to be a dep