1. Introduction
2. Hash algorithms
3. MAC algorithms
4. Block cipher algorithms
5. Block cipher encryption modes
6. Stream cipher algorithms
7. Key derivation functions
8. AEAD
9. Streaming AEAD
10. Digest utility
11. Cryptor utility
12. Portability notes
13. Download link
cppcrypto is a small cross-platform BSD-licensed C++ library providing some cryptographic primitives. It has no external dependencies.
The library thrives to be as fast as possible. CPU type is detected at runtime and the fastest implementation is selected dynamically.
Supported compilers: Visual C++ 2017 or later on Windows; gcc 12 or later, clang 13 or later on Linux, OS X, FreeBSD.
Supported architectures: x86_64 and x86.
Download cppcrypto from sourceforge
Full list of supported cryptographic primitives is described below.
All hash algorithms derive from crypto_hash
class and implement its interface.
class crypto_hash { public: virtual void init() = 0; virtual void update(const unsigned char* data, size_t len) = 0; virtual void final(unsigned char* hash) = 0; virtual size_t hashsize() const = 0; virtual size_t blocksize() const = 0; // Convenience functions void hash_string(const unsigned char* data, size_t len, unsigned char* hash); void hash_string(const char* data, size_t len, unsigned char* hash); void hash_string(const std::string& data, unsigned char* hash); };
If you have a short message, you can calculate the hash using a single hash_string()
call.
Otherwise, call init()
to start hashing,
then call update()
any number of times to add the next chunk of data, and finally call final()
to get the hash.
The hash
parameter should point to a buffer large enough to accept the hash of correspondent size (length in bytes is hashsize()/8
).
Classes derived from crypto_hash
:
Class Name | Description | Supported output sizes |
---|---|---|
blake |
BLAKE hash function (one of SHA-3 finalists). This is one of the fastest hash functions and we recommend it you are free to choose. | 224 / 256 / 384 / 512 |
blake2b |
BLAKE2b hash function with variable output size up to 512 bits. This is a version of BLAKE-512 with reduced number of rounds and other simplifications. | 8 - 512 |
blake2s |
BLAKE2s hash function with variable output size up to 256 bits. This is a version of BLAKE-256 with reduced number of rounds and other simplifications. | 8 - 256 |
echo |
ECHO hash function (one of SHA-3 Round 2 candidates). | 8 - 512 |
esch |
Esch hash function (one of NIST Lightweight Crypto Competition finalists). | 256 / 384 |
groestl |
Grøstl hash function (one of SHA-3 finalists). | 8 - 512 |
jh |
JH hash function (one of SHA-3 finalists). | 224 / 256 / 384 / 512 |
kupyna |
Kupyna hash function (Ukrainian national standard DSTU 7564:2014) with output sizes 256/512 bits. 224/384-bit functions are not provided because their output is identical to the truncated 256/512-bit output. | 256 / 512 |
md5 |
MD5 hash function. Not secure and therefore not recommended; use only if you need it for compatibility. | 128 |
sha1 |
SHA-1 hash function. Not secure and therefore not recommended; use only if you need it for compatibility. | 160 |
sha224 sha256 sha384 sha512 |
SHA-2 hash function (NIST standard FIPS 180-4).
Individual functions are known as SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256. SHA-512 supports variable output size up to 512 bits (SHA-512/t). sha512(224) and sha512(256) are faster than sha224 and sha256 on 64-bit platforms.
| 224 / 256 / 384 / 512, 8 - 512 (SHA-512/t) |
sha3 shake128 shake256 |
SHA-3 hash function (NIST standard FIPS 202) based on Keccak algorithm.
SHAKE-128 and SHAKE-256 support variable output size. cSHAKE-128 and cSHAKE-256 as defined by NIST SP 800-185 are also supported. | 224 / 256 / 384 / 512 (SHA-3) arbitrary (SHAKE) |
skein256 |
Skein hash function (one of SHA-3 finalists) with block size 256 bits and variable output size. This algorithm is slower than skein512 on modern PCs, so use it only if you need them for compatibility. | arbitrary |
skein512 |
Skein hash function (one of SHA-3 finalists) with block size 512 bits and variable output size. This is one of the fastest hash functions and we recommend it if you are free to choose. | arbitrary |
skein1024 |
Skein hash function (one of SHA-3 finalists) with block size 1024 bits and variable output size. | arbitrary |
sm3 |
SM3 hash function (Chinese national standard) | 256 |
streebog |
Streebog hash function (Russian standard GOST R 34.11-2012) | 256 / 512 |
whirlpool |
Whirlpool hash function (recommended by NESSIE) | 512 |
MD5 and SHA-1 algorithms are broken and should not be used for new applications. We do not recommend using Streebog because of possible back door in the algorithm. All other supported hash functions are unbroken and safe to use.
The following snippet calculates BLAKE-256 hash of a string using a single function call:
unsigned char hash[256/8]; blake(256).hash_string("The quick brown fox jumps over the lazy dog", hash); // Now hash contains the hash
The following snippet demonstrates how to calculate the hash of a very long message using the init/update/final interface:
blake(256) hasher; unsigned char hash[256/8]; hasher.init(); hasher.update(datachunk1, chunk1len); hasher.update(datachunk2, chunk2len); ... hasher.final(hash); // Now hash contains the hash
Class crypto_mac
is similar to crypto_hash
. The only difference is that you need to pass a key to the init
method.
All MAC algorithms derive from crypto_mac
class and implement its interface.
class crypto_mac { public: virtual void init(const unsigned char* key, size_t keylen) = 0; virtual void update(const unsigned char* data, size_t len) = 0; virtual void final(unsigned char* hash) = 0; virtual size_t keysize() const = 0; virtual size_t hashsize() const = 0; virtual size_t blocksize() const = 0; // Convenience functions void mac_string(const unsigned char* key, size_t key_len, const unsigned char* data, size_t len, unsigned char* hash); void mac_string(const char* key, size_t key_len, const unsigned char* data, size_t len, unsigned char* hash); void mac_string(const char* key, size_t key_len, const char* data, size_t len, unsigned char* hash); void mac_string(const std::string& key, const std::string& data, unsigned char* hash); };
If you have a short message, you can calculate the MAC using a single mac_string()
call.
Otherwise, call init()
to start hashing,
then call update()
any number of times to add the next chunk of data, and finally call final()
to get the MAC.
The hash
parameter should point to a buffer large enough to accept the MAC of correspondent size (length in bytes is hashsize()/8
).
Class hmac
is derived from crypto_mac
. To specify the underlying hash function, you need to pass a reference to the hash algorithm in the constructor.
hmac(const crypto_hash& hash);
The key can be of any length and you can use any of the supported hash algorithms to calculate HMAC. The following sample calculates HMAC-SHA-256 of a string "The quick brown fox jumps over the lazy dog" with key "key":
unsigned char hmackey[3]; hmackey[0] = 'k'; hmackey[1] = 'e'; hmackey[2] = 'y'; hmac mac(sha256()); unsigned char result[32]; mac.hash_string(hmackey, sizeof(hmackey), "The quick brown fox jumps over the lazy dog", result);
Class poly1305
is also derived from crypto_mac
and implements its interface.
The key must have length 32 bytes (256 bits). The following sample calculates Poly1305 of a string "The quick brown fox jumps over the lazy dog" with key "\x00\x01\x02...\x31":
unsigned char key[32]; std::iota(key, key + 32, 0); unsigned char result[16]; poly.hash_string(key, sizeof(key), "The quick brown fox jumps over the lazy dog", result);
All block cipher algorithms derive from block_cipher
class and implement its interface.
class block_cipher { public: enum direction { encryption, decryption }; virtual size_t blocksize() const = 0; virtual size_t keysize() const = 0; virtual bool init(const unsigned char* key, block_cipher::direction direction) = 0; virtual void encrypt_block(const unsigned char* in, unsigned char* out) = 0; virtual void decrypt_block(const unsigned char* in, unsigned char* out) = 0; };
A low-level interface to the block cipher. To start encryption or decryption, call init()
(key
should point to a key of keysize()/8
bytes), then call encrypt_block()
or decrypt_block()
to encrypt or decrypt a single block of blocksize()/8
bytes.
In practice in most cases you probably want to use these block ciphers in an AEAD mode described in a separate section (using aead_etm
class).