Restructured hashing functions. Will separate distinct implementations into separate header files, so that users need only use the implementations that are relevant to them.