So I have a set of coordinates and I will hash these with a random salt with SHA256. Coordinate range is 0,100.

salt = abc
[1, 5] = "sZv6eqPT9bqGiXbjvO8yrb4wuFjl0Z1CwSHdnIgGqEI="
[3, 4] = "8XgDJ/rrDELExVflBfDOLjqV5SB//8urxN5I6hxK9Mo="
[6, 3] = "FTzCfctBaBKp/wmopgMw7YFRpo1z2p6/IdHVujFliGs="
[1, 6] = "t2WE+ba8pt0ZEo0uW3uQH9FpI94tPVaICbctcl0YPtU="
[6, 3] = "FTzCfctBaBKp/wmopgMw7YFRpo1z2p6/IdHVujFliGs="

Input format is "{x},{y}".

Pastebin with C# code I used to generate this example: https://pastebin.com/yyMiYApc

So we have a back-end where we generate a list of hashed coordinates using a salt that just got generated. The idea was to send the hashed coordinates and the salt to the front-end. So they can verify a right coordinate using the same algorithm. If the generated hash in the front-end is like any of the hashes from the back-end, the coordinate is right. They have 20 attempts to guess all coordinates from the front-end. The idea was that the front-end would call the back-end with their coordinate and their assumption, the back-end would then verify their assumption and save it in the database. If they give faulty input we would ban / strike a user because of cheating.

We are creating a competitive guess game and we can't have 500ms delay from the back-end be a problem, so that is why we are letting the front-end make an assumption and let the back-end make the actual decision. Basically to remove input lag in UI.

This was a solid plan until we forgot that any client can decide to not call the back-end after they've verified a coordinate on the front-end. Thus making the number of maximum attempts redundant. For example any client could brute-force all 10,000 possible coordinates and check what 5 are the right coordinates. Then call the verify in the back-end 5x and win the game.

We have real prizes for this game and want to make cheating impossible and at the same time remove the delay of calling a back-end to verify your answer.

I am in no way a cryptography expert. Is there any way cryptography could help us? And if yes, could you point us in the right direction? If this problem can't be sealed completely how could we make it very hard for the client to cheat?

Feel free to edit this question so cryptography experts understand it better!

Edit 1:

The reason the send the salt right now to the front-end is because the front-end needs to know whenever they have a right coordinate. So, like I explained before. There is no time to wait for the back-end to give feedback, because that would be too much input lag.

Whenever someone guessed an coordinate they should know this instantly. And not at the end of the game.

  • $\begingroup$ If you send the hash and the salt, then the front and have lots of time to find the pre-images. The coordinate, when converted to bits, has 256 bits, so it is safe, as long as, the coordinates are a small set of all possible coordinates. The question doesn't include this information. $\endgroup$ – kelalaka Nov 24 '20 at 14:39
  • $\begingroup$ @kelalaka yeah but our coordinates are from range 0,100 so 10,000 possible combinations. Looping through this and comparing the generated hashes with the provided hashes shows which coordinates are the right ones within seconds. It's no challenge for a computer to loop through 10,000 possible combinations. That is the problem really. $\endgroup$ – Roy Berris Nov 24 '20 at 14:50
  • $\begingroup$ Your question is too long to address your issues. Why do you send the hash and the salt to the front-end? $\endgroup$ – kelalaka Nov 24 '20 at 15:06
  • $\begingroup$ @kelalaka sorry for not explaining. I'll edit the post $\endgroup$ – Roy Berris Nov 26 '20 at 10:10

You should not send salt to the front end. Send only the hash. After the "game" completed, e.g. after the front end has done 20 attempts you named, you should present the right answer and the salt. Thus every participant can check that the hash you presented at the beginning really matches the message and the salt.

And the cryptographic properties of SHA-256 guarantee that you cannot deny the right answer, because there is no easy way to find another message (coordinates in your case) and another salt, that produce the same hash. In your example, if you publish hash sZv6eqPT9bqGiXbjvO8yrb4wuFjl0Z1CwSHdnIgGqEI=, then everyone can be sure that you cannot find any other salt and any other message (coordinates) that produce the same hash.

  • $\begingroup$ I've edited my question. $\endgroup$ – Roy Berris Nov 26 '20 at 10:12

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.