Back to homepage
The sha_digest package is an ANSI C implementation of the Secure Hashing Algorithms SHA-1, SHA-224, SHA-256, SHA-384 and SHA512 as described in FIPS PUB 180-3, published October 2008.
You can either use it as a library to be linked against your programs, thus incoorporting all the above hashing algorithms, or pick one of the source files, implementing the algorithms, and use that within your programs (each SHA algorithm has its own source file that can be used independently).
The implementation is written in (hopefully) standard compliant C (ANSI C89) and should work without dependencies on the underlying hardware (i.e. it should run on e.g. 32-bit as well as 64-bit or even less common systems) or the operating system.
The code allows hashing of both byte- and bit-oriented messages, i.e. the number of bits that can be hashed can be arbitrary (of course within the limits laid out by FIPS 180-3, i.e. up to 2^64-1 bits for SHA-1, SHA-224 and SHA-256 and 2^128-1 for SHA-384 and SHA-512) and is not restricted to a multiple of 8 as it's the case with most other implementations.
While I implemented the SHA algorithms as far as my abilities and understanding of the FIPS 180-3 standard cited above allowed me I'm not claiming that it's error-free. Thus if you intend to use it, especially if in cryptographic applications, you definitely MUST review and test the code carefully yourself! (You get what you paid for;-)
On systems where the char type has more than 8 bits (i.e. CHAR_BIT as defined in <limits.h> is larger than 8) only the lowest 8 bits of each byte of the data passed to the appropriate function for hashing will be taken into account, higher order bits simply get ignored.
Due to trying to be platform-agnostic this implementation might be a bit slower than those that can make assumptions about the availability of certain types of unsigned integers (which are heavily used in these algorithms) or the endianess on the architecture the program is running on.
The way the library etc. gets built is rather UNIX specific and probably will need some tweaking to work on other types of systems.
The package can be downloaded here (total size is about 40 kB):
The package contains the documentation - there are only four functions needed for each of the hashing algorithms.
For testing you can download the test data ("test vectors") from the Cryptographic Algorithm Validation Program (CAVP) (ca. 2.7 MB and 21 MB):
Alternatively, you can also download my local copies:
(But take into account that you can't rule out that I might have fiddled with the original NIST files (or even the links above) in order to trick you into using my SHA implementation – you hardly can be too paranoid when security is involved (and mentioning this may just be my way into luring you to believe that I'm a good guy;-)
A lot of ideas came from the example implementation from RFC 3174 by D. Eastlake, 3rd (Motorola) and P. Jones (Cisco Systems).
The part for dealing with 64-bit numbers on systems that lack such a type has directly been taken from code written by Paul Eggert, which is part of the GNU Coreutils in the file 'lib/u64.h'.
If you need one or more SHA implementations in your own code you can simply link against the library. From within your code you then only have to '#include' the file 'sha_digest.h'.
But you could as well just re-use the code for one (or more) of the SHA algorithms directly within your code. If you e.g. just need SHA-1 you can copy the files 'sha1.c', 'sha1.h' and (not to be forgotten!) 'sha_types.h' to your project directory and compile it with your code. From within your code you then only need to '#include' the file 'sha1.h' and afterwards link with 'sha1.o'.
There are also two programs that you can use to calculate the SHA digests of files (or data redirected to the programs), sha_digest and sha_bdigest. The first one allows to calculate the hash digest for a message that consists of bytes (i.e. a number of bits that is a multiple of 8) and the second one is for hashing of arbitrary numbers of bits.
The program is released under the GNU General Public License (GPL), version 2.
While I don't want to repeat myself and bore you to death this is IMPORTANT: if you intend to use this code in a security critical application review and test the code with utmost care before using it – I can't guarantee its correctness. I have tested it using the test vectors supplied by the NIST Cryptographic Algorithm Validation Program (CAVP) and – for byte-oriented messages – also compared results with those from other implementations (like the ones from the GNU coreutils) for several thousands of files on two machines, with a 64- and and a 32-bit version of Linux. While these tests didn't show any problems you should, of course, not consider this as proof that the implementation is doing the "Right Thing" in all possible cases! And, of course (again), a successful test with the test vectors from NIST does NOT constitute a validation as it can only be obtained through the Cryptographic Algorithm Validation Program (CAVP).
If you find bugs or implement improvements please don't hesitate to contact me.
Back to homepage
|Last modified: October 29, 2011|