Собственно на написание сподвигло неторопливость работы криптографически-православного SHA-256.
Алгоритм перемешивания взят из реализации SHA-256 BSD, с небольшим усовершенствованием.

При запуске программы выводятся хеши строк, различающихся одним битом.
Выношу на суд сообщества, комментарии приветствуются:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// cyclic diletantic check
struct cdc256_data {
  uint64_t a, b, c, d, e, f, g, h;
  uint64_t position;
};

struct cdc256 {
  union {
    uint8_t data[32];
    uint32_t d32[8];
    uint64_t d64[4];
  };
};

static const struct cdc256_data prime = {
  UINT64_C(0x992E367BE6F0EA1E),
  UINT64_C(0x71DCF41FFACC283F),
  UINT64_C(0xC9581F48D85ABD75),
  UINT64_C(0xE4B93335FF1CE990),
  UINT64_C(0xE51D6424EFEC1E01),
  UINT64_C(0x353867A0E66C2A39),
  UINT64_C(0xA8DBF7B782226B67),
  UINT64_C(0x9F8B7F0DC254488E),
  0
};

static void shuffle(struct cdc256_data * v)
{
  v->a -= v->e; v->f ^= v->h >>  9; v->h += v->a;
  v->b -= v->f; v->g ^= v->a <<  9; v->a += v->b;
  v->c -= v->g; v->h ^= v->b >> 23; v->b += v->c;
  v->d -= v->h; v->a ^= v->c << 15; v->c += v->d;
  v->e -= v->a; v->b ^= v->d >> 14; v->d += v->e;
  v->f -= v->b; v->c ^= v->e << 20; v->e += v->f;
  v->g -= v->c; v->d ^= v->f >> 17; v->f += v->g;
  v->h -= v->d; v->e ^= v->g << 14; v->g += v->h;
}

static void update(struct cdc256_data * a,const struct cdc256_data * v)
{
  a->a -= v->e; a->f ^= v->h >>  9; a->h += v->a;
  a->b -= v->f; a->g ^= v->a <<  9; a->a += v->b;
  a->c -= v->g; a->h ^= v->b >> 23; a->b += v->c;
  a->d -= v->h; a->a ^= v->c << 15; a->c += v->d;
  a->e -= v->a; a->b ^= v->d >> 14; a->d += v->e;
  a->f -= v->b; a->c ^= v->e << 20; a->e += v->f;
  a->g -= v->c; a->d ^= v->f >> 17; a->f += v->g;
  a->h -= v->d; a->e ^= v->g << 14; a->g += v->h;
}

void cdc256_init(struct cdc256_data * code)
{
  static const struct cdc256_data init_value = {
    UINT64_C(0xA640524A5B44F1FC),
    UINT64_C(0xC535059705F0BB7E),
    UINT64_C(0xC8ED76CF6B6EA626),
    UINT64_C(0x531D1E8E254EA59E),
    UINT64_C(0x8C0FE7F3E46E2A80),
    UINT64_C(0x1C53F41FD1E3A7F8),
    UINT64_C(0x08D4DEAAA1C33335),
    UINT64_C(0x4C592980FBE9B011),
    0
  };
  *code = init_value;
}

void cdc256_update(struct cdc256_data * code,const void * data,uintptr_t size)
{
  struct cdc256_data pad;

  code->position += size;

  while( size > 0 ){
    if( size < 64 ){
      memcpy(&pad,data,size);
      memset((uint8_t *) &pad + size,0,64 - size);
      data = &pad;
    }
    update(code,(const struct cdc256_data *) data);
    shuffle(code);
    if( size < 64 ) break;
    data = (const uint8_t *) data + 64;
    size -= 64;
  }

  pad.a = pad.b = pad.c = pad.d = pad.e = pad.f = pad.g = pad.h = code->position;

  shuffle(&pad);
  shuffle(&pad);

  update(code,&pad);

  shuffle(code);
}

void cdc256_final(struct cdc256_data * code,struct cdc256 * cdc256)
{
  uintptr_t c;
  const uint8_t * p = (const uint8_t *) code;

  for( c = 0; c < 4; c++, p += 16 ){
    uint64_t h = 5381;
    h = (h << 5) + h + p[0];
    h = (h << 5) + h + p[1];
    h = (h << 5) + h + p[2];
    h = (h << 5) + h + p[3];
    h = (h << 5) + h + p[4];
    h = (h << 5) + h + p[5];
    h = (h << 5) + h + p[6];
    h = (h << 5) + h + p[7];
    h = (h << 5) + h + p[8];
    h = (h << 5) + h + p[9];
    h = (h << 5) + h + p[10];
    h = (h << 5) + h + p[11];
    h = (h << 5) + h + p[12];
    h = (h << 5) + h + p[13];
    h = (h << 5) + h + p[14];
    h = (h << 5) + h + p[15];
    cdc256->d64[c] = h;
  }
}

void cdc256_print(FILE * stream,const struct cdc256 * code)
{
  fprintf(stream,
    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
    "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
    code->data[0],
    code->data[1],
    code->data[2],
    code->data[3],
    code->data[4],
    code->data[5],
    code->data[6],
    code->data[7],
    code->data[8],
    code->data[9],
    code->data[10],
    code->data[11],
    code->data[12],
    code->data[13],
    code->data[14],
    code->data[15],
    code->data[16],
    code->data[17],
    code->data[18],
    code->data[19],
    code->data[20],
    code->data[21],
    code->data[22],
    code->data[23],
    code->data[24],
    code->data[25],
    code->data[26],
    code->data[27],
    code->data[28],
    code->data[29],
    code->data[30],
    code->data[31]
  );
}

void main(void)
{
  struct cdc256_data ctx;
  struct cdc256 b;
  
  char t[] = "0123456789ABCDEF";

  cdc256_init(&ctx);
  cdc256_update(&ctx,t,strlen(t));
  cdc256_final(&ctx,&b);

  fprintf(stderr,"%s\n",t);
  cdc256_print(stdout,&b);

  t[3] |= 0x40;

  cdc256_init(&ctx);
  cdc256_update(&ctx,t,strlen(t));
  cdc256_final(&ctx,&b);

  fprintf(stderr,"%s\n",t);
  cdc256_print(stdout,&b);
}


Компилируем GCC.