A cipher may be converted into a hash function by simply discarding part of the result. While that isn't the fastest way to produce a hash function, and it certainly won't work in cases where one might need a bijective hash function (e.g. a function which will take 128 bits of input and yield 128 bits of output, such that every possible output value will occur for some input) it should work adequately for many purposes.
The only type of bijective one-way function I've been able to formulate by myself would be (example given for 128->128):
- Map an input of all zeroes to an output of all zeroes.
- For any other input, load a linear feedback shift register with all 1's, interpret the input as a 128-bit shift count, and run the shifter for that many counts (note that this does not require actually doing 2^128 steps!).
Reversing the one-way hash would require solving the discrete log problem. For largeish numbers of bits, that is indeed a hard problem, but unfortunately I believe there are approaches for solving it with n=128. I suspect using a number base larger than 2, and using a fundamental operation other than xor, might improve the strength of the approach, but I have no idea how to analyze such tweaks to ensure the function is bijective.