WjCryptLib: single-file hash and cipher primitives you can drop into a C project
Public Domain C Library of Cryptographic functions. Including: MD5, SHA1, SHA256, SHA512, RC4, AES, AES-CTR, AES-OFB, AES-CBC
At a glance
- What is it?
- WjCryptLib is a public domain C library of cryptographic primitives, where each algorithm lives in one .c file and one .h file that you copy into your project rather than link as a dependency. It covers MD5, SHA-1, SHA-256, SHA-512, RC4 and AES in CBC, CTR and OFB modes.
- Who is it for?
- Adopt WjCryptLib when you need a hash or a cipher in C and want to vendor the source rather than take on a dependency, since each algorithm is a self-contained file pair and the whole library is in the public domain. Do not adopt it for new cryptographic design, because the README says MD5, SHA-1 and RC4 are broken and should not be used for new work.
- Can I use it commercially?
- Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 40 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A library you copy files from, not a package you depend on
WjCryptLib is a public-domain collection of cryptographic primitives in C: MD5, SHA-1, SHA-256, SHA-512, RC4, AES, and AES in CBC, CTR and OFB modes. The README states the arrangement plainly: each module is independent, so a single .c file and matching .h file are usually all that is needed.
That is the whole design in one sentence, and it is the reason to choose this over a general purpose crypto library. There is no dependency tree, no version constraint, no package manager entry, no transitive update surface and nothing to keep in step with a release cadence. You take the two files for the one algorithm you need and you own them.
The delivery mechanism is documented in the Algorithms table. To use a single algorithm, you copy the files listed into your project. MD5 is WjCryptLib_Md5.{h,c}, SHA-1 is WjCryptLib_Sha1.{h,c}, SHA-256 is WjCryptLib_Sha256.{h,c}, SHA-512 is WjCryptLib_Sha512.{h,c} and RC4 is WjCryptLib_Rc4.{h,c}. The AES modes are WjCryptLib_AesCbc.{h,c}, WjCryptLib_AesCtr.{h,c} and WjCryptLib_AesOfb.{h,c}, each of which needs the base AES files as well.
That last detail is a small design decision with real consequences. The modes are not self-contained; they build on the AES core. So AES-CBC means three file pairs rather than two, and any change to the block cipher propagates to all three modes.
The portability claim is worth noting for embedded work. The code is portable across little-endian and big-endian architectures, builds on macOS, Linux and Windows, and supports OpenMP for parallel AES-CTR. The OpenMP support is unusual in a library this small, and it is the one place where the code departs from being strictly a set of independent primitives, since the parallel path only exists for the counter mode.
The primary language is C, the default branch is main, and the homepage is waterjuice.org. The copyright line in the README reads Placed into Public Domain by WaterJuice 2013 to 2026, so the code has been in the public domain for over a decade.
The algorithm list and the advice to not use half of it
The README has an Algorithm choice section, and it is unusually direct for a library that ships broken primitives.
The guidance: MD5, SHA-1 and RC4 are included for interoperability with existing systems but are considered cryptographically broken and should not be used for new work. Prefer SHA-256 or SHA-512 over MD5 and SHA-1, and prefer an AES mode over RC4.
This is worth pausing on. The presence of MD5, SHA-1 and RC4 is not accidental and it is not a claim that they are safe. It is an interoperability decision. If you are reading a legacy protocol, verifying a file against a checksum someone published years ago, or talking to a device whose firmware will not change, you need those algorithms, and the library provides them so you do not have to find and vendor someone else's broken copy.
What the library does not offer is a modern authenticated encryption mode. There is no GCM, no ChaCha20-Poly1305, no Poly1305, and the AES modes present are CBC, CTR and OFB, all of which are unauthenticated. CTR and OFB are stream-like constructions that provide confidentiality without integrity, and CBC without a separate MAC is malleable. If you need to encrypt and authenticate in one pass, this library does not have what you need, and that is a real gap rather than a stylistic one.
The topic tags on the repository confirm the scope: aes, aes-cbc, aes-ctr, aes-ofb, md5, rc4, sha1, sha2, sha256 and sha512. There is nothing else in the box.
The licence is the Unlicense, and the README says the software is released into the public domain, referring to the UNLICENSE file and to unlicense.org. For a library meant to be copied into proprietary code, that is the most permissive arrangement available: no attribution requirement, no copyleft obligation on the host project.
Building with CMake, and the Makefile convenience wrapper
The canonical build setup is CMakeLists.txt, and CMake generates build files for any system: Visual Studio projects on Windows, Unix Makefiles or Ninja on Linux and macOS, Xcode and so on. The two commands are the whole thing.
cmake -S . -B build
cmake --build buildA thin Makefile wrapper is provided as a convenience that delegates everything to CMake. It works on macOS, Linux, and Windows native when GNU Make is installed.
make build # configure and build everything
make test # build then run the test harness via ctest
make clean # remove the build tree
make help # show available targets (default)The wrapper itself is a good example of restraint. It exists so the project has the same make build, make test and make clean entry points as other projects, and all real work is delegated to cmake.
Two details in the Makefile are practical rather than cosmetic. The build target runs cmake -S . -B $(BUILD) and then cmake --build $(BUILD), with BUILD defaulting to build, so the configure step is idempotent and re-running the target is safe. And the test target runs ctest with -C Debug and --output-on-failure from inside the build directory, with the comment that ctest knows how to locate the binary regardless of generator, whether that is multi-config Visual Studio, Ninja or Unix Makefiles. That last point matters more than it looks: with a multi-config generator, ctest needs the configuration name, and the wrapper supplies Debug.
There is also an ensure-cmake prerequisite that checks cmake --version on PATH before anything else runs, quietly on success and printing a message pointing at cmake.org if it is missing. The clean target uses cmake's portable rm -f operation rather than rm -rf so the recipe works in cmd.exe as well as POSIX shells.
The Windows note in the Makefile comment names two package managers for getting GNU Make, choco install make and scoop install make.
The command-line programs in projects/
The projects/ directory holds several programs that compile to command-line executables, and they are what turns a file-copy library into something you can check your port against.
WjCryptLibTest verifies every algorithm against known test vectors, and the README describes it as useful when porting to a new platform. That is its real purpose. Vendoring a .c file into an unfamiliar toolchain or an unfamiliar architecture means you need to know the implementation still agrees with the specification, and the test vector program is the answer to that question without a separate reference library.
The rest are small utilities for looking at the output directly. Md5String, Sha1String, Sha256String and Sha512String compute a hash of a string given on the command line. Rc4Output outputs an RC4 stream as hex, and AesCtrOutput and AesOfbOutput do the same for AES-CTR and AES-OFB streams. AesBlock encrypts or decrypts a single AES block.
That set covers the cases where you want to see bytes rather than trust a function. A hex dump of a keystream is how you would sanity check a counter mode implementation's block counter and endianness, and a single-block AES encrypt is how you would check a key schedule against a published vector. None of these are applications; they are the tools you reach for when something looks wrong and you need to narrow down where.
The absence of a matching CBC demo is noticeable given that AES-CBC is in the library. The projects listed cover AES block operations and the two stream modes, and the test program covers the rest against vectors, so CBC verification is available but through the vector suite rather than through a standalone hex dumper.
The library also carries a ChangeLog.md with the full version history. The recent releases are Version 3.0.0 from 2026-05-17, with Version 2.3.0 and 2.2.0 both from 2018, so there was a long gap and then a substantial version bump, which usually means the build system or the API changed rather than the algorithms.
Where WjCryptLib is the wrong choice
There are three limits, and the first is the one the README implies without ever stating.
The first is that there is no authenticated encryption anywhere in the library. AES in CBC, CTR and OFB, with no GCM and no Poly1305, means every construction you build on top is confidentiality only. For a network protocol, a file format or anything stored at rest, you now need a MAC and a key management scheme, and you have to get the combination right yourself, including the encrypt-then-MAC ordering that CBC needs to avoid padding oracle attacks. The library will not tell you that, and it will not stop you from getting it wrong. If you need a modern AEAD, you need a different library.
The second is that this is a set of primitives, not a cryptographic library in the fuller sense. There is no key derivation, no password-based encryption, no key generation, no certificate handling, no secure random source, no constant-time comparison helper and no AEAD. Each of those is a component you would otherwise expect a crypto library to provide, and their absence is what makes the library small enough to copy into a project. It also means the security of your use depends on code you write around these files.
The third is the maintenance and support profile, and here the picture is mixed. The code has been in the public domain since 2013, so it is stable in the sense of not changing under you, and Version 3.0.0 in May 2026 shows someone is still working on it, with the last push on 2026-09-13. But the last two releases before that were in 2018, and the public-domain placement means there is no supported channel, no security advisory process and no promise of a fix if something is found. For an algorithm like SHA-256 or AES, that is largely academic, since the algorithms are fixed and the implementations are small enough to read. For anything involving the modes' interaction with your protocol, it is not academic at all.
The honest alternative depends on what you are actually solving. If you are writing C and want a maintained implementation with modern modes, libsodium covers hashing, password hashing, secret-key cryptography and constant-time operations with a deliberately small API, and it is what most projects reach for when the requirement is C plus a real crypto library. If you need certified primitives and are willing to depend on a library, OpenSSL or libsodium's underlying primitives come with test vectors and, in the case of a FIPS-validated library, certification. If you are on a language with a standard library, the platform's own hash and cipher implementations are usually both maintained and faster, because they use the CPU's AES and SHA instructions.
What WjCryptLib does instead is give you four kilobytes of vendored code with no dependency, no licence obligation and no API to learn, for the case where you need a hash and a cipher in C and you would rather not take a dependency at all.
Editorial conclusion
Adopt WjCryptLib when you need a hash or a cipher in C and want to vendor the source rather than take on a dependency, since each algorithm is a self-contained file pair and the whole library is in the public domain. Do not adopt it for new cryptographic design, because the README says MD5, SHA-1 and RC4 are broken and should not be used for new work. Before you copy anything in, read the Algorithm choice section and confirm the primitives you need are the ones you actually want, and note the last push was on 2026-09-13 with Version 3.0.0 from 2026-05-17.
Frequently asked questions
What is WjCryptLib and which algorithms does it include?
It is a public domain collection of cryptographic primitives in C covering MD5, SHA-1, SHA-256, SHA-512, RC4, AES and AES in CBC, CTR and OFB modes. Each module is independent, so a single .c file and matching .h file are usually all that is needed.
How do I use WjCryptLib in my own project?
You copy the files for the algorithm you need into your project, listed in the README table, such as WjCryptLib_Sha256.{h,c} for SHA-256 or WjCryptLib_AesCtr.{h,c} together with the base AES files for AES-CTR. There is no package to install and no dependency to resolve.
Which WjCryptLib algorithms should I avoid for new work?
MD5, SHA-1 and RC4 are included for interoperability with existing systems but are considered cryptographically broken and should not be used for new work. The README advises preferring SHA-256 or SHA-512 over MD5 and SHA-1, and preferring an AES mode over RC4.
How do I build WjCryptLib and run its tests?
Run cmake -S . -B build and then cmake --build build, or use the Makefile wrapper with make build, make test, make clean and make help. The test target builds and then runs the bundled harness via ctest with --output-on-failure.
What licence does WjCryptLib use?
It is released into the public domain under the Unlicense, with the README referring to the UNLICENSE file and to unlicense.org. The code is marked as placed into public domain by WaterJuice from 2013 to 2026, which means it can be copied into a proprietary project with no attribution or copyleft requirement.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/waterjuice-wjcryptlib)Was this useful?