the simple weakness here is that this code pretends to be a block cipher but it really is a stream cipher:
for(i = 0; i != 16; ++i)
secret[i] ^= key[i] ^ m[i];
because
secret
at this point contains data derived from
key
, we can see that
secret[i] ^= key[i]
is really the last step of keystream derivation. the entire line (
secret[i] ^= key[i] ^ m[i];
) is just a stream cipher operation: bitwise XORing a message with a keystream.
block ciphers can be used as stream ciphers (CTR mode) but not really the other way around, and stream ciphers have their own problems/security considerations (the need for a unique IV). so you shouldn't compare its speed and security with AES but with other stream ciphers. stream ciphers are faster in general, and they are often implemented in hardware.
how to see if your're are cipher is a good stream cipher? well, stream ciphers are basically cryptographically secure RNGs. and as an RNG of any kind, your're are cipher has a critical flaw: as it's written, it uses a 16-byte seed to generate a 16-byte output. for comparison, Mersenne Twister generates 2
19937-1 bytes from a 4-byte input. and Mersennte Twister isn't even a cryptographically strong RNG (it can be reversed give 624 consecutive outputs). other important features of a good stream cipher (which I didn't bother testng for yet) are:
- irreversible - operations used to generate keystream cannot be easily reversed, so that if you know one keystream state you cannot get the previous one
- impossible to clone - as mentioned with regards to Mersenne Twister, observing keystream should not be enough to replicate a generator instance (which would allow the attacker to generate arbitrary keystream bytes)
- entropic - a good keystream should look just like random noise