Did you know that C# foreach statement is your enemy in games development?

Did you know that C# foreach statement is your enemy in games development?

When a developer lands in the games industry he has to change his state of mind about performances. In this industry we have to perform a lot of operations in less than 33 milliseconds (30 FPS, frames per second), possibly tuning the logic and the art assets to achieve 60 FPS on standalone (Windows/Linux/Mac) and consoles (Xbox One/PS4) and that means rendering the scene content, computing physics and game logic in no more than 16 milliseconds! Not really an easy task, that’s why in our industry every CPU tick counts really a lot.

So, what about the foreach statement? Well, this one is really bad, killing hundreds CPU ticks just to allow the programmer to write less code!  You think I’m exaggerating here? Let’s have a look to some code to give definitive proof.

Let’s open Visual Studio (originally tested in VS2008 Professional, then VS2010 Professional, then VS2015 Enterprise and tested again with VS2017 Enterprise with .Net 4.6.2, to produce the compiled code below) and let’s create a simple C# console app, and in that let’s write the following very simple code:

That’s an easy one, right? these two methods perform the same job, but one costs a lot in term of CPU ticks… let’s see why. I use ILSpy (http://ilspy.net/) to look into the compiled code, so let’s analyze the IL (intermediate language) I get after Visual Studio builds it (result unchanged over the years!).

Let’s start with the Cheap method:

So, nothing odd in the above, it’s pretty much what I would expect: a simple loop and a straight move of reference value, nothing more.

Now let’s have a look to what we get in IL from the Costly method:

Well, well, well… it’s many lines longer, and it contains some quite nasty logic. As we can see it allocates a generic enumerator (IL_0006) that gets disposed finally (IL_0028 to IL_002e), and that apparently is creating load on the GC (Garbage Collector). Is that it? Not really! We can also see (IL_0015) the nasty unbox operation, one of the most costly and slow in the framework! Please also note how the loop end is caught by the finally clause in case something happens (mostly an invalid casting), not really code we would write in the first place… and still we get it just using a foreach.

So, imagine to have a few of these in your game logic executing at every frame… obviously it’s never simple code like in this example so that it will be way nastier than the result shown in this above.

We struggle already so much to keep our games above 30FPS while presenting beautiful artwork (really costly to render), and a lot of nice VFX (visual effects, definitely costly) and we all love to rely on the underlying physics engine to improve the overall gaming experience: all that costs quite a lot… so when it comes to the game logic we have to write, every clock cycle and CPU tick are so valuable… we cannot possibly waste any of them, so let’s remember two rule of thumbs:

  • Language helpers that make it easier to code come with a performance cost
  • Always verify the efficiency of your code habits looking into the generated IL code

In the game industry we are all aiming at improving gamers’ experiences, making it immersive as much as technically possible: gamers are quite demanding, so let’s make sure that we always keep performance testing at the top of our coding practice, because losing even one frame in a second can be a failure factor from a market perspective.

How to securely store user credentials

How to securely store user credentials

The most common mistake is storing passwords in clear text, accompanied by the equally dangerous mistake of sending them in clear text over the network, the latter based on the naïve assumption that an SSL connection grants enough security.

SSL connectivity alone cannot guarantee security: every week new vulnerabilities are identified and fixed, and that shows how wrong it is to assume that SSL alone grants security. That assumption also implies that all users always install the latest security fixes, and that is another quite wrong assumption.

Now let’s talk about “salting” mistakes, but first let’s define it: when we add something to a password to make it more complex, we say that we are adding salt to it. For instance, if the user chooses mypass as his/her password, we might  want to generate a random number to salt it, let’s say 1234. We add that to the original password, so getting the salted password mypass1234.

Salting the password and then storing the salt in the database is another common mistake: why? Because doing that we assume that the attacker is an entity outside of the company, but that is a incorrect assumption. What about a disgruntled employee dumping the client’s database on the Torrent network? This is becoming an issue we encounter frequently, trending all over the world because of current bad employment practices. We need to remember that threats do not come only from outside the company, they might as well hit us from within, and those are the most dangerous.

Because of this we should never store any salt in the database. We make sure that we code the algorithm that computes the salt in a deterministic way. We also need to ensure that the algorithm is known only by a close circle of people, and that its parts have been developed either within the “circle of trust”; if this is not possible then make sure to break it down into methods that can be aggregated separately and have those produced by different people. The full source code should never be available outside the company’s “circle of trust”.

One other definition we now need to continue is “hashing”. The actual dictionary definition brings us quite close to what we do: we break down into pieces and scramble the bits of a word or phrase, and in doing so we reduce it to a fixed length string of hexadecimal values. To do so we implement algorithms that have been approved by NIST (and other organizations). In this algorithm we’ll use MD5 and SHA256 and SHA512.

The password generation process in details

The above implies that the first password hashing must always happen on the client side, and the result of that is sent over to the server. But is this safe enough? Not entirely, we need to add “salt“ to ensure security.

What does that mean? Let’s look into it from an attacker’s perspective. The common way to hack an account is to use lookup tables to find common passwords, so the hacker takes the encrypted password that he found on the hacked database and runs it against a database of password hashes like the followings:

The above are simple test resources, in reality any hacker has a seriously complete database compiled against full phraseological dictionaries and thesauruses in multiple languages: that’s what we are up against. Have you tested your email on Have I Been Pwned? That resource (quite nice!) can tell you if your email was part of a known security breach, and you can see what the breach was about. Most likely your email address and your hashed password have been compromised, and if the hash was simply the MD5 or SHA256 of the password itself then a hacker relying on a good dictionary database will most likely get your password back in clear text.

Because of this we have to be very careful, starting with establishing a strong password protection algorithm. Mine is shown in the following diagram.

Let’s see this in a step by step practical example from a real world algorithm in use in DFT Games Ltd games (very simplified version). In the sign up phase, the user types his user name, let’s assume it’s the email address as it’s a common scenario (we force it lower case to ensure determinism in the next steps):


then he types his password:

my password

Such weak passwords are painfully common, so we have to make sure we correct this to protect the client and zero out our liabilities. To do that, let’s compute our salt from the user name. Here I use one of many possible approaches, any other is ok as long as it’s deterministic.

Because the first letter is “j” its value is 152 in ASCII, an even number, therefore we pick all odd characters from the user name, so that


becomes for our purpose the following string:


Now we hash this new string, and for this step a simple MD5 will be enough, giving us the following:


Now we have all we need to fix that weak password, so we chain all together adding a star character in between just to increase the complexity, getting the following string:

my password* d9e2feaea42f0f4b6891f8030f357041

Now this looks much better and it is quite hard to hack using common tools, therefore this is what we are now going to hash using SHA512, getting our first secure value as all lower case Base 64:


Well, how can we improve this even more? For instance, we can apply the same odd/even rule to this hash, making sure that, because “j” is even, every non numeric character in an odd position is upper case, getting this final string:


This final one is not just the SHA512 of a salted password but has been parsed to apply a letter casing rule derived by the username exponentially reducing the already dramatically low odds to be able to crack the code via any brute force attack, with or without any hash database.

But… will this be enough? Not really! We still could be cracked given enough computing power because the only source of this hash is the username and password: we need to add something on top of this on the server side. A good way to do this is the one I show in the diagram above. Basically, when the user signs up, the server creates the user record first, then it takes the record’s time-stamp as a string, and strips all the white spaces from it:


then selects a part of this new string, maybe using an approach similar to the one used for the password by the client algorithm, but with some changes, like odd/even value of the third character in the password hash sent by the client, getting a result like this:


Then we concatenate this new information to the hash received from the client to salt it, and we hash that again via SHA512, getting the final hash:


If you want, you can also perform the upper case process on this result, to make it harder to crack. The result of all the above steps is the one we store in the database. We’ll perform the very same steps when the user signs in again in the future.

There is no dictionary attack that can crack this algorithm, no matters how good the hacker is… even the US NSA and CIA combined would certainly fail to crack this, no matter how many resources could be put on the task!

Naturally, the above steps are just a sample, a suggestion: be creative and original, don’t just use it as it is in this article because… I just published it, so it’s now possible to crack it 🙂 Use different combinations to compute your salt on both client and server and make sure it’s complex enough that it cannot be easily derived.

The actual full algorithm of the above real-life implementation is in use in our family company, DFT Games Ltd., and the real details about the salt are known only to family members and provided via a scrambled DLL to the development teams for in-app implementation. Keeping the client and server algorithms a secret is key to make this really secure. On top of this we have two-factor authentication based on our own authenticator app (and algorithm) for specific high-security applications.