0

I'm looking to design a sorting process/algorithm that shuffles items in a list, but to do so uniquely based on the hash of an input; so that when the same input--essentially a passphrase--is hashed or processed, the same exact shuffling is reproduced. This would need to have the capacity to uniquely shuffle 26^4 things (application is pairing up two lists that are each 26^4 things long, but it only needs to shuffle one of them).

Can this be a thing?

  • What have **you** tried so far? Share your findings. Show us your code. – MrSmith42 Apr 19 '18 at 20:12
  • MrSmith42, I have no code, I don't know what to try. As is probably evident by my obtusely-applied technical vocabulary, I don't even know how to frame the problem in the terms of this discipline. I can only imagine how it would work based on my conceptual understanding of cryptography; this thread is trying to figure out from the subject experts whether it's realistic. I can't think of any other way to go about this, other than studying for a second undergrad degree, and it's frustrating trying to find forums that don't downvote with dismissal. – temporary2848921 Apr 20 '18 at 04:34
  • I think most forums, and also this one, follow the approach: "I have a problem and have researched and tried a lot and could still not find the answer." So if you did that, add the results of your research and what you have tried to your question, so we do not need to start from zero. – MrSmith42 Apr 20 '18 at 07:18
  • Yes, and that's partly also what's frustrating is not even knowing enough about the subject to frame the problem in the right words. I don't code. I've read Cryptonomicon. And I'm certainly not looking for others to code this solution for me or anything; I just need to know if it's feasible. An algorithm that shuffles a list with enough randomness and capacity to handle 26^4 things, based on a seed that acts as a shared secret. Beyond an answer on a scale of "yes" to "no," anything like "sure, you'd probably do that with a such and such feeding into a whatever function," is just bonus. – temporary2848921 Apr 20 '18 at 07:47

3 Answers3

2

You can use the hash of your input as a seed to a random number generator that you then use to perform the shuffling. If two inputs are the same (have the same hash), then the RNG gets seeded the same way, resulting in the same shuffle.

k_ssb
  • 6,024
  • 23
  • 47
  • Does this guarantee a unique shuffle for each input value? – Oliver Charlesworth Apr 19 '18 at 19:16
  • 1
    @OliverCharlesworth Of course not. There are only a finite number of distinct shuffles, so collisions are bound to happen. – k_ssb Apr 19 '18 at 19:16
  • 1
    The OP said "unique based on the hash of an input", so I *assumed* (though could obviously be wrong) an implication that the hash would be less than log2((26^4)!) bits in length. – Oliver Charlesworth Apr 19 '18 at 19:18
  • I understand there may be collisions; so within some parameter that ensures some acceptable level of infeasibility – temporary2848921 Apr 19 '18 at 19:33
  • You mentioned the shuffle should depend on the hash of the input, so let's assume that you have two inputs with different hashes. Then, the probability of two different hashes (seeds) resulting in the exact same shuffle for 26^4 items is incredibly small. There are (26^4)! different shuffles, and you're essentially picking two at random by shuffling with different seeds. They're not going to collide within your lifetime. – k_ssb Apr 19 '18 at 19:36
  • Perfect. Where can I go to learn about the PRNGs that would help with this specific application? – temporary2848921 Apr 19 '18 at 19:39
0

If you have 26^4 items, there are about 10^240000 possible permutations, requiring a passphrase of at least 1 million characters (or so) to make the permutations guaranteed unique. So no, not really.

But! If you just want to permute unpredictably based on the passphrase, just hash it, use the result as the seed of a PRNG, then use the PRNG to do a standard (Fisher-Yates) shuffle of the items. The result will be unique-ish, though not cryptographically strong.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • I'm not sure I follow your first paragraph. It sounds like your conclusion should be the opposite - for anything **less** than 1 million characters, each input value can be mapped to a unique permutation. – Oliver Charlesworth Apr 19 '18 at 19:20
  • How could the process described in your second paragraph be made cryptographically strong? That's essentially what I'm after, is a cryptographically strong sorting of a list, based on a passphrase/shared-secret. I'm sure other algorithms could be used to salt and expand (maybe with avalanching effects?) the end product so as to affect a 26^4 long list. – temporary2848921 Apr 19 '18 at 19:36
  • 1
    @temporary2848921 - What does "cryptographically strong" mean in the context of shuffling a list? – Oliver Charlesworth Apr 19 '18 at 19:47
  • Where the resulting pseudorandomness is high enough to ensure some acceptable level of infeasibility in brute force breaking the order of the sort; so that the shared-secret/seed is the only thing that can recreate its respective sort. – temporary2848921 Apr 19 '18 at 19:57
0

One way to do it is to use your seed value as a permutation index. That is, given some seed value, m, you generate the mth permutation of those 26^4 elements.

For example, the possible permutations of the numbers 1 through 3 are:

123,132,213,231,312,321

The fourth permutation, then, is 231.

Eric Lippert did a series on generating permutations some time back. The fourth article in the series shows how to generate the mth permutation. Check it out at https://ericlippert.com/2013/04/25/producing-permutations-part-four/

The code examples are in C#, but the explanation and code are clear enough that implementing in any other language should be straightforward.

This technique will guarantee you a different ordering (permutation) for every seed, provided that the range of the seed is smaller than the total number of possible permutations (26^4)!.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351