Hash Functions

All TaoCrypt Hash functions are derived from the HASH Class which provides two very useful virtual functions:

     virtual void Update(const byte*, word32) = 0;
     virtual void Final(byte*) = 0;

Most Hashing needs can be fulfilled using these two functions, e.g.,

     byte md5sum[MD5::DIGEST_SIZE];
     byte buffer[1024];
     // fill buffer

     MD5 hash;
     hash.Update(buffer, 1024);
     // continue updating if needed
     hash.Final(md5sum);

md5sum now contains the digest of the hashed data. The same code can be used for MD2, MD5, SHA-1, or RIPEMD. Using the base class can abstract away the differences:

     void GetDigest(byte* digest, HASH& hash, const byte* input, word32 sz) {
          hash.Update(input, sz);
          hash.Final(digest);
     }

Please see test.cpp for complete examples and test vectors.

Message Digests

TaoCrypt currently provides HMAC for message digest needs. Update() and Final() are provided, just like the hashing functions, but an additional function is needed for keying:

     void SetKey(const byte*, word32);

HMAC is as easy to use as the hashes, just provide a hashing function and a key:

     byte digest[SHA::DIGEST_SIZE];
     byte buffer[1024];
     byte key[16];
     // fill buffer and key

     HMAC<SHA> hmac;
     hmac.SetKey(key, 16);
     hmac.Update(buffer, 1024);
     hmac.Final(digest);

Block Ciphers

TaoCrypt provides DES, 3DES, and AES for block cipher needs. Currently, ECB and CBC modes are supported (only what SSL and TLS require). Some typedefs are provided in the headers for these ciphers:

     typedef BlockCipher<ENCRYPTION, DES, ECB> DES_ECB_Encryption;

The Block Ciphers rely on one function for encrypting and decrypting:

     void Process(byte*, const byte*, word32);

Keying is simple:

     void SetKey(const byte*, word32);
     void SetKey(const byte*, word32, const byte*);

The second version is used when an initialization vector is needed. Usage is trivial, to encrypt:

     byte key[8] = { // some key };
     byte buffer[24] = { // some plain text };
     byte cipherText[24];

     DES_ECB_Encryption enc;
     enc.SetKey(key, 8);
     enc.Process(cipherText, buffer, 24);

Decrypting is simple as well:

     byte plainText[24];

     DES_ECB_Decryption dec;
     dec.SetKey(key, 8);
     dec.Process(plainText, cipherText, 24);

3DES and AES are used the same way, please see test.cpp for complete examples.

Stream Ciphers

TaoCrypt provides ARC4 for stream cipher needs. Like BlockCipher, ARC4 can be used with just two functions:

     void SetKey(const byte*, word32);
     void Process(byte*, const byte*, word32);

Typdefs are also provided in the header for encryption and decryption needs. Here is a simple example that encrypts:

     byte key[16] = { // some key };
     byte buffer[100] = { // some plain text };
     byte cipherText[100];

     ARC4::Encryption enc;
     enc.SetKey(key, 16);
     enc.Process(cipherText, buffer, 100);

Decrypting is analogous:

     byte plainText[100];

     ARC4::Decryption dec;
     dec.SetKey(key, 16);
     dec.Process(plainText, cipherText, 100);

Please see test.cpp for a complete example and test vectors.

Public Key Cryptography

TaoCrypt provides RSA and DSA for Public Key Cryptography.

RSA

There are public and private RSA keys, RSA_PublicKey and RSA_PrivateKey. Typically, they are initialized with a Source object, which is usually constructed with a byte array or a file:

     byte privKey[64] = { // some key };
     Source privSrc(privKey, 64);
     RSA_PrivateKey rsaPriv(privSrc);

A public key can also be constructed from a private key:

     RSA_PublicKey rsaPub(rsaPriv);
     // or a file source example

     Source fSrc;
     FileSource("./rsaPublic.dat", fSrc);

     RSA_PublicKey rsaPub(fSrc);

Once you have a public key, you can perform public encryption:

     byte buffer[64] = { // plain Text };
     byte cipher[64];
     RandomNumberGenerator rng;

     RSAES_Encryptor enc(rsaPub);
     enc.Encrypt(buffer, 64, cipher, rng);

RSAES_Encryptor is a typedef for:

     typedef RSA_Encryptor<> RSAES_Encryptor;

Where the default template argument is RSA_BlockType2, a padding scheme. Decrypting requires a private key:

     byte plain[64];
     RSAES_Decryptor dec(rsaPriv);
     dec.Decrypt(cipher, 64, plain, rng);

TaoCrypt can also do RSA sign and verify operations, including the SSL type which require RSA_BlockType1 padding. The member functions SSL_Sign() and SSL_Verify() handle these and are used with the same arguments as encryption and decryption. TaoCrypt handles inversing the keys transparently. Please see test.cpp for a complete example.

DSA

There are public and private DSA keys, DSA_PublicKey and DSA_PrivateKey. Typically, they are initialized with a Source object, which is usually constructed with a byte array or a file:

     byte privKey[128] = { // some key };
     Source privSrc(privKey, 128);
     DSA_PrivateKey dsaPriv(privSrc);

Once you have a private DSA key, you can sign a message, usually an SHA digest:

     RandomNumberGenerator rng;
     byte message[SHA::DIGEST_SIZE] = { // a hash };
     byte signature[40];

     DSA_Signer signer(dsaPriv);
     signer.Sign(message, signature, rng);

Verifying is a simple operation as well:

     DSA_Verifier verifier(dsaPriv); // or Public Key
     bool result = verifier.Verify(message, signautre);

Please see test.cpp for a complete example.

Key Agreement

TaoCrypt provides Diffie-Hellman (DH) for key agreement arrangements. The DH class is generally constructed from a Source object to initialize p and g.

     byte key[80] = { // contains p and g };
     Source keySrc(key, 80);
     DH self(keySrc);

Once you have a DH object, you generate a key pair:

     byte pub[128];
     byte priv[128];
     RandomNumberGenerator rng;
     self.GenerateKeyPair(rng, priv, pub);

Then you can send someone your public key and obtain their public one. Using your private key and their public key you can generate an agreement:

     byte agree[128];
     self.Agree(agree, priv, otherPublicKey);

The other person will get the same agreement. Please see test.cpp for a complete example.

Home