Re: Templates HowTo?
On 21 Feb, 15:25, ke...@bytebrothers.co.uk wrote:
Now you can probably see what I'm trying to do with this 'index' call;
it has to return the result of find_cipher("ciphername"). The problem
is that at compile time, I get the following error:
S'ok - I cracked it!
Here's the final, working wrapper (for now). All I had to do was put
an extra static member into each specialisation, containing the name
of the cipher. Obvious after a good night's sleep! Now somebody will
tell me at least one very good reason why I shouldn't do that :)
//=---------------------BEGIN--------------------
#include "tomcrypt.h"
/* Our abstract base class */
class AbstractCipher
{
public:
virtual ~AbstractCipher() {}
virtual int setup (const uint8_t* key, int keylen) = 0;
virtual int ecb_encrypt (const uint8_t *ptext, uint8_t* ctext) = 0;
virtual int ecb_decrypt (const uint8_t *ctext, uint8_t* ptext) = 0;
virtual int test () = 0;
virtual int keysize (int* keysize) = 0;
virtual int index () = 0;
};
/* Our functors */
struct CFunctionTypes
{
typedef int (*Setup)
(const uint8_t* key, int keylen, int rounds, symmetric_key* skey);
typedef int (*ECBencrypt)
(const uint8_t *ptext, uint8_t* ctext, symmetric_key* skey);
typedef int (*ECBdecrypt)
(const uint8_t *ctext, uint8_t* ptext, symmetric_key* skey);
typedef int (*Test)
();
typedef int (*Keysize)
(int* keysize);
typedef void (*Done)
(symmetric_key* skey);
typedef const struct ltc_cipher_descriptor* Desc;
typedef const char* Name;
};
/* Now specialise the functors for each cipher */
struct AESCipher:CFunctionTypes
{
static Setup const setup;
static ECBencrypt const ecb_encrypt;
static ECBdecrypt const ecb_decrypt;
static Test const test;
static Keysize const keysize;
static Done const done;
static Desc const descriptor;
static Name const name;
};
CFunctionTypes::Setup const AESCipher::setup = &aes_setup;
CFunctionTypes::ECBencrypt const AESCipher::ecb_encrypt =
&aes_ecb_encrypt;
CFunctionTypes::ECBdecrypt const AESCipher::ecb_decrypt =
&aes_ecb_decrypt;
CFunctionTypes::Test const AESCipher::test = &aes_test;
CFunctionTypes::Keysize const AESCipher::keysize =
&aes_keysize;
CFunctionTypes::Done const AESCipher::done = &aes_done;
CFunctionTypes::Desc const AESCipher::descriptor = &aes_desc;
CFunctionTypes::Name const AESCipher::name = "aes";
struct TwofishCipher:CFunctionTypes
{
static Setup const setup;
static ECBencrypt const ecb_encrypt;
static ECBdecrypt const ecb_decrypt;
static Test const test;
static Keysize const keysize;
static Done const done;
static Desc const descriptor;
static Name const name;
};
CFunctionTypes::Setup const TwofishCipher::setup =
&twofish_setup;
CFunctionTypes::ECBencrypt const TwofishCipher::ecb_encrypt =
&twofish_ecb_encrypt;
CFunctionTypes::ECBdecrypt const TwofishCipher::ecb_decrypt =
&twofish_ecb_decrypt;
CFunctionTypes::Test const TwofishCipher::test =
&twofish_test;
CFunctionTypes::Keysize const TwofishCipher::keysize =
&twofish_keysize;
CFunctionTypes::Done const TwofishCipher::done =
&twofish_done;
CFunctionTypes::Desc const TwofishCipher::descriptor =
&twofish_desc;
CFunctionTypes::Name const TwofishCipher::name =
"twofish";
template < class CFunctions > class Cipher : public AbstractCipher
{
public:
Cipher () : skey()
{ register_cipher (CFunctions::descriptor); }
Cipher (const uint8_t* key, int keylen) : skey()
{ register_cipher (CFunctions::descriptor);
CFunctions::setup (key, keylen, 0, &skey);
}
virtual int setup (const uint8_t* key, int keylen)
{ return CFunctions::setup (key, keylen, 0, &skey); }
virtual int ecb_encrypt (const uint8_t *ptext, uint8_t* ctext)
{ return CFunctions::ecb_encrypt (ptext, ctext, &skey); }
virtual int ecb_decrypt (const uint8_t *ctext, uint8_t* ptext)
{ return CFunctions::ecb_decrypt (ctext, ptext, &skey); }
virtual int test ()
{ return CFunctions::test(); }
virtual int keysize (int* keysize)
{ return CFunctions::keysize(keysize); }
virtual int index ()
{ return find_cipher(CFunctions::name); }
virtual ~Cipher ()
{ CFunctions::done (&skey);
unregister_cipher (CFunctions::descriptor);
}
protected:
symmetric_key skey;
};
typedef Cipher < AESCipher > AES;
typedef Cipher < TwofishCipher > Twofish;
//=---------------------END--------------------