Problem Definition
The goal of cryptography is to approximate a process whereby
crypt(x)
conveys no information about x but there exists a function decrypt
such that
decrypt(crypt(x)) == x
If decrypt and crypt were only done in the same run of the same program, you could implement this perfectly using hidden state:
var map = {}; // A hidden hashmap.
function crypt(x) {
var k = unique_unforgeable_value();
map[k] = x;
return k;
}
function decrypt(k) { return map[k]; }
In practice though, crypt
and decrypt
are called by different programs or different runs of the same program, so we need to approximate crypt
using a deterministic function whose output is indistinguishable from random bits -- it has to be incompressible (in the Shannon coding sense) so there are no extra structure bits that can be used to glean information about x.
Algorithms are highly structured therefore compressible. So what we need is a way to get apparent randomness while retaining the determinism that is required for $decrypt \circ crypt = identity$.
Answer
By currying a simple compressible algorithm with an incompressible secret
crypt = crypt_algo(secret)
decrypt = decrypt_algo(secret)
we can approximate the goal above. crypt
and decrypt
have high information content due to the high information content of secret even though crypt_algo
and decrypt_algo
have low information content.
secret
needs to be kept from attackers for this to work since otherwise an attacker could simply do the currying above. The algorithm does not need to be kept secret since it only provides a small portion of the information content of the curried function.
Caveat
"Cryptographic security must rely on a secret key instead of a secret algorithm."
I disagree with the instead of part.
You might get some measure of defense-in-depth by keeping both secret, but testing crypt_algo
is hard, so historically, secret algorithms developed in-house by amateurs have fared worse when subjected to attack than those which have been carefully reviewed by large numbers of professional cryptographers. This is why security by obscurity has gotten a deservedly bad name. The "obscurity" there refers to attempts to keep the algorithm secret as a substitute for properly protecting keys.