Hey, like you I decided to dive into cryptography coming from a different background. Although this quote is not directly related to your problem it can be safely applied to it:
"Almost certainly you will get the urge to invent new cryptographic algorithms, and will believe that they are unbreakable. Don't resist the urge; this is one of the fun parts. But resist the belief; almost certainly your creations will be breakable, and almost certainly no one will spend the time breaking them for you. You can break them yourself as you get better."[1]
The problem that Schneier is referring to is that doing a careful analysis (that is required if you want to use your crypto in production) is tedious, time consuming, and requires expertise in the area to know most blank spots of the algorithms (heck a single one is hard enough). That's why he recommends you to be have enough experience breaking many algorithms before you make any serious claim about your the safety of your crypto.
So all in all it's great that you got the interest in the area, there is a lot of work needed in OSS. But be very careful about claiming that your lib is ready for production. What you got is a bunch of volunteers to glance at your code. Few cryptographers (if any) will seriously try to break it.
Note that the author is not inventing crypto algorithms, rather implementing them (although the part about XChaCha20 being a mix of ChaCha20 and XSalsa20 is IMHO dancing on the line). Still a risky business, and tricky to get right, but several orders of magnitude safer than "hey, what if we just XORed everything with a random number? Unbreakable, eh?"
> the part about XChaCha20 being a mix of ChaCha20 and XSalsa20 is IMHO dancing on the line
It was a few months ago. Then Libsodium danced on the same line, and I was able to compare the results (they behave the same, phew).
It's not inventing crypto either: it's a straightforward application of what was done to Salsa20. The security reduction that worked for XSalsa20 (guaranteed secure if Salsa20 is secure) applies to XChacha20 as well.
> Then Libsodium danced on the same line, and I was able to compare the results (they behave the same, phew).
Do they really? What about timing attacks? Does all your code run in constant time? If not, there's a whole class of vulnerability that basically will only be found when experienced attackers have a chance to poke at it. Timing attacks are a great example of why "don't roll your own crypto" is sound advice. No amount of testing your library against a reference library will uncover them.
Can't say for sure, but it look like they didn't have an independent implementation to compare to. Just like me a few months a go.
---
> What about timing attacks?
Monocypher is immune.
First, the primitive were chosen precisely because they are easily immunised against timing attacks.
Second, this is easily checked simply by looking at the source code: no secret-dependent branches, no secret-dependent indices, and that's about it. One doesn't need to be an expert to check that, a junior programmer could do it after being told what to look for.
What's wrong with xoring with a stream of random numbers? Isn't it how stream ciphers work? Get a good cryptographic RNG, initialize it properly with a long enough key and you should be fine.
You're right about the theory, but you're also wrong about how to implement - which is the point of telling people not to roll their own crypto.
What about reseeding or prediction resistance? How do you handle biased entropy input from that hairdryer someone is blowing on your chips? Oops, the quantum random number generator card doesn't work anymore after adding that extra GPGPU to the system.
You wouldn't want true random numbers anyways. If you're encrypting it, then you'll want to decrypt it later. That means you'll need the random data you used again. If you had a secure channel over which to send or store the random data, then you could just use that channel to send or store the plaintext itself (note that the random data will be the same length as the plaintext). Such a system could only be useful if the cryptographic key was shorter than the plaintext. So it would have to be a deterministic RNG, and you would only need the seed and the ciphertext in order to decrypt.
Also, if someone has acccess to the hardware, then you're screwed. No one would bother wasting time with a hairdryer. If the plaintext was on your harddrive, they would just grab that and run.
I think you missed the point of the comment, which wasn't about physical possession of a computer.
You also make assumptions, such as chips being inside the computer, when they can in fact be in an outside environment-based RNG. The hairdryer example is the canonical and prototypical weakness in that particular type of "rng". I'll try to be explicit about that in the future.
I didn't write anything about environment-based RNG. RNG must be deterministic and seeded by preshared encryption key. One point of using a cryptographically secure RNG is that it should not be possible to learn the seed by observing the output of the RNG without bruteforcing the key.
If you had a RNG that sampled some hardware noise but then you altered the environment by introducing extreme temperatures, maybe the RNG would end up with biased output. A simple example: you can use a camera as a good source of randomness, even taking a picture of a wall indoors. But if an attacker was able to flood that room with light and overwhelm your sensor, he could predict the image would be 100% white pixels or near to it and guess the random output.
But the comment is exaggerating. Encryption algorithms do not handle the case of your entropy source being compromised. Good RNG algorithms like Yarrow try to mitigate this somewhat.
Even if you need a real entropy-based RNG, e.g. for key generation, you need to gather entropy once at the beginning to seed the RNG. Then running RNG does not need any more entropy, so your hairdryer trick won't work. A common myth I hear is that "entropy" gets "depleted" during RNG operation, but in fact it does not. You only need enough bits of entropy once at the beginning, equal to the internal RNG state length.
Strong RNG designs re-seed to deal with compromise or poor seeding. That way if an attacker has temporary read access they do not permanently compromise the system going forward. Or if on boot you are in a compromised or low entropy environment the system will improve over time. Perhaps the utility of this is arguable. If an attacker is able to see your private RNG state then it is most likely game over. But it is a cheap operation with little downside and again, designs like Yarrow put considerable time into thinking it through.
Well, to be fair, a good implementation should throw some simple statistical sanity checks at RNG input during self-test and throw an error when it doesn't pass. Passing such tests doesn't indicate that the RNG is cryptographically secure, but failing them indicates that it is insecure.
Nothing wrong with what you wrote - but note the subtle difference between "XORing a stream of random numbers" (potentially viable, even unbreakable when using a OTP) and "XORing a random number" (essentially a Caesar cipher, kid-sister encryption).
> note the subtle difference between "XORing a stream of random numbers" (potentially viable, even unbreakable when using a OTP) and "XORing a random number" (essentially a Caesar cipher, kid-sister encryption)
No, that's not a difference. A "stream of numbers" is just one very large number. What you're worrying about is how large the numbers are, not whether there's one or more than one.
Original point was certainly to point out the most common mistake of typical homegrown cryptosystems. Even programmers who know that XORing stuff with constant byte is not viable encryption can produce systems that do essentially the same thing (usually by XORing everything with RC4 output with long lived or even constant key)
"Almost certainly you will get the urge to invent new cryptographic algorithms, and will believe that they are unbreakable. Don't resist the urge; this is one of the fun parts. But resist the belief; almost certainly your creations will be breakable, and almost certainly no one will spend the time breaking them for you. You can break them yourself as you get better."[1]
The problem that Schneier is referring to is that doing a careful analysis (that is required if you want to use your crypto in production) is tedious, time consuming, and requires expertise in the area to know most blank spots of the algorithms (heck a single one is hard enough). That's why he recommends you to be have enough experience breaking many algorithms before you make any serious claim about your the safety of your crypto.
So all in all it's great that you got the interest in the area, there is a lot of work needed in OSS. But be very careful about claiming that your lib is ready for production. What you got is a bunch of volunteers to glance at your code. Few cryptographers (if any) will seriously try to break it.
[1] https://www.schneier.com/crypto-gram/archives/1999/1015.html...