0
$\begingroup$

So I'm new to this area of Stack Exchange, and to cryptography in general, but I just wanted to ask this question here to see if I could get any advice. I don't understand a lot of the technical jargon used around here, so go easy on me.

I'm programming something where I need to use a hash algorithm to convert a 96-bit number into another 96-bit number. No, it's not for passwords, and it doesn't really need to be super secure. Actually, it's just for generating a unique UUID for each level a player creates in a game. The original 96-bit number contains the user's MAC address, the timestamp when the level was created, and a pseudorandomly generated number. To me it seems a bit weird to have a level's UUID traceable back to the timestamp and the creator's MAC address (and possibly a minor security risk for the latter, from what I get at), so I decided on using a hash function to obscure that information.

However, most hash functions take an input of indefinite length and return an output of predetermined length, which in most cases is not 96 bits. I need a hash function where I can specify the length of the output. Preferably, the function would require an input of that same length. Why is that? Well, however rare they may be, the possibility of hash collisions is a given for functions that take an input of indefinite length. If my function were to take an input with a length of 96 bits and return an output with a length of 96 bits, a one-to-one mapping could be created between the inputs and outputs. Again, I don't know a huge deal about cryptography, so I have no idea if creating a function like this that is completely immune to hash collisions is even possible, but I would like to try to avoid them as much as I can because of my requirement for uniqueness.

Thanks in advance for the help.

$\endgroup$
  • $\begingroup$ Personally, given your use case, I would use SHA-512 with a fixed message prefix, maybe a 256-bit random number, and truncate the result $\endgroup$ – Richie Frame Dec 7 '16 at 1:58
  • $\begingroup$ You're saying to add a fixed prefix to each unhashed string? Why would I do that? $\endgroup$ – Grady Shoemaker Dec 9 '16 at 4:55
  • $\begingroup$ so that more data is being fed into the hash function. The input to a single iteration of SHA-512 is a 1024-bit block, 895 of which are used for the data, meaning 799 of them are 0s for a 96-bit input $\endgroup$ – Richie Frame Dec 9 '16 at 5:33
  • $\begingroup$ What's the advantage of using SHA-512 over SHA-256? $\endgroup$ – Grady Shoemaker Dec 9 '16 at 6:06
  • $\begingroup$ in your case, probably none, however SHA-512 does have a native SHA-512/t variant for truncated outputs $\endgroup$ – Richie Frame Dec 9 '16 at 7:18
1
$\begingroup$

What you're asking for is basically a 96-bit block cipher (pseudorandom permutation) that does not have an easily computable inverse. On the contrary, your permutation should instead be resistant to preimage attacks.

Alas, I'm not familiar with any such cryptographic primitive, or any construction that would allow one to be constructed from standard components. (If anybody does know such a construction, I'd be quite interested to learn about it.)

In practice, I'd recommend just using a standard hash function (like SHA-256) and truncating its output to 96 bits. In practice, you're not likely to see any collisions before the number of hashed inputs starts to approach the "birthday bound", i.e. the square root of the number of possible outputs, in your case $\sqrt{2^{96}} = 2^{48}$. It seems very unlikely that your game would ever end up with anywhere near that many players, considering that there are less than $2^{33}$ people living on Earth.

If you want even more certainty than that, just don't truncate the hash.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.