Since there are only three valid key sizes for AES, it makes sense to not even let the AES class be instantiated with any uint16 value. I would introduce an enum similar to this:
enum class AesKeyLen
{
Aes128,
Aes192,
Aes256
};
And then change the uint16 constructor to this:
explicit AES (AesKeyLen keyLen);
Sure, they could still pass bad values, but they have to try harder by explicitly creating an invalid enum value. Also, and because it'smaking it a scoped enum, integers aren't implicitly cast to the AesKeyLen provides extra type-safety and prevents naming clashes.
Either way, I think it makes sense to throw out of the constructor immediately if the key length is wrong instead of waiting until the encrypt function.
If you want to enforce a valid value at compile-time, you can use a static_assert, or you can use a smart-enum pattern. This is an example hacked together real quick:
class AesKeyLen
{
private:
uint16 _length;
AesKeyLen(uint16 len)
{
_length = len;
}
public:
uint16 length()
{
return _length;
}
static AesKeyLen Aes128()
{
return AesKeyLen(128);
}
static AesKeyLen Aes192()
{
return AesKeyLen(192);
}
static AesKeyLen Aes256()
{
return AesKeyLen(256);
}
};
And then replace the uint16 constructor again:
explicit AES (AesKeyLen keyLen);