kmaragon / Konscious.Security.Cryptography

MIT License
202 stars 20 forks source link

Switch to unsigned ints #17

Closed sallgeud closed 6 years ago

sallgeud commented 7 years ago

The configuration values are ints, which have the ability to be negative numbers. Please consider changing them to uint or ushort or ulong.

kmaragon commented 6 years ago

As far as the domain is concerned, they would still need to be upper bounds checked at runtime. The exception to this is if I were to create a new special value type that is bounds checked on creation. But that again is at runtime. Unfortunately there's no way in C# to create a compile time assertion on such values like I'd be able to do with something like C++.

sallgeud commented 6 years ago

It's just good coding practice to give yourself more space for future expansion, especially in lengths or sizes, by using unsigned numbers.

kmaragon commented 6 years ago

DegreeOfParallelism - this is roughly tied to the number of threads. Quantum computing will make actual work orders of magnitude faster. But without major technology shifts and OS scheduler rewrites, You won't be having more than 2 Billion threads. Let's be real, you won't have 200 threads. There's a direct relationship to this and the amount of memory, which needs to at minimum allow for a full block per thread.

MemorySize - this is size in KB of the memory used for generating the hash. The difference between 2 Terabytes and 4 Terabytes of memory (machines with that much memory generally cost 5-6 figures in USD) isn't significant when you consider that before quantum computing, that's a difference of an order of 4 days or 8 days to generate your one hash with a very low number of iterations. I can't actually test that random guess for timing because I can't afford a machine with 4 Terabytes of memory.

Iterations - Same idea as MemorySize but you could make this 4 billion today. But again, expect it to take several weeks at 100% on all cores to get your hash. When quantum computers are commodity, this can be revisited. But that's a 2x difference (so say, 6 weeks to generate the hash vs 12 weeks - still a total guess. I don't want to wait to test it. With a tiny memory size and DegreeOfParallelism, it's probably more on the order of hours, rather than weeks). Not 2000x.

The thing to understand about Argon2 is that the very thing that makes it so secure is that it requires tons of CPU and memory to generate the hash. So it's prohibitively slow to brute force - that continues to be true with quantum CPUs because of the memory required (until that bottleneck is also eliminated). It's these crazy high performance requirements that make it so secure (combined with a cyptographically secure hash). A modern, state-of-the-art machine, still can't go anywhere NEAR int.max.

Most OS level calls with sizes are NOT unsigned. But they ARE 64 bit integers. You'll notice that none of these are. That was on purpose. Any one of these values that go anywhere near 0x7fffffff will be untenable for regular use while our CPUs are still powered by electric circuits. And forever will be until they are powered by post-newtonian physics, at which point, whole OSes will likely need major overhauls.

The realistic challenge I face right now with these values is that I probably don't do enough validation to make sure they aren't too BIG. Not that I need to let them get bigger.