Is there a simple decryption algorithm that is idempotent? Something like this:
decrypt(encrypt(x)) === x === decrypt(decrypt(decrypt(encrypt(x))))
Is there a simple decryption algorithm that is idempotent? Something like this:
decrypt(encrypt(x)) === x === decrypt(decrypt(decrypt(encrypt(x))))
Suppose decrypt
is a function f
and encrypt
is a function g
. Hence, we have f(g(x)) = x
and f(f(f(g(x)))) = x
. Hence, we have f(f(x)) = x
, and then f(f(x)) = f(g(x)) = x
. If the result of the decryption function will be a bijective functio, we can conclude that f(x) = g(x)
, and then g(g(x)) = x
. Also, if we suppose g(x)
is bijective, it means f
is inverse of g
. Therefore, g(x) = x
!
Also, if we don't have the bijective assumption for the function g
(which is not too far!), from g(g(x)) = x
, we find that for all input x
the function maps the value of g(x)
to itself. Hence, g(x) = x
by the definition.
Here's another take (but accept OmG's answer).
A decryption function must be injective, because otherwise it is useless.
You want the decryption function to be idempotent.
The only idempotent injective function is the identity function. Proof: Let f be idempotent and injective. Then by the definition of idempotent, f(f(x)) = f(x). Now because f is injective, f(x) maps to f(x), for all x, so hey, that's the identity function. Q.E.D.
The identity function is an affirmative answer to your question "Is there a simple decryption algorithm that is idempotent?"
HOWEVER, the identity function is not a real decryption function, because it would imply the ciphertext and the message must be the same, so in practice that is completely useless, in which case, the best answer to your question is "no."
If decryption has to be idempotent and it actually has to do something, then it must be possible to distinguish (unencrypted) plaintext from (encrypted) ciphertext.
Often this is easy, because you can have the encrypt() function mark the ciphertext with something that just can't occur in plaintext. If the plaintext is text, for example, but the ciphertext can contain any binary data, then you can just include an invalid character at the start of every ciphertext.
If there is no structure that can occur in ciphertext, but can't occur in plaintext, though, then you can still do the job by marking the ciphertext with something that won't occur in plaintext. A reasonable way would be to digitally sign the ciphertext with the same key you use for encryption.
Then your idempotent decryption is just like:
idempotentDecrypt(ciphertext,key) {
if (is_signed(ciphertext, key)) {
return rawDecrypt(removeSignature(ciphertext),key)
} else {
return ciphertext;
}
}
Of course there is a chance that some unencrypted plaintext could turn out to be validly signed just by chance, but that chance is vanishingly small and if your signature algorithm is good then you don't really have to worry about it.
Note that your encryption method also has to be idempotent -- it must leave already-encrypted ciphertext alone -- or it must refuse to encrypt things that are already encrypted.