kcrypt2
Disclaimer⌗
You’ve heard what they say about rolling your own crypto, right? Don’t do this at home. I would not deploy the program that I have just made into production. It’s not just algorithmic mistakes that you can make: individual implementations have a certain set of assumptions they operate in and for most applications the most stringent security measures are necessary. Leaking information through side channels and variable running times is a show stopper for cryptographic suites. You have been warned.
The idea⌗
I am not a cryptography expert (I never claimed to be), but I know a few things about math and CS. Fortunately, this is largely enough to make something interesting.
My algorithm is based on the NP-hard problem of polynomial reconstruction. Encryption is performed by following these steps:
- Generate a key from a CSPRNG. The key is 624 32-bit unsigned integers.
- Chop the message up into 64-byte blocks. Perform the remaining steps for each block.
- Using MT19937, generate a random permutation of integers from 0 to 128 and a bit vector of 128 bits with exactly a half of the bits randomly set.
- Treat the message as a set of 8-bit unsigned integers. Interpolate a polynomial where is the message and is a vector of 8 random numbers from MT19937 of degree 72 in the Galois field of order 256 using the Lagrange interpolation formula.
- Evaluate this polynomial at 128 points from . This gives us a vector of 128 8-bit unsigned integers (which are statistically indistinguishable from noise) from which the original message can be recovered by re-interpolating and and evaluating at the first 64 points.
- Corrupt 64 of the 128 points with cryptographically secure random numbers from
/dev/urandom
. Permute the 128 points using the permutation generated earlier. - This is the ciphertext. If we know which of the points have been corrupted, we can recover the polynomial by interpolating on the known 64 good points and the 8 random points known by the decoder and derived from the key. The message is then this polynomial evaluated at the first 64 points.
Without knowing the key, the attacker would have to try all the possible methods of eliminating the 64 corruted points, which is computationally infeasible. To my knowledge, there is no faster way because the problem of polynomial reconstruction is NP-hard. There are algorithms to recover the polynomial if the amount of errors is smaller than 32 (e.g. Berlekamp-Massey), but they are not applicable here as we always make 64 errors.
The code⌗
Feedback⌗
Think that this code sucks? Found a fatal flaw that I missed? Shoot me an e-mail.