I am willing to write a Whitebox Crypto unit using ChaCha20 algorithm (Bernstein, D. 2008) for an input consisting of a single block. The fact it is going to be a single block cipher is of special importance here, as otherwise, the simple algorithm below wouldn't apply.
The principle is quite simple and reuses some logic from Chow et al: transform all inner block (formed by a series of 8 quarterround()
functions looped 10 times) into a lookup table that takes the nonce as input. Notice that here, again, I am not considering more than one block of input, otherwise what I am proposing here wouldn't make sense, as a second round of the algorithm would have different x[0]..x[3]
.
In other terms, this is what I am trying to do. As in RFC 7539, instead of:
chacha20_block(key, counter, nonce):
state = constants | key | counter | nonce
working_state = state
for i=1 upto 10
inner_block(working_state)
end
state += working_state
return state
end
I am willing to do something like:
chacha20_1st_block(nonce):
return lookup_tables(nonce)
end
precomputing lookup tables where the counter is always 0 (or any other constant), and dimensioning the nonce such as the table size doesn't get too long, complementing the other bits with zero. For instance, if we consider nonces consisting of 13 bits, it is possible to generate 8192 tables containing 16 words of 32 bits, or exactly 512kB. Other sizes may be obtained by adjusting the nonce size.
I'm afraid I am making obvious questions here, but:
- Am I considerably reducing the complexity of finding the original key this way?
- Am I increasing attack chances?
EDIT 1: I left an implementation of the algorithm above in https://github.com/balena/chacha20-whitebox.