#include "Bunny.h"

//!BunnyAES CLASS
/*!
This class inherits the methods from Bunny class, and specifies the virtual methods which are different from Bunny's.

BunnyAES allows to instantiate a block cipher as AES working on 128 bits, with a master key of nb_key bits, whose s-box take input of 8 bits, and with nround rounds.
*/
template <unsigned nb_key, unsigned nround>
class BunnyAES : public Bunny<128,nb_key,8,nround> {
public:

  typedef Bunny<128,nb_key,8,nround> BUNNY ;

  typedef typename BUNNY::msgType      msgType ;
  typedef typename BUNNY::keyType      keyType ;
  typedef typename BUNNY::sboxType     sboxType ;
  typedef typename BUNNY::wordType     wordType ;
  typedef typename BUNNY::roundkeyType roundkeyType ;

private:
  //! Contains the round keys
  roundkeyType rk;
  bitset<32> rcon[16] ; // Constant assigned to each keyschedule round

public:
  // CONSTRUCTORS
  BunnyAES() ;

  // CODING FUNCTIONS
  virtual msgType encode(msgType m, keyType k) ;
  virtual msgType decode(msgType m, keyType k) ;

//private:
//se le metto private non posso testarle!!

  // SBOX

  virtual msgType sBox        ( msgType m ) ; // sBox based on sbox
  virtual msgType sBoxInverse ( msgType m )  ; // sBox based on sbox

  virtual sboxType sbox       ( unsigned nbox, sboxType x ) ;
  virtual sboxType sboxInverse( unsigned nbox, sboxType x ) ;

  // MIXING LAYER
  virtual msgType mixingLayer        ( msgType m )  ;
  virtual msgType mixingLayerInverse ( msgType m )  ;

  msgType shiftRows     ( msgType m ) const ;
  msgType shiftRowsInv  ( msgType m ) const ;
  msgType mixColumns    ( msgType m ) const ;
  msgType mixColumnsInv ( msgType m ) const ;

  // ADD ROUND KEY
  //virtual msgType addRoundKey (msgType m, msgType k) ;

  // KEY SCHEDULE
  virtual void keySchedule(keyType k) ;

} ;

#include "BunnyAES.hxx"
