[1] https://www.tarsnap.com/scrypt.html
[2] https://github.com/jedisct1/libsodium
[1] https://www.tarsnap.com/scrypt.html
[2] https://github.com/jedisct1/libsodium
Don't use a JS translation of Nacl. Nacl goes to pains to ensure that it doesn't expose side channels; no Javascript implementation can make the claims Nacl makes.
I'd say that scrypt is most useful when generating derived keys for file encryption. For login passwords you probably want a fairly low work factor (say, 0.1 seconds), both to make logins responsive and to make it harder for an attacker to use login attempts to DoS you; but for file encryption you can easily spend 5 seconds or more.
So there are no real problems that adding scrypt solves, besides "making it slower".
for P in password candidates do:
compute K = KDF(P, salt);
M_0 = decrypt(block #0 of cyphertext, K, IV);
if M_0 looks like plaintext:
store P for future analysis
fi
od
Encryption using a passphrase needs a good KDF just as much as login password hashing does.As for password hashing, that is a very different application than deriving a key for encryption. You are storing the result (usually in a database), and in the case there is a leak, hoping that no one can brute-force the passwords. This is when you start the process of changing salts and work values (in the case of scrypt), and getting everyone to change their password. Using a KDF in this case makes a lot of sense.
I also had a quick look at the tarsnap source code, and I see you do exactly that for the passphrased keyfile.
Most encryption algorithms are already designed to take a users key, and apply them in a secure fashion. Unless you aren't using such an algorithm, you should trust the crypto primitives that have already been built for you. Of course, many people will have special use cases, but they should already know what they are.
What specifically are the side channels you see that Javascript exposes?
The usual side channel is timing. Some numeric operations take longer than others depending on the key, and an adversary can measure these to narrow down possible keys: https://en.wikipedia.org/wiki/Timing_attack
Javascript engines have complicated numeric type conversion rules, together with single-entry type caches that seem very likely to leak.
While I agree that absence of evidence is not evidence of absence I have to take you up on that second statement. I'd say you deserve an encryption that's carefully constructed to provide appropriate protection against a threat model matching the use case.
A case in point would be MD5. MD5 is vulnerable to collisions, does that mean that we should use MD5 for passwords? Of course not but because of moore's law and scrypt, not because of collisions. Should we use MD5 for hashing content? For anything forensic, no. For situations where collisions aren't important, perhaps yes.
Many software crypto systems are susceptible to direct leakage through RAM, that doesn't mean that we shouldn't use them.
Why assume the risk?
I see where you're coming from with it but to take your point I can pull keys out of a memory dump, who cares which process it comes from? In this case does it mean we should all wait for a perfect OS that scrubs memory on everything properly and encrypts swap?
That's not to say you're wrong, I think you have some valid points but in every other domain it appears there's a good enough level and when I at least encounter UK government crypto we're told it's the same. The thing about the cryptocat thing is that there are questions about transparency that are valid (and I've seen your conversation on twitter and agree with some of your points), but I'm trying to avoid falling into that situation.