Fractal Crypt-Hash (FCH) is an experimental cryptographic hash function based on a fractal (self-similar) recursive structure rather than traditional round-based compression.
FCH is a research / experimental hash design and reference implementation. It has not undergone broad public cryptanalysis or independent security review.
Do not use FCH in production or for security-critical purposes, including (but not limited to):
- authentication, signatures, tokens, or MACs
- password hashing / key derivation
- integrity checks where adversaries exist
- any scenario where a broken hash causes harm
This repository is intended for learning, experimentation, benchmarking, and discussion.
Unlike conventional hash functions that rely on repeated rounds, FCH achieves diffusion through recursive fractal decomposition.
A small change in the input propagates:
- locally at leaf nodes,
- recursively through variable n-way splits,
- and globally at the root via recompression.
- Fractal recursive hash structure
- Variable n-way (2–6) splitting derived from the entire node input
- Order-dependent tree recombination
- Separate root, internal-node, leaf, and child domains
- Full-width leaf states with XOR / ADD / ROTATE / S-box mixing
- Recompression at each internal node
- Deterministic, non-keyed hash function
| Variant | Output Size | Internal State |
|---|---|---|
| FCH-256 | 256 bits | 4 × uint64 |
| FCH-512 | 512 bits | 8 × uint64 |
uint8_t out256[32];
uint8_t out512[64];
int ok256 = fch_hash_256_checked(data, len, out256);
int ok512 = fch_hash_512_checked(data, len, out512);The checked functions return 1 on success and 0 on invalid input,
allocation failure, or an unsupported input length. The original void
functions remain available as compatibility wrappers.
FCH provides a streaming API that writes incoming chunks to an anonymous temporary file. Finalization reads that data through fixed-size buffers, so RAM usage does not grow with the total input size. The digest is identical to the one-shot API. This mode requires temporary-file support and can be slower.
#include "fch_stream.h"
fch256_ctx ctx;
fch256_init(&ctx);
fch256_update(&ctx, chunk1, chunk1_len);
fch256_update(&ctx, chunk2, chunk2_len);
int ok = fch256_final_checked(&ctx, out256);
fch256_free(&ctx);After finalization, further updates and repeated finalization are rejected. The CLI uses the same bounded-memory path for files and standard input.
Build the CLI:
cd build
make allHash a file:
./fch -256 path/to/file
./fch -512 path/to/fileHash stdin:
cat path/to/file | ./fch -256The implementation includes:
- Statistical avalanche tests (length/bit diffusion)
- Determinism tests (same input → same output)
- Boundary condition tests
- Structural invariant tests (split coverage)
- Portability and domain-separation tests
- Split-configuration sensitivity tests
The reference implementation includes extensive tests for determinism, boundary conditions, structural invariants, and statistical diffusion behavior.
Test programs:
tests/test_avalanche.ctests/test_consistency.ctests/test_boundaries.ctests/test_invariants.ctests/test_portability.ctests/test_vectors.ctests/test_split_sensitivity.c
Build/run:
cd build
make checkThe CI workflow runs the suite with GCC and Clang and also runs AddressSanitizer and UndefinedBehaviorSanitizer.
If make is unavailable (Windows), you can compile directly with gcc:
gcc -Wall -Wextra -O2 -Iinclude tests/test_consistency.c src/*.c -o build/test_consistency.exe
gcc -Wall -Wextra -O2 -Iinclude tests/test_boundaries.c src/*.c -o build/test_boundaries.exe
gcc -Wall -Wextra -O2 -Iinclude tests/test_invariants.c src/*.c -o build/test_invariants.exe
gcc -Wall -Wextra -O2 -Iinclude tests/test_avalanche.c src/*.c -o build/test_avalanche.exe
gcc -Wall -Wextra -O2 -Iinclude tests/test_vectors.c src/*.c -o build/test_vectors.exe
gcc -Wall -Wextra -O2 -Iinclude tools/fch.c src/*.c -o build/fch.exe
build\\fch.exe -256 README.md