• Mikina@programming.dev
    link
    fedilink
    arrow-up
    13
    ·
    edit-2
    9 months ago

    I can’t really imagine how would this work in practice. While “I’m using industry standart AES encryption” may mean the cypher and the key itself will not be breakable, the bigger issue is how to get the 256b key from the player. Does he expect them to actually figure out and manually input 265b of data? That would be a pretty hefty game design challenge to make something like that possible.

    I’m betting there’s probably something that generates the key from a vastly smaller player input, i.e what gameobjects you interacted with, in what order, or what did you press/place somwhere. But that also means that the entropy is probably in the bruteforcable range, and once you find the function that decrypts the secrets, it should be pretty easy to find the function that generates the key, and the inputs it takes.

    The only A solution to keeping data from data-miners I can imagine would require just storing the key on the server - which could generally also be bypassed, since then you probably need a way to request the key, which could be data-mined and faked, so you’re back at step one - how to validate requests for the key.

    Or just make the secret puzzles so difficult, that they can’t be brute-forced and the result really is 256b or more of data. Thinking about it, having specified 256 inputs you either have to make or are red-herrings that shouldn’t be interacted with isn’t really that much, but then the data-miner can just check the location of each one and filter out the inaccessible, and bruteforce the rest. And if all are accessible, it would make for a really difficult secret to discover properly.

    • metiulekm@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      6
      ·
      9 months ago

      I’m betting there’s probably something that generates the key from a vastly smaller player input, i.e what gameobjects you interacted with, in what order, or what did you press/place somwhere. But that also means that the entropy is probably in the bruteforcable range, and once you find the function that decrypts the secrets, it should be pretty easy to find the function that generates the key, and the inputs it takes.

      When handling passwords, it is standard practice to use an intentionally costly (in CPU, memory, or both) algorithm to derive the encryption key from the password. Maybe the dev can reuse this? The resulting delay could easily be masked with some animation.

      • Mikina@programming.dev
        link
        fedilink
        arrow-up
        3
        ·
        9 months ago

        Most of the costly algortihms I know of are still reasonably fast, i.e you can try thousands of checks per second, so it would definitely help, but you would then still have to design a puzzle that has a large number od possible answers or combinations - which I still think really limits what you can create with it.

        He could design a check/hash that would take a lot longer than common algs like bcrypt, but then theres a risk of someone reverse engineering it and simplyfiing it, or even finding a vulnerabilty that makes guessing the key easier. Because its suprisingly really difficult to make a hash that is matematically ok and doesnt have side-effects. Especially since crypto is dealling with some obscure advanced math, and some of the vulnerabilities in existing algorithms are pretty mind-blowing - especially since the more math you stack up, the more chances are there of you unknowingly using some kind of obscure math laws that can be used to simlplyfi or predict the results of your algorithm.

        For a really bad and simple example (that kind of illustrates the point) from the top of my head, if i was just multipliing the input by 2 to get the key, and i did it 1000 times, it would mean that 1) the attacker could make it faster by multiplying it just once by 2^1000, and 2) the result would always be even, so now he knows he only has to bruteforce half of the keys, since it cannot be any odd key.

        • metiulekm@sh.itjust.works
          link
          fedilink
          English
          arrow-up
          1
          ·
          9 months ago

          Ultimately you can configure these however you want. On my 5600X, I easily got one full execution of scrypt to last 34.6 seconds (--logN 27 -r 1 -p 1 in the example CLI), and one full execution of bcrypt to last 47.5 seconds (rounds=20 and the bcrypt Python library).

          This kind of configuration (ok, not this long, but definitely around 1 second per execution) is very common in things like password managers or full disk encryption.

    • nous@programming.dev
      link
      fedilink
      English
      arrow-up
      3
      ·
      9 months ago

      I am guessing it will just be sharded and hidden throughout the code in areas that get triggered as you play though the game.

      The only real question is if it is quicker to find it in the code or to play though the game. IMO that is all a bit pointless as once it is cracked it will be cracked. All this does is maybe buy a few hours after launch (assuming the game files are not predownloaded before then) at best before all the info is available online. And now they have announced this quite a few will take it as a challenge and I doubt it will really slow anyone down.

    • Risk
      link
      fedilink
      arrow-up
      3
      ·
      9 months ago

      I apologise as I know next to nothing about how this all works - so ELI5 please:

      Based on what you explained here, could the game designed in theory put those 256 bits of key into 256 puzzles - with several hundred more puzzle pieces being red herrings?

      But were you making the point the data miner could just then target the thing that accepts those puzzle pieces and reads the key from them?

      • Mikina@programming.dev
        link
        fedilink
        arrow-up
        3
        ·
        9 months ago

        Most of cyphers have some kind of decryption key, mostly between 256 to 4098 bits long. That means the (256 bit) key is 256 ones or zeroes (where order is important), so there’s 2^256 combinations you have to try. To quote a stack overflow question about it:

        You’d expect to find it after going through (on average) half of the keys, so average expected number of attempts would be 2^255. This is a Really Big Number. If every atom on earth (about 1.3 * 10^50 atoms) was a computer that could try ten billion keys a second, it would still take about 2.84 billion years.

        But, remembering and imputing 256 ones or zeroes (or one number between 0-2^255, if you convert it from binary to decimal, which is around 78 digits) is really difficult and infeasible in practice. Due to that, when you want to encrypt something for example with a password that is easier to remember, you somehow have to generate the 256b key from the password, usually using a hash function. Because hash functions are designed to convert mostly any input into a 256b (or other size) bit keys, while making sure that the 256b are randomly distributed - so if you for example change one letter in the password, the hash will be absolutely random (but still the same for the same input), with no way to tell that it has anything in common with the hash of the previous password.

        However, this introduces a problem - if for example you only used 4 digit PINs for the password, all anyone needs to do now is to 1) figure out how you generate the 256b encryption key from the PIN (which is usually doable by reverse-engineering the code), and 2) try every 4 digit combination, generate a key from it and then see if that key decrypts the data. That’s only 6561 combinations, and can be done pretty quickly. So, by using the password that’s limited to 4 digit PIN, even though you are using a 256b key for encryption, you have reduced the number of keys that can be valid - because there’s only 6561 valid passwords, which only map to 6561 encryption keys out of the 2^256.

        EDIT: I’ve realized that I’ve explained something you didn’t ask for, I’ll just keep it up for others, I didn’t read your question properly, sorry about that :D

        For the game development, assuming the author wants to use AES, it would mean that either there is some kind of “password”, be it having to input a number, interact with game objects in certain order, or do some actions in order, out of which the key is generated. But then the answer has to be really complex (super-large number, or interacting with tens to hundreds of objects, or a long string), so the number of possible answers is large-enough that it can’t be brute-forced - which would make for a really hard puzzle. Even if you for example required the player to input a text password of some kind, it could get frustrating, since it would have to be pretty long to not be bruteforcable.

        The other solution I was thinking about is that you would have 256 objects or puzzles, where represents one “digit” in the key. If you solved the puzzle, the digit would flip to 1. However, it would be easy to check from code which puzzles are connected to the key - because that’s what you are generating the key from. That would mean that unless you want the key to be all 1, some of the puzzles that are connected would have to be unreachable by the player (which can also be data-mined with some effort) or intended to NOT be solved, which does add more complexity and makes the puzzle even harder - those would be the red herrings.

        could the game designed in theory put those 256 bits of key into 256 puzzles - with several hundred more puzzle pieces being red herrings?

        Not exactly, because if you wanted to generate the key by solving 256 puzzles, it would mean that either the key is 256 ones, or each puzzle has a value - one or zero - it adds to the key. If that’s the case, then you can simply take the values from the puzzle code and generate the key like that. Having more red herrings wouldn’t help, because in code (which you can dissasemble and reverse-engineer with enough skill), there will have to be a function “UnlockSecret(key)”, and probably something like “key = CreateKey()”. And in the CreateKey function, you have to have only the puzzles that are not red herrings - otherwise the code has no way of knowing which puzzles to use for building the key. So a dataminer would just check the CreateKey function, and then check what exact puzzles are used for the key. That’s why the only option in this case is to have a 256 puzzles, where each is either completed (1) or uncomplete(0), and out of the 256 puzzles, some are red herrings that should not be completed (and stay at 0), and some that should be - and those add 1s into the key.

        However, now that I think about, just having some kind of a cypher puzzle which gets you a password of 10-20 characters (that’s 10^29 options) would probably be enough. But then again - that’s not that much fun, and it greatly limits what you can actually design.

        • Risk
          link
          fedilink
          arrow-up
          1
          ·
          9 months ago

          Great explanation (including the pre-edit bit ha) - thank you!

          When you say the cypher puzzle wouldn’t be much fun - why not? Surely you could have a set of puzzles through the game that each yield a keyword (seemingly plot relevant, but still pretty random when combined with the others) and the player has to combine all of them via clues in game in the correct order to yield the correct key. That doesn’t sound unfun on the surface?