The following implementation, here for illustration:
void hash(int* bits, int bitsLen, int* out, int outLen){
const int tt[9] = {1,2,0,0,0,1,1,2,2};
int st[128], i, k, j, x, y, a, b; // state st holds 128 trits
for (i=0; i<128; ++i) // initial state setup
st[i] = i%3; //
for (k=0; k < bitsLen + outLen; ++k){ // for each input and output bit
for (j=0; j<32; ++j){ // 32 times for each input and output bit
if (k < bitsLen) // if processing an input bit..
st[0] = bits[k]; // enter that input bit in state
for (i=j%2; i<128; i+=2){ // for each pair of trits in state
x = (i+0)%128; // index of first trit
y = (i+1)%128; // index of second trit
a = st[x]; // get these current trits values
b = st[y]; //
st[x] = tt[a*3+b]; // update these trits per table tt
st[y] = tt[b*3+a]; //
}; //
}; //
if (k >= bitsLen) // building an output bit
out[k-bitsLen] = (st[0] + st[1] + st[2] + st[3]) % 2;
};
}
uses a 3-symbol block cellular automata, with transition rules encoded as the 3x3 table defined by tt
and using a 128-trit (about 202 bits) state space, to materialize an one-way function. It employs k
interactions, where each interaction advances the automata by 32
steps, inserting one of the input bits on the first cell of the automata at each step. Under those conditions, is this function secure against preimage attacks? Here is a test run.
Note: code commented and trimmed for clarity, without changing the output. See previous link or this for the original.