We can convert tfunc
equations to
A0^A1^A2 = B0^(maj(A3,A4,A5)<<1)
A1^A2^A3 = B1^(maj(B0,A6,A7)<<1)
A2^A3^A4 = B2^(maj(B1,A0,A1)<<1)
A3^A4^A5 = B3^(maj(B2,A2,A3)<<1)
A4^A5^A6 = B4^(maj(B3,A4,A5)<<1)
A5^A6^A7 = B5^(maj(B4,A6,A7)<<1)
A6^A7^A0 = B6^(maj(B5,A0,A1)<<1)
A7^A0^A1 = B7^(maj(B6,A2,A3)<<1)
In these, knowing the Bj
and the i
low-order bits of the Aj
lets us compute the right-hand side to i+1
low-order bits, thus the left-hand side to i+1
low-order bits, thus the Ai
to ì+1
low-order bits using the invert matrix/equations already in the question.
We can apply this for ì
from 0
to n-1
to fully invert the function. Baring mistakes, code could be (not tested):
function inv_tfunc([B0, B1, B2, B3, B4, B5, B6, B7]) {
M = (((1<<(n-1))-1)<<1)+1; // mask for n bits
A0 = A1 = A2 = A3 = A4 = A5 = A6 = A7 = 0; // initial value is immaterial
for (i = 0; i < n; i = i + 1) {
C0 = (B0^(maj(A3,A4,A5)<<1))&M;
C1 = (B1^(maj(B0,A6,A7)<<1))&M;
C2 = (B2^(maj(B1,A0,A1)<<1))&M;
C3 = (B3^(maj(B2,A2,A3)<<1))&M;
C4 = (B4^(maj(B3,A4,A5)<<1))&M;
C5 = (B5^(maj(B4,A6,A7)<<1))&M;
C6 = (B6^(maj(B5,A0,A1)<<1))&M;
C7 = (B7^(maj(B6,A2,A3)<<1))&M;
A0 = C1^C2^C4^C5^C7;
A1 = C2^C3^C5^C6^C0;
A2 = C3^C4^C6^C7^C1;
A3 = C4^C5^C7^C0^C2;
A4 = C5^C6^C0^C1^C3;
A5 = C6^C7^C1^C2^C4;
A6 = C7^C0^C2^C3^C5;
A7 = C0^C1^C3^C4^C6;
}
return [A0, A1, A2, A3, A4, A5, A6, A7];
}
Note: the &M
insures that variables stay within n
bits. If variables have exactly n
bits (e.g. in C uint32_t
variables with n = 32
), we can do without M
and &M
. If variables have some fixed width larger than n
, we can deffer the &M
to the return step.