#ifndef KEY_GENERATOR_CLASS
#define KEY_GENERATOR_CLASS

/*****************************************************************************\
*                                                                             *
*  Name   : key_generator                                                     *
*  Author : Chris Koeritz                                                     *
*                                                                             *
*******************************************************************************
* Copyright (c) 2002-$now By Author.  This program is free software; you can  *
* redistribute it and/or modify it under the terms of the GNU General Public  *
* License as published by the Free Software Foundation; either version 2 of   *
* the License or (at your option) any later version.  This is online at:      *
*     http://www.fsf.org/copyleft/gpl.html                                    *
* Please send any updates to: fred@gruntose.com                               *
\*****************************************************************************/

//! Generates a rotating ice_key for changing keys during communication.
/*!
  Implements a key generation process that occurs at different stages,
  each creating a new key.  While based on a single private key initially,
  the key_generator allows a new key to be created identically on each side
  of a communication that can be used for somewhat secure encoding.
*/

#include "crypto_dll.h"

#include <basis/object_base.h>

class CRYPTO_CLASS_STYLE key_generator
{
public:
  key_generator(int key_size);
    //!< creates a new key generator with the "key_size".
    /*!< the "key_size" here must be a multiple of 8.  it is the size in bytes
    of the keys that we will deal with. */

  virtual ~key_generator();

  IMPLEMENT_CLASS_NAME("key_generator");

  int key_size() const { return _key_size; }

  bool twist_key(int stage, const byte_array &previous_key,
          const byte_array &fodder, byte_array &new_key);
    //!< switches keys in the middle of an encrypted chat.
    /*!< given a "previous_key" that was negotiated during a phase
    ("stage" - 1), a "new_key" is created given the "fodder" for mingling
    with the key data.  the "fodder" is decrypted using the "previous_key"
    before it is used in creating a new key.  in "stage" 0, the "previous_key"
    will be empty and our internal key will be used.  it is important that the
    "stage" start at zero and increase by one, since it is mixed with
    the decrypted "fodder".  note that the "fodder" size can vary, but the
    "previous_key" must always be the size specified in the constructor.
    however, the "fodder" should be approximately the same length as the
    key size (or greater) in order to best scramble the new key. */

private:
  int _key_size;  //!< the size of the keys we'll generate.

  void fill_default_key(byte_array &to_fill);
    //!< provides the key for stage zero in "to_fill".
};

#endif

