For a personal project I'm currently tinkering on, I'm looking for a function which has the following properties:
- For any number X in the range 0..MAX, there is a 1:1 random mapping with another number Y in that range.
- As long as the key/algorithm remains the same, that mapping should not change. For every X, there is one and only one Y, and for every Y there is one and only one X.
- Small changes in X should generate massive changes in Y.
- Calculating X -> Y should be computationally simple, even for extraordinarily large values of MAX.
- Calculating Y -> X should be (effectively) impossible, as should guessing the key.
In non-numerical terms: I'll be encrypting chunks of data (think 4096 bits, maybe more), and expecting an equally-sized unique output chunk for every possible input chunk. Every chunk will always be the same size.
Arbitrary values of X will be converted to Y quite often. End users will be able to choose their value of X at will and see its corresponding Y, across a vast numerical range. Cryptography is not my strong suit, but from my reading this translates as "the algorithm would need to be resistant to chosen-plaintext attacks". The users should never be able to calculate Y -> X, as that would spoil all the fun (to say the least).
A simple visual, for MAX=8:
So it should be criminally easy to start with X=2 and calculate Y=5, but it should be essentially impossible to guess X=6 from Y=3 without brute forcing.
There were several promising answers here, but it was unclear how secure any of them actually would be given the conditions: https://stackoverflow.com/questions/16398843/unique-int-to-int-hash
My strong preference would be to use an existing and battle-tested encryption algorithm for this, and preferably one which exists in OpenSSL or some other library I can just plug into from Rust, but I've had trouble knowing the right vocabulary to search for what I want (I'm far from new to programming, but very very green in cryptography). It seems from my reading that block ciphers are what I'm looking for, but I have been thrown off by all the talk of IVs and counters and am unsure if CBC/CTR/etc actually work for what I'm trying to do (or if what I'm trying to do is even possible).
Any pointers in the right direction would be greatly appreciated!