#line 1 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
/* nettle.cmod -*- c -*- */
/* $Id: nettle.cmod,v 1.37 2005/12/11 18:01:46 nilsson Exp $ */

#include "global.h"
#include "interpret.h"
#include "svalue.h"
/* For this_object() */
#include "object.h"
#include "operators.h"
#include "module_support.h"
#include "threads.h"

#include "nettle_config.h"

#ifdef HAVE_LIBNETTLE

#include "nettle.h"

#include <nettle/yarrow.h>
#include <nettle/knuth-lfib.h>

#include <assert.h>
#include <stdio.h>
#include <stdarg.h>

/*! @module Nettle
 *! Low level crypto functions used by the @[Crypto] module. Unless
 *! you are doing something very special, you would want to use the
 *! Crypto module instead.
 */

/*! @class Yarrow
 *!
 *! Yarrow is a family of pseudo-randomness generators, designed for
 *! cryptographic use, by John Kelsey, Bruce Schneier and Niels Ferguson.
 *! Yarrow-160 is described in a paper at
 *! @url{http://www.counterpane.com/yarrow.html@}, and it uses SHA1 and
 *! triple-DES, and has a 160-bit internal state. Nettle implements
 *! Yarrow-256, which is similar, but uses SHA256 and AES to get an
 *! internal state of 256 bits.
 */

#undef class_Yarrow_defined
#define class_Yarrow_defined
struct program *Yarrow_program=NULL;
static int Yarrow_program_fun_num=-1;

#undef var_ctx_Yarrow_defined
#define var_ctx_Yarrow_defined

#undef var_sources_Yarrow_defined
#define var_sources_Yarrow_defined

#undef THIS
#define THIS ((struct Yarrow_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_YARROW
#define THIS_YARROW ((struct Yarrow_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_YARROW
#define OBJ2_YARROW(o) ((struct Yarrow_struct *)(o->storage+Yarrow_storage_offset))

#undef GET_YARROW_STORAGE
#define GET_YARROW_STORAGE ((struct Yarrow_struct *)(o->storage+Yarrow_storage_offset)
static ptrdiff_t Yarrow_storage_offset;
struct Yarrow_struct {

#ifdef var_ctx_Yarrow_defined
#line 46 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct yarrow256_ctx ctx;
#endif /* var_ctx_Yarrow_defined */

#ifdef var_sources_Yarrow_defined
#line 47 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct yarrow_source *sources;
#endif /* var_sources_Yarrow_defined */
};
/*! @decl void create(void|int sources)
   *! The number of entropy sources that will feed entropy to the
   *! random number generator is given as an argument to Yarrow
   *! during instantiation.
   *! @seealso
   *!   @[update]
   */
  #define f_Yarrow_create_defined
ptrdiff_t f_Yarrow_create_fun_num = 0;
void f_Yarrow_create(INT32 args) {
#line 56 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct svalue * arg;
#line 56 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args > 1) wrong_number_of_args_error("create",args,1);
if (args > 0) {
#line 56 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-args].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("create",1,"void|int");
#line 56 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
arg=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
} else arg=0;
#line 57 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    INT32 num = 0;

    if(arg) {
      if (arg->type != PIKE_T_INT)
	Pike_error("Bad argument type.\n");
      num = arg->u.integer;
      if(num < 0)
	Pike_error("Invalid number of sources.\n");
      free (THIS->sources);
      THIS->sources = xalloc(sizeof(struct yarrow_source)*num);
    }
    else
    {
      free (THIS->sources);
      THIS->sources = NULL;
    }
    yarrow256_init(&THIS->ctx, num, THIS->sources);
  }

  }
/*! @decl Yarrow seed(string data)
   *! The random generator needs to be seeded before
   *! it can be used. The seed must be at least 32
   *! characters long. The seed could be stored from
   *! a previous run by inserting the value returned
   *! from @[get_seed].
   *! @returns
   *!   Returns the called object.
   *! @seealso
   *!   @[min_seed_size], @[get_seed], @[is_seeded]
   */
  #define f_Yarrow_seed_defined
ptrdiff_t f_Yarrow_seed_fun_num = 0;
void f_Yarrow_seed(INT32 args) {
#line 88 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * data;
#line 88 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("seed",args,1);
#line 88 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("seed",1,"string");
#line 88 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(data=Pike_sp[0-1].u.string);
#line 90 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    if(data->len < YARROW256_SEED_FILE_SIZE)
      Pike_error( "Seed must be at least 32 characters.\n" );

    NO_WIDE_STRING(data);
    yarrow256_seed(&THIS->ctx, data->len, data->str);
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 97 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl int(0..) min_seed_size()
   *! Returns the minimal number of characters that the @[seed]
   *! needs to properly seed the random number generator.
   *! @seealso
   *!   @[seed]
   */
  #define f_Yarrow_min_seed_size_defined
ptrdiff_t f_Yarrow_min_seed_size_fun_num = 0;
void f_Yarrow_min_seed_size(INT32 args) {
#line 105 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("min_seed_size",args,0);
#line 107 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(YARROW256_SEED_FILE_SIZE);  push_int(ret_); return; }while(0);
#line 109 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl string get_seed()
   *! Returns part of the internal state so that it can
   *! be saved for later seeding.
   *! @seealso
   *!   @[seed]
   */
  #define f_Yarrow_get_seed_defined
ptrdiff_t f_Yarrow_get_seed_fun_num = 0;
void f_Yarrow_get_seed(INT32 args) {
#line 117 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("get_seed",args,0);
#line 119 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    if( !yarrow256_is_seeded(&THIS->ctx) )
      Pike_error("Random generator not seeded.\n");
    do { struct pike_string * ret_=(make_shared_binary_string(THIS->ctx.seed_file,
				     YARROW256_SEED_FILE_SIZE));  push_string(ret_); return; }while(0);
#line 124 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl int(0..1) is_seeded()
   *! Returns 1 if the random generator is seeded and ready
   *! to generator output. 0 otherwise.
   *! @seealso
   *!   @[seed]
   */
  #define f_Yarrow_is_seeded_defined
ptrdiff_t f_Yarrow_is_seeded_fun_num = 0;
void f_Yarrow_is_seeded(INT32 args) {
#line 132 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("is_seeded",args,0);
#line 134 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(yarrow256_is_seeded(&THIS->ctx));  push_int(ret_); return; }while(0);
#line 136 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl void force_reseed()
   *! By calling this function entropy is moved from the slow
   *! pool to the fast pool. Read more about Yarrow before using
   *! this.
   */
  #define f_Yarrow_force_reseed_defined
ptrdiff_t f_Yarrow_force_reseed_fun_num = 0;
void f_Yarrow_force_reseed(INT32 args) {
#line 143 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("force_reseed",args,0);
#line 145 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    yarrow256_force_reseed(&THIS->ctx);
  }

  }
/*! @decl int(0..1) update(string data, int source, int entropy)
   *! Inject additional entropy into the random number generator.
   *!
   *! @seealso
   *!   @[create]
   */
  #define f_Yarrow_update_defined
ptrdiff_t f_Yarrow_update_fun_num = 0;
void f_Yarrow_update(INT32 args) {
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * data;
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE source;
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE entropy;
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 3) wrong_number_of_args_error("update",args,3);
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-3].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("update",1,"string");
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(data=Pike_sp[0-3].u.string);
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[1-3].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("update",2,"int");
source=Pike_sp[1-3].u.integer;
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[2-3].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("update",3,"int");
entropy=Pike_sp[2-3].u.integer;
{
    /* FIXME: Wide strings could actually be supported here */
    NO_WIDE_STRING(data);
    if( !THIS->sources )
      Pike_error("This random generator has no sources.\n");
    if( source<0 || (unsigned)source>=THIS->ctx.nsources )
      Pike_error("Invalid random source.\n");
    if( entropy<0 )
      Pike_error("Entropy must be positive.\n");
    if( entropy>(data->len*8) )
      Pike_error("Impossibly large entropy value.\n");
    do { INT_TYPE ret_=(yarrow256_update(&THIS->ctx, source, entropy, data->len, data->str)); pop_n_elems(3); push_int(ret_); return; }while(0);
#line 169 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl int(0..) needed_sources()
   *! The number of sources that must reach the threshold before a
   *! slow reseed will happen.
   */
  #define f_Yarrow_needed_sources_defined
ptrdiff_t f_Yarrow_needed_sources_fun_num = 0;
void f_Yarrow_needed_sources(INT32 args) {
#line 175 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("needed_sources",args,0);
#line 177 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(yarrow256_needed_sources(&THIS->ctx));  push_int(ret_); return; }while(0);
#line 179 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl string random_string(int length)
   *! Returns a pseudo-random string of the requested @[length].
   */
  #define f_Yarrow_random_string_defined
ptrdiff_t f_Yarrow_random_string_fun_num = 0;
void f_Yarrow_random_string(INT32 args) {
#line 184 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE length;
#line 184 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("random_string",args,1);
#line 184 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("random_string",1,"int");
length=Pike_sp[0-1].u.integer;
{
    struct pike_string *rnd;
    if(length < 0)
      Pike_error("Invalid length, must be positive.\n");
    if( !yarrow256_is_seeded(&THIS->ctx) )
      Pike_error("Random generator not seeded.\n");
    rnd = begin_shared_string(length);
    yarrow256_random(&THIS->ctx, length, rnd->str);
    do { struct pike_string * ret_=(end_shared_string(rnd)); pop_stack(); push_string(ret_); return; }while(0);
#line 195 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }

#undef internal_init_Yarrow_defined
#define internal_init_Yarrow_defined

#undef Yarrow_event_handler_defined
#define Yarrow_event_handler_defined
static void init_Yarrow_struct(void)
#line 198 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    THIS->sources = NULL;
    yarrow256_init(&THIS->ctx, 0, NULL);
  }
  
#undef internal_exit_Yarrow_defined
#define internal_exit_Yarrow_defined

#undef Yarrow_event_handler_defined
#define Yarrow_event_handler_defined
static void exit_Yarrow_struct(void)
#line 203 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    /* It's ok to call free(NULL); */
    free(THIS->sources);
  }

#ifdef Yarrow_event_handler_defined
static void Yarrow_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_Yarrow_defined
  case PROG_EVENT_INIT: init_Yarrow_struct(); break;

#endif /* internal_init_Yarrow_defined */

#ifdef internal_exit_Yarrow_defined
  case PROG_EVENT_EXIT: exit_Yarrow_struct(); break;

#endif /* internal_exit_Yarrow_defined */
  default: break; 
  }
}

#endif /* Yarrow_event_handler_defined */
/*! @endclass
 */

/*! @decl string crypt_md5(string password, string salt)
 *! Does the crypt_md5 abrakadabra (MD5 + snakeoil).
 *! It is assumed that @[salt] does not contain "$".
 */
#define f_crypt_md5_defined
ptrdiff_t f_crypt_md5_fun_num = 0;
void f_crypt_md5(INT32 args) {
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * pw;
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * salt;
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 2) wrong_number_of_args_error("crypt_md5",args,2);
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("crypt_md5",1,"string");
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(pw=Pike_sp[0-2].u.string);
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[1-2].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("crypt_md5",2,"string");
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(salt=Pike_sp[1-2].u.string);
#line 218 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
  char *hash;
  NO_WIDE_STRING(pw);
  NO_WIDE_STRING(salt);
  THREADS_ALLOW();
  hash = pike_crypt_md5(pw->len, pw->str,salt->len, salt->str);
  THREADS_DISALLOW();
  push_text(hash);
}


}
#line 229 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
static const char *crypto_functions[] = {
  "block_size",
  "key_size",
  "set_encrypt_key",
  "set_decrypt_key",
  "crypt",
  0
};

static const char *assert_is_crypto_object(struct program *p,
				    const char *const *required) {
  while (*required) {
    if (find_identifier( (char *) *required, p) < 0)
      return *required;
    required++;
  }
  return 0;
}

static struct object *make_cipher_object(INT32 args) {
  ptrdiff_t fun;
  const char *missing;
  struct svalue *top = Pike_sp-args;
  struct object *obj;

  switch(top->type)
  {
    case T_PROGRAM:
      obj = clone_object(top->u.program, args-1);
      break;

    case T_FUNCTION:
      apply_svalue(Pike_sp - args, args-1);

      /* Check return value */
      if(Pike_sp[-1].type != T_OBJECT)
	Pike_error("Returned value is not an object.\n");

      add_ref(obj = Pike_sp[-1].u.object);
      break;

    case T_OBJECT:
      fun = -1;
      missing = assert_is_crypto_object(top->u.object->prog,
					crypto_functions);
      if(missing)
	fun = FIND_LFUN(top->u.object->prog, LFUN_CALL);
      if(fun!=-1) {
	apply_low(top->u.object, fun, args-1);
	stack_swap();
	pop_stack();
      }
      else
	if(args!=1) Pike_error("Too many arguments.\n");

      add_ref(obj = top->u.object);
      break;
    default:
      SIMPLE_BAD_ARG_ERROR("create", 1, "program|object|function");
    }

  pop_stack();

  missing = assert_is_crypto_object(obj->prog, crypto_functions);
  if(missing) {
    free_object(obj);
    Pike_error("Object is missing identifier \"%s\"\n", missing);
  }

  return obj;
}


/*! @class CBC
 *! @belongs Crypto
 *! Implementation of the cipher block chaining mode (CBC). Works as
 *! a wrapper for the cipher algorithm put in create.
 */

#undef class_CBC_defined
#define class_CBC_defined
struct program *CBC_program=NULL;
static int CBC_program_fun_num=-1;

#undef var_object_CBC_defined
#define var_object_CBC_defined

#undef var_iv_CBC_defined
#define var_iv_CBC_defined

#undef var_block_size_CBC_defined
#define var_block_size_CBC_defined

#undef var_mode_CBC_defined
#define var_mode_CBC_defined

#undef THIS
#define THIS ((struct CBC_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_CBC
#define THIS_CBC ((struct CBC_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_CBC
#define OBJ2_CBC(o) ((struct CBC_struct *)(o->storage+CBC_storage_offset))

#undef GET_CBC_STORAGE
#define GET_CBC_STORAGE ((struct CBC_struct *)(o->storage+CBC_storage_offset)
static ptrdiff_t CBC_storage_offset;
struct CBC_struct {

#ifdef var_object_CBC_defined
#line 309 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct object *object;
#endif /* var_object_CBC_defined */

#ifdef var_iv_CBC_defined
#line 310 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
unsigned INT8 *iv;
#endif /* var_iv_CBC_defined */

#ifdef var_block_size_CBC_defined
#line 311 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT32 block_size;
#endif /* var_block_size_CBC_defined */

#ifdef var_mode_CBC_defined
#line 312 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT32 mode;
#endif /* var_mode_CBC_defined */
};

#undef internal_init_CBC_defined
#define internal_init_CBC_defined

#undef CBC_event_handler_defined
#define CBC_event_handler_defined
static void init_CBC_struct(void)
#line 315 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    THIS->object = 0;
    THIS->iv = 0;
    THIS->block_size = 0;
    THIS->mode = 0;
  }

  
#undef internal_exit_CBC_defined
#define internal_exit_CBC_defined

#undef CBC_event_handler_defined
#define CBC_event_handler_defined
static void exit_CBC_struct(void)
#line 323 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    if(THIS->object) free_object(THIS->object);
    if(THIS->iv) {
      MEMSET(THIS->iv, 0, THIS->block_size);
      free(THIS->iv);
    }
    THIS->iv = 0;
  }

  INLINE static void cbc_encrypt_step(const unsigned INT8 *const source,
				      unsigned INT8 *dest)
  {
    INT32 block_size = THIS->block_size;
    INT32 i;

    for(i=0; i < block_size; i++)
      THIS->iv[i] ^= source[i];

    push_string(make_shared_binary_string((INT8 *)THIS->iv, block_size));
    safe_apply(THIS->object, "crypt", 1);

    if(Pike_sp[-1].type != T_STRING)
      Pike_error("Expected string from crypt()\n");

    if(Pike_sp[-1].u.string->len != block_size) {
      Pike_error("Bad string length %ld returned from crypt()\n",
		 DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
    }
    MEMCPY(THIS->iv, Pike_sp[-1].u.string->str, block_size);
    MEMCPY(dest, Pike_sp[-1].u.string->str, block_size);
    pop_stack();
  }

  INLINE static void cbc_decrypt_step(const unsigned INT8 *const source,
				      unsigned INT8 *dest)
  {
    INT32 block_size = THIS->block_size;
    INT32 i;

    push_string(make_shared_binary_string((const INT8 *)source, block_size));
    safe_apply(THIS->object, "crypt", 1);

    if(Pike_sp[-1].type != T_STRING)
      Pike_error("Expected string from crypt()\n");

    if(Pike_sp[-1].u.string->len != block_size) {
      Pike_error("Bad string length %ld returned from crypt()\n",
		 DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
    }

    for(i=0; i < block_size; i++)
      dest[i] = THIS->iv[i] ^ Pike_sp[-1].u.string->str[i];

    pop_stack();
    MEMCPY(THIS->iv, source, block_size);
  }

  /*! @decl void create(program|object|function cipher, mixed ... args)
   *! Initialize the CBC wrapper with a cipher algorithm. If it is a
   *! program, an object will be instantiated with @[args] as arguments.
   *! If it is an object that doesn't conform to the cipher API, but has
   *! an @[LFUN::`()], that LFUN will be called. If it is a function,
   *! that function will be called with @[args] as arguments.
   */
  #define f_CBC_create_defined
ptrdiff_t f_CBC_create_fun_num = 0;
void f_CBC_create(INT32 args) {
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct svalue * cipher;
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct svalue * more;
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args < 1) wrong_number_of_args_error("create",args,1);
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
cipher=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if (args > 1) {
  INT32 argcnt = 0;
  do {
    dmalloc_touch_svalue(Pike_sp+1+argcnt-args);
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  } while (++argcnt < args-1);
  more=Pike_sp+1-args;
} else more=0;
#line 389 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    int old_block_size = THIS->block_size;
    THIS->object = make_cipher_object(args);

    safe_apply(THIS->object, "block_size", 0);

    if(Pike_sp[-1].type != T_INT)
      Pike_error("block_size() didn't return an int.\n");

    THIS->block_size = Pike_sp[-1].u.integer;

    pop_stack();

    if ((!THIS->block_size) ||
	(THIS->block_size > 4096))
      Pike_error("Bad block size %d.\n", THIS->block_size);

    if(THIS->iv) {
      MEMSET(THIS->iv, 0, old_block_size);
      free(THIS->iv);
    }
    THIS->iv = (unsigned INT8 *)xalloc(THIS->block_size);
    MEMSET(THIS->iv, 0, THIS->block_size);
  }

  }
/*! @decl string name()
   *! Returns the string @expr{"CBC(x)"@} where x is the
   *! encapsulated algorithm.
   */
  #define f_CBC_name_defined
ptrdiff_t f_CBC_name_fun_num = 0;
void f_CBC_name(INT32 args) {
#line 418 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("name",args,0);
#line 420 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    push_constant_text("CBC(");
    safe_apply(THIS->object, "name", 0);
    push_constant_text(")");
    f_add(3);
  }

  }
/*! @decl int block_size()
   *! Reurns the block size of the encapsulated cipher.
   */
  #define f_CBC_block_size_defined
ptrdiff_t f_CBC_block_size_fun_num = 0;
void f_CBC_block_size(INT32 args) {
#line 430 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("block_size",args,0);
#line 432 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(THIS->block_size);  push_int(ret_); return; }while(0);
#line 434 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl int key_size()
   *! Returns the key size of the encapsulated cipher.
   */
  #define f_CBC_key_size_defined
ptrdiff_t f_CBC_key_size_fun_num = 0;
void f_CBC_key_size(INT32 args) {
#line 439 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("key_size",args,0);
#line 441 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    safe_apply(THIS->object, "key_size", args);
  }

  }
/*! @decl this_program set_encrypt_key(string key)
   *! Prepare the cipher and the wrapper for encrypting
   *! with the given @[key].
   */
  #define f_CBC_set_encrypt_key_defined
ptrdiff_t f_CBC_set_encrypt_key_fun_num = 0;
void f_CBC_set_encrypt_key(INT32 args) {
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * key;
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("set_encrypt_key",args,1);
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("set_encrypt_key",1,"string");
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(key=Pike_sp[0-1].u.string);
#line 451 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    assert(THIS->block_size);
    THIS->mode = 0;
    safe_apply(THIS->object, "set_encrypt_key", args);
    pop_stack();
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 457 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl this_program set_decrypt_key(string key)
   *! Prepare the cipher and the wrapper for decrypting
   *! with the given @[key].
   */
  #define f_CBC_set_decrypt_key_defined
ptrdiff_t f_CBC_set_decrypt_key_fun_num = 0;
void f_CBC_set_decrypt_key(INT32 args) {
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * key;
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("set_decrypt_key",args,1);
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("set_decrypt_key",1,"string");
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(key=Pike_sp[0-1].u.string);
#line 465 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    assert(THIS->block_size);
    THIS->mode = 1;
    safe_apply(THIS->object, "set_decrypt_key", args);
    pop_stack();
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 471 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl this_program set_iv(string iv)
   *! Set the initialization vector to @[iv].
   */
  #define f_CBC_set_iv_defined
ptrdiff_t f_CBC_set_iv_fun_num = 0;
void f_CBC_set_iv(INT32 args) {
#line 476 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * iv;
#line 476 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("set_iv",args,1);
#line 476 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("set_iv",1,"string");
#line 476 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(iv=Pike_sp[0-1].u.string);
#line 478 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    assert(THIS->iv);
    NO_WIDE_STRING(iv);
    if(iv->len != THIS->block_size)
      Pike_error("Argument incompatible with cipher block size.\n");
    MEMCPY(THIS->iv, iv->str, THIS->block_size);
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 485 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl string crypt(string data)
   *! Encrypt/decrypt @[data] and return the result. @[data] must
   *! be an integral number of blocks.
   */
  #define f_CBC_crypt_defined
ptrdiff_t f_CBC_crypt_fun_num = 0;
void f_CBC_crypt(INT32 args) {
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * data;
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("crypt",args,1);
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("crypt",1,"string");
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(data=Pike_sp[0-1].u.string);
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    unsigned INT8 *result;
    INT32 offset = 0;

    NO_WIDE_STRING(data);

    if(data->len % THIS->block_size)
      Pike_error("Data length not multiple of block size.\n");
    if(!(result = alloca(data->len)))
      SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len);

    if(THIS->mode == 0) {
      while (offset < data->len) {
	cbc_encrypt_step((const unsigned INT8 *)data->str + offset,
			 result + offset);
	offset += THIS->block_size;
      }
    }
    else {
      while (offset < data->len) {
	cbc_decrypt_step((const unsigned INT8 *)data->str + offset,
			 result + offset);
	offset += THIS->block_size;
      }
    }

    pop_n_elems(args);
    push_string(make_shared_binary_string((INT8 *)result, offset));
    MEMSET(result, 0, offset);
  }
}

#ifdef CBC_event_handler_defined
static void CBC_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_CBC_defined
  case PROG_EVENT_INIT: init_CBC_struct(); break;

#endif /* internal_init_CBC_defined */

#ifdef internal_exit_CBC_defined
  case PROG_EVENT_EXIT: exit_CBC_struct(); break;

#endif /* internal_exit_CBC_defined */
  default: break; 
  }
}

#endif /* CBC_event_handler_defined */
/*! @endclass
 */

/*! @class Buffer
 *! @belongs Crypto
 *! Acts as a buffer so that data can be fed to a cipher in blocks
 *! that doesn't correspond to cipher block sizes.
 */

#undef class_Proxy_defined
#define class_Proxy_defined
struct program *Proxy_program=NULL;
static int Proxy_program_fun_num=-1;

#undef var_object_Proxy_defined
#define var_object_Proxy_defined

#undef var_block_size_Proxy_defined
#define var_block_size_Proxy_defined

#undef var_backlog_Proxy_defined
#define var_backlog_Proxy_defined

#undef var_backlog_len_Proxy_defined
#define var_backlog_len_Proxy_defined

#undef THIS
#define THIS ((struct Proxy_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_PROXY
#define THIS_PROXY ((struct Proxy_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_PROXY
#define OBJ2_PROXY(o) ((struct Proxy_struct *)(o->storage+Proxy_storage_offset))

#undef GET_PROXY_STORAGE
#define GET_PROXY_STORAGE ((struct Proxy_struct *)(o->storage+Proxy_storage_offset)
static ptrdiff_t Proxy_storage_offset;
struct Proxy_struct {

#ifdef var_object_Proxy_defined
#line 532 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct object *object;
#endif /* var_object_Proxy_defined */

#ifdef var_block_size_Proxy_defined
#line 533 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
int block_size;
#endif /* var_block_size_Proxy_defined */

#ifdef var_backlog_Proxy_defined
#line 534 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
unsigned char *backlog;
#endif /* var_backlog_Proxy_defined */

#ifdef var_backlog_len_Proxy_defined
#line 535 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
int backlog_len;
#endif /* var_backlog_len_Proxy_defined */
};

#undef internal_init_Proxy_defined
#define internal_init_Proxy_defined

#undef Proxy_event_handler_defined
#define Proxy_event_handler_defined
static void init_Proxy_struct(void)
#line 537 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    THIS->object = 0;
    THIS->block_size = 0;
    THIS->backlog = 0;
    THIS->backlog_len = 0;
  }

  
#undef internal_exit_Proxy_defined
#define internal_exit_Proxy_defined

#undef Proxy_event_handler_defined
#define Proxy_event_handler_defined
static void exit_Proxy_struct(void)
#line 544 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    if(THIS->backlog) {
      MEMSET(THIS->backlog, 0, THIS->block_size);
      free(THIS->backlog);
    }
    if(THIS->object)
      free_object(THIS->object);
  }

  /*! @decl void create(program|object|function cipher, mixed ... args)
   *! Initialize the Proxy wrapper with a cipher algorithm. If it is a
   *! program, an object will be instantiated with @[args] as arguments.
   *! If it is an object that doesn't conform to the cipher API, but has
   *! an @[LFUN::`()], that LFUN will be called. If it is a function,
   *! that function will be called with @[args] as arguments.
   */
  #define f_Proxy_create_defined
ptrdiff_t f_Proxy_create_fun_num = 0;
void f_Proxy_create(INT32 args) {
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct svalue * cipher;
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct svalue * more;
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args < 1) wrong_number_of_args_error("create",args,1);
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
cipher=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if (args > 1) {
  INT32 argcnt = 0;
  do {
    dmalloc_touch_svalue(Pike_sp+1+argcnt-args);
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  } while (++argcnt < args-1);
  more=Pike_sp+1-args;
} else more=0;
#line 562 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    THIS->object = make_cipher_object(args);

    safe_apply(THIS->object, "block_size", 0);
    if (Pike_sp[-1].type != T_INT)
      Pike_error("block_size() didn't return an int\n");
    THIS->block_size = Pike_sp[-1].u.integer;

    pop_stack();

    if ((!THIS->block_size) ||
	(THIS->block_size > 4096))
      Pike_error("Bad block size %ld\n", DO_NOT_WARN((long)THIS->block_size));

    THIS->backlog = (unsigned char *)xalloc(THIS->block_size);
    THIS->backlog_len = 0;
    MEMSET(THIS->backlog, 0, THIS->block_size);
  }

  }
/*! @decl string name()
   *! Returns the string @expr{"CBC(x)"@} where x is the
   *! encapsulated algorithm.
   */
  #define f_Proxy_name_defined
ptrdiff_t f_Proxy_name_fun_num = 0;
void f_Proxy_name(INT32 args) {
#line 585 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("name",args,0);
#line 587 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    push_constant_text("Proxy(");
    safe_apply(THIS->object, "name", 0);
    push_constant_text(")");
    f_add(3);
  }

  }
/*! @decl int block_size()
   *!
   *! Get the block size of the contained block crypto.
   */
  #define f_Proxy_block_size_defined
ptrdiff_t f_Proxy_block_size_fun_num = 0;
void f_Proxy_block_size(INT32 args) {
#line 598 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("block_size",args,0);
#line 600 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(THIS->block_size);  push_int(ret_); return; }while(0);
#line 602 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl int key_size()
   *!
   *! Get the key size of the contained block crypto.
   */
  #define f_Proxy_key_size_defined
ptrdiff_t f_Proxy_key_size_fun_num = 0;
void f_Proxy_key_size(INT32 args) {
#line 608 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("key_size",args,0);
#line 610 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    safe_apply(THIS->object, "key_size", args);
  }

  }
/*! @decl this_program set_encrypt_key(string key)
   *!
   *! Set the encryption key.
   *!
   *! @note
   *!   As a side-effect any buffered data will be cleared.
   */
  #define f_Proxy_set_encrypt_key_defined
ptrdiff_t f_Proxy_set_encrypt_key_fun_num = 0;
void f_Proxy_set_encrypt_key(INT32 args) {
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * key;
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("set_encrypt_key",args,1);
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("set_encrypt_key",1,"string");
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(key=Pike_sp[0-1].u.string);
#line 623 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    MEMSET(THIS->backlog, 0, THIS->block_size);
    THIS->backlog_len = 0;
    safe_apply(THIS->object, "set_encrypt_key", args);
    pop_stack();
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 629 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl this_program set_decrypt_key(string key)
   *!
   *! Set the decryption key.
   *!
   *! @note
   *!   As a side-effect any buffered data will be cleared.
   */
  #define f_Proxy_set_decrypt_key_defined
ptrdiff_t f_Proxy_set_decrypt_key_fun_num = 0;
void f_Proxy_set_decrypt_key(INT32 args) {
#line 638 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * key;
#line 638 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("set_decrypt_key",args,1);
#line 638 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("set_decrypt_key",1,"string");
#line 638 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(key=Pike_sp[0-1].u.string);
#line 640 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    MEMSET(THIS->backlog, 0, THIS->block_size);
    THIS->backlog_len = 0;
    safe_apply(THIS->object, "set_decrypt_key", args);
    pop_stack();
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 646 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
/*! @decl string crypt(string data)
   *!
   *! Encrypt some data.
   *!
   *! Adds data to be encrypted to the buffer. If there's enough
   *! data to en/decrypt a block, that will be done, and the result
   *! returned. Any uncrypted data will be left in the buffer.
   */
  #define f_Proxy_crypt_defined
ptrdiff_t f_Proxy_crypt_fun_num = 0;
void f_Proxy_crypt(INT32 args) {
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * data;
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("crypt",args,1);
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("crypt",1,"string");
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(data=Pike_sp[0-1].u.string);
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    unsigned char *result;
    ptrdiff_t roffset = 0;
    ptrdiff_t soffset = 0;
    ptrdiff_t len;

    if (!(result = alloca(data->len + THIS->block_size)))
      SIMPLE_OUT_OF_MEMORY_ERROR("crypt", data->len + THIS->block_size);

    if (THIS->backlog_len) {
      if (data->len >= (THIS->block_size - THIS->backlog_len)) {
	MEMCPY(THIS->backlog + THIS->backlog_len, data->str,
	       (THIS->block_size - THIS->backlog_len));
	soffset += (THIS->block_size - THIS->backlog_len);
	THIS->backlog_len = 0;
	push_string(make_shared_binary_string((char *)THIS->backlog,
					      THIS->block_size));
	safe_apply(THIS->object, "crypt", 1);
	if (Pike_sp[-1].type != T_STRING)
	  Pike_error("crypt() did not return string\n");
	if (Pike_sp[-1].u.string->len != THIS->block_size)
	  Pike_error("Unexpected string length %ld\n",
		     DO_NOT_WARN((long)Pike_sp[-1].u.string->len));

	MEMCPY(result, Pike_sp[-1].u.string->str, THIS->block_size);
	roffset = THIS->block_size;
	pop_stack();
	MEMSET(THIS->backlog, 0, THIS->block_size);
      } else {
	MEMCPY(THIS->backlog + THIS->backlog_len,
	       data->str, data->len);
	THIS->backlog_len += data->len;
	pop_n_elems(args);
	push_constant_text("");
	return;
      }
    }
  
    len = (Pike_sp[-1].u.string->len - soffset);
    len -= len % THIS->block_size;

    if (len) {
      push_string(make_shared_binary_string(Pike_sp[-1].u.string->str +
					    soffset, len));
      soffset += len;

      safe_apply(THIS->object, "crypt", 1);

      if (Pike_sp[-1].type != T_STRING)
	Pike_error("crypt() did not return string.\n");
      if (Pike_sp[-1].u.string->len != len)
	Pike_error("crypt() Unexpected string length %ld.\n",
		   DO_NOT_WARN((long)Pike_sp[-1].u.string->len));

      MEMCPY(result + roffset, Pike_sp[-1].u.string->str, len);

      pop_stack();
    }

    if (soffset < Pike_sp[-1].u.string->len) {
      MEMCPY(THIS->backlog, Pike_sp[-1].u.string->str + soffset,
	     Pike_sp[-1].u.string->len - soffset);
      THIS->backlog_len = Pike_sp[-1].u.string->len - soffset;
    }

    pop_n_elems(args);

    push_string(make_shared_binary_string((char *)result, roffset + len));
    MEMSET(result, 0, roffset + len);
  }

  }
/*! @decl string pad()
   *!
   *! Pad and de/encrypt any data left in the buffer.
   *!
   *! @seealso
   *!   @[unpad()]
   */
  #define f_Proxy_pad_defined
ptrdiff_t f_Proxy_pad_fun_num = 0;
void f_Proxy_pad(INT32 args) {
#line 734 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("pad",args,0);
#line 734 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    ptrdiff_t i;

    for (i = THIS->backlog_len; i < THIS->block_size - 1; i++)
      THIS->backlog[i] = DO_NOT_WARN((unsigned char)(my_rand() & 0xff));
  
    THIS->backlog[THIS->block_size - 1] =
      DO_NOT_WARN((unsigned char)(THIS->block_size - THIS->backlog_len - 1));

    push_string(make_shared_binary_string((const char *)THIS->backlog,
					  THIS->block_size));

    MEMSET(THIS->backlog, 0, THIS->block_size);
    THIS->backlog_len = 0;

    safe_apply(THIS->object, "crypt", 1);
  }

  }
/*! @decl string unpad(string data)
   *!
   *! De/encrypt and unpad a block of data.
   *!
   *! This performs the reverse operation of @[pad()].
   *!
   *! @seealso
   *!   @[pad()]
   */
  #define f_Proxy_unpad_defined
ptrdiff_t f_Proxy_unpad_fun_num = 0;
void f_Proxy_unpad(INT32 args) {
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct pike_string * str;
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("unpad",args,1);
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_STRING) SIMPLE_BAD_ARG_ERROR("unpad",1,"string");
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
debug_malloc_pass(str=Pike_sp[0-1].u.string);
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    ptrdiff_t len;

    len = str->len;

    if( len % THIS->block_size)
      Pike_error("String must be integral numbers of blocks.\n");
    safe_apply(THIS->object, "crypt", 1);
    if (Pike_sp[-1].type != T_STRING)
      Pike_error("crypt() did not return string.\n");
    if (Pike_sp[-1].u.string->len != len)
      Pike_error("crypt() Unexpected string length %ld.\n",
		 DO_NOT_WARN((long)Pike_sp[-1].u.string->len));
    str = Pike_sp[-1].u.string;

    if (str->str[len - 1] > (THIS->block_size - 1))
      Pike_error("Invalid padding (%d > %d)\n",
		 str->str[len-1], THIS->block_size-1);

    len -= (str->str[len - 1] + 1);

    if (len < 0)
      Pike_error("String to short to unpad\n");
  
    add_ref(str);
    pop_stack();
    push_string(make_shared_binary_string(str->str, len));
    free_string(str);
  }
}

#ifdef Proxy_event_handler_defined
static void Proxy_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_Proxy_defined
  case PROG_EVENT_INIT: init_Proxy_struct(); break;

#endif /* internal_init_Proxy_defined */

#ifdef internal_exit_Proxy_defined
  case PROG_EVENT_EXIT: exit_Proxy_struct(); break;

#endif /* internal_exit_Proxy_defined */
  default: break; 
  }
}

#endif /* Proxy_event_handler_defined */
/*! @endclass
 */

#line 795 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
#if 0

/* @class LFib
 * The Donald Knuth Lagged Fibonacci pseudo random number generator.
 * This is @b{not@} a source for cryptographic randomness. Use
 * @[Crypto.Yarrow] instead.
 */

#undef class_LFib_defined
#define class_LFib_defined
struct program *LFib_program=NULL;
static int LFib_program_fun_num=-1;

#undef var_ctx_LFib_defined
#define var_ctx_LFib_defined

#undef THIS
#define THIS ((struct LFib_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_LFIB
#define THIS_LFIB ((struct LFib_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_LFIB
#define OBJ2_LFIB(o) ((struct LFib_struct *)(o->storage+LFib_storage_offset))

#undef GET_LFIB_STORAGE
#define GET_LFIB_STORAGE ((struct LFib_struct *)(o->storage+LFib_storage_offset)
static ptrdiff_t LFib_storage_offset;
struct LFib_struct {

#ifdef var_ctx_LFib_defined
#line 804 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
struct knuth_lfib_ctx *ctx;
#endif /* var_ctx_LFib_defined */
};

#undef internal_init_LFib_defined
#define internal_init_LFib_defined

#undef LFib_event_handler_defined
#define LFib_event_handler_defined
static void init_LFib_struct(void)
#line 806 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    THIS->ctx = xalloc(sizeof(struct knuth_lfib_ctx));
  }

  
#undef internal_exit_LFib_defined
#define internal_exit_LFib_defined

#undef LFib_event_handler_defined
#define LFib_event_handler_defined
static void exit_LFib_struct(void)
#line 810 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    free(THIS->ctx);
  }

  /* @decl void create(int seed)
   * The Lfib generator must be seeded with a number.
   */
  #define f_LFib_create_defined
ptrdiff_t f_LFib_create_fun_num = 0;
void f_LFib_create(INT32 args) {
#line 817 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE seed;
#line 817 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("create",args,1);
#line 817 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("create",1,"int");
seed=Pike_sp[0-1].u.integer;
#line 817 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    knuth_lfib_init(THIS->ctx, seed);
  }

  }
#line 821 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
/* @decl this_program reseed(int s)
   * Reseed this object with seed @[s].
   * @return
   *   Returns the current object.
   */
  #define f_LFib_reseed_defined
ptrdiff_t f_LFib_reseed_fun_num = 0;
void f_LFib_reseed(INT32 args) {
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE s;
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("reseed",args,1);
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("reseed",1,"int");
s=Pike_sp[0-1].u.integer;
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    knuth_lfib_init(THIS->ctx, s);
    do { struct object * ret_=(this_object()); pop_stack(); push_object(ret_); return; }while(0);
#line 829 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
#line 831 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
/* Get one 32bit pseudorandom integer.
   */
  #define f_LFib_get_defined
ptrdiff_t f_LFib_get_fun_num = 0;
void f_LFib_get(INT32 args) {
#line 833 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 0) wrong_number_of_args_error("get",args,0);
#line 833 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    do { INT_TYPE ret_=(knuth_lfib_get(THIS->ctx));  push_int(ret_); return; }while(0);
#line 835 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
}

  }
#line 837 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
/* Get a pseudorandom string of length @[len].
   */
  #define f_LFib_get_string_defined
ptrdiff_t f_LFib_get_string_fun_num = 0;
void f_LFib_get_string(INT32 args) {
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
INT_TYPE len;
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(args != 1) wrong_number_of_args_error("get_string",args,1);
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
if(Pike_sp[0-1].type != PIKE_T_INT) SIMPLE_BAD_ARG_ERROR("get_string",1,"int");
len=Pike_sp[0-1].u.integer;
#line 839 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
{
    struct pike_string *s = begin_shared_string(len);
    knuth_lfib_random(THIS->ctx, len, s->str);
    push_string(end_shared_string(s));
  }
}

#ifdef LFib_event_handler_defined
static void LFib_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_LFib_defined
  case PROG_EVENT_INIT: init_LFib_struct(); break;

#endif /* internal_init_LFib_defined */

#ifdef internal_exit_LFib_defined
  case PROG_EVENT_EXIT: exit_LFib_struct(); break;

#endif /* internal_exit_LFib_defined */
  default: break; 
  }
}

#endif /* LFib_event_handler_defined */
#line 846 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
/* @endclass
 */

#endif

/*! @endmodule
 */



#endif /* HAVE_LIBNETTLE */

PIKE_MODULE_INIT
{
#ifdef __NT__
  struct program *nt_program = NULL;
  struct object *nt_object = NULL;
#endif /* __NT__ */
  
#ifdef class_Yarrow_defined

#ifdef PROG_YARROW_ID
#line 44 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  START_NEW_PROGRAM_ID(YARROW);
#else
#line 44 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  start_new_program();

#endif /* PROG_YARROW_ID */

#ifndef tObjImpl_YARROW

#undef tObjImpl_YARROW
#define tObjImpl_YARROW tObj

#endif /* tObjImpl_YARROW */

#ifdef THIS_YARROW

  Yarrow_storage_offset=ADD_STORAGE(struct Yarrow_struct);

#endif /* THIS_YARROW */

#ifdef Yarrow_event_handler_defined
  pike_set_prog_event_callback(Yarrow_event_handler);

#endif /* Yarrow_event_handler_defined */

#ifdef f_Yarrow_create_defined
  f_Yarrow_create_fun_num =
#line 56 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("create", f_Yarrow_create, tFunc(tOr(tVoid,"\10\200\0\0\0\177\377\377\377"),tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Yarrow_create_defined */

#ifdef f_Yarrow_seed_defined
  f_Yarrow_seed_fun_num =
#line 88 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("seed", f_Yarrow_seed, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_Yarrow_seed_defined */

#ifdef f_Yarrow_min_seed_size_defined
  f_Yarrow_min_seed_size_fun_num =
#line 105 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("min_seed_size", f_Yarrow_min_seed_size, tFunc(tNone,"\10\0\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Yarrow_min_seed_size_defined */

#ifdef f_Yarrow_get_seed_defined
  f_Yarrow_get_seed_fun_num =
#line 117 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("get_seed", f_Yarrow_get_seed, tFunc(tNone,tString), 0, OPT_EXTERNAL_DEPEND);

#endif /* f_Yarrow_get_seed_defined */

#ifdef f_Yarrow_is_seeded_defined
  f_Yarrow_is_seeded_fun_num =
#line 132 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("is_seeded", f_Yarrow_is_seeded, tFunc(tNone,"\10\0\0\0\0\0\0\0\1"), 0, OPT_EXTERNAL_DEPEND);

#endif /* f_Yarrow_is_seeded_defined */

#ifdef f_Yarrow_force_reseed_defined
  f_Yarrow_force_reseed_fun_num =
#line 143 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("force_reseed", f_Yarrow_force_reseed, tFunc(tNone,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Yarrow_force_reseed_defined */

#ifdef f_Yarrow_update_defined
  f_Yarrow_update_fun_num =
#line 155 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("update", f_Yarrow_update, tFunc(tString "\10\200\0\0\0\177\377\377\377" "\10\200\0\0\0\177\377\377\377","\10\0\0\0\0\0\0\0\1"), 0, OPT_SIDE_EFFECT);

#endif /* f_Yarrow_update_defined */

#ifdef f_Yarrow_needed_sources_defined
  f_Yarrow_needed_sources_fun_num =
#line 175 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("needed_sources", f_Yarrow_needed_sources, tFunc(tNone,"\10\0\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND);

#endif /* f_Yarrow_needed_sources_defined */

#ifdef f_Yarrow_random_string_defined
  f_Yarrow_random_string_fun_num =
#line 184 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("random_string", f_Yarrow_random_string, tFunc("\10\200\0\0\0\177\377\377\377",tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Yarrow_random_string_defined */
#line 44 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  Yarrow_program=end_program();
#line 44 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  Yarrow_program_fun_num=add_program_constant("Yarrow",Yarrow_program,0);

#endif /* class_Yarrow_defined */

#ifdef class_CBC_defined

#ifdef PROG_CBC_ID
#line 307 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  START_NEW_PROGRAM_ID(CBC);
#else
#line 307 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  start_new_program();

#endif /* PROG_CBC_ID */

#ifndef tObjImpl_CBC

#undef tObjImpl_CBC
#define tObjImpl_CBC tObj

#endif /* tObjImpl_CBC */

#ifdef THIS_CBC

  CBC_storage_offset=ADD_STORAGE(struct CBC_struct);

#endif /* THIS_CBC */

#ifdef CBC_event_handler_defined
  pike_set_prog_event_callback(CBC_event_handler);

#endif /* CBC_event_handler_defined */

#ifdef f_CBC_create_defined
  f_CBC_create_fun_num =
#line 387 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("create", f_CBC_create, tFuncV(tOr3(tPrg(tObj),tObj,tFuncV(tNone,tMix,tAny)),tMix,tVoid), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_CBC_create_defined */

#ifdef f_CBC_name_defined
  f_CBC_name_fun_num =
#line 418 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("name", f_CBC_name, tFunc(tNone,tString), 0, OPT_TRY_OPTIMIZE);

#endif /* f_CBC_name_defined */

#ifdef f_CBC_block_size_defined
  f_CBC_block_size_fun_num =
#line 430 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("block_size", f_CBC_block_size, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_CBC_block_size_defined */

#ifdef f_CBC_key_size_defined
  f_CBC_key_size_fun_num =
#line 439 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("key_size", f_CBC_key_size, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND);

#endif /* f_CBC_key_size_defined */

#ifdef f_CBC_set_encrypt_key_defined
  f_CBC_set_encrypt_key_fun_num =
#line 449 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("set_encrypt_key", f_CBC_set_encrypt_key, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_CBC_set_encrypt_key_defined */

#ifdef f_CBC_set_decrypt_key_defined
  f_CBC_set_decrypt_key_fun_num =
#line 463 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("set_decrypt_key", f_CBC_set_decrypt_key, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_CBC_set_decrypt_key_defined */

#ifdef f_CBC_set_iv_defined
  f_CBC_set_iv_fun_num =
#line 476 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("set_iv", f_CBC_set_iv, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_CBC_set_iv_defined */

#ifdef f_CBC_crypt_defined
  f_CBC_crypt_fun_num =
#line 491 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("crypt", f_CBC_crypt, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_CBC_crypt_defined */
#line 307 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  CBC_program=end_program();
#line 307 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  CBC_program_fun_num=add_program_constant("CBC",CBC_program,0);

#endif /* class_CBC_defined */

#ifdef class_Proxy_defined

#ifdef PROG_PROXY_ID
#line 531 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  START_NEW_PROGRAM_ID(PROXY);
#else
#line 531 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  start_new_program();

#endif /* PROG_PROXY_ID */

#ifndef tObjImpl_PROXY

#undef tObjImpl_PROXY
#define tObjImpl_PROXY tObj

#endif /* tObjImpl_PROXY */

#ifdef THIS_PROXY

  Proxy_storage_offset=ADD_STORAGE(struct Proxy_struct);

#endif /* THIS_PROXY */

#ifdef Proxy_event_handler_defined
  pike_set_prog_event_callback(Proxy_event_handler);

#endif /* Proxy_event_handler_defined */

#ifdef f_Proxy_create_defined
  f_Proxy_create_fun_num =
#line 560 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("create", f_Proxy_create, tFuncV(tOr3(tPrg(tObj),tObj,tFuncV(tNone,tMix,tAny)),tMix,tVoid), ID_STATIC, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Proxy_create_defined */

#ifdef f_Proxy_name_defined
  f_Proxy_name_fun_num =
#line 585 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("name", f_Proxy_name, tFunc(tNone,tString), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Proxy_name_defined */

#ifdef f_Proxy_block_size_defined
  f_Proxy_block_size_fun_num =
#line 598 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("block_size", f_Proxy_block_size, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Proxy_block_size_defined */

#ifdef f_Proxy_key_size_defined
  f_Proxy_key_size_fun_num =
#line 608 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("key_size", f_Proxy_key_size, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND);

#endif /* f_Proxy_key_size_defined */

#ifdef f_Proxy_set_encrypt_key_defined
  f_Proxy_set_encrypt_key_fun_num =
#line 621 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("set_encrypt_key", f_Proxy_set_encrypt_key, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_Proxy_set_encrypt_key_defined */

#ifdef f_Proxy_set_decrypt_key_defined
  f_Proxy_set_decrypt_key_fun_num =
#line 638 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("set_decrypt_key", f_Proxy_set_decrypt_key, tFunc(tString,tObj), 0, OPT_SIDE_EFFECT);

#endif /* f_Proxy_set_decrypt_key_defined */

#ifdef f_Proxy_crypt_defined
  f_Proxy_crypt_fun_num =
#line 656 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("crypt", f_Proxy_crypt, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Proxy_crypt_defined */

#ifdef f_Proxy_pad_defined
  f_Proxy_pad_fun_num =
#line 734 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("pad", f_Proxy_pad, tFunc(tNone,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Proxy_pad_defined */

#ifdef f_Proxy_unpad_defined
  f_Proxy_unpad_fun_num =
#line 761 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("unpad", f_Proxy_unpad, tFunc(tString,tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Proxy_unpad_defined */
#line 531 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  Proxy_program=end_program();
#line 531 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  Proxy_program_fun_num=add_program_constant("Proxy",Proxy_program,0);

#endif /* class_Proxy_defined */

#ifdef class_LFib_defined

#ifdef PROG_LFIB_ID
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  START_NEW_PROGRAM_ID(LFIB);
#else
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  start_new_program();

#endif /* PROG_LFIB_ID */

#ifndef tObjImpl_LFIB

#undef tObjImpl_LFIB
#define tObjImpl_LFIB tObj

#endif /* tObjImpl_LFIB */

#ifdef THIS_LFIB

  LFib_storage_offset=ADD_STORAGE(struct LFib_struct);

#endif /* THIS_LFIB */

#ifdef LFib_event_handler_defined
  pike_set_prog_event_callback(LFib_event_handler);

#endif /* LFib_event_handler_defined */

#ifdef f_LFib_create_defined
  f_LFib_create_fun_num =
#line 817 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("create", f_LFib_create, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_LFib_create_defined */

#ifdef f_LFib_reseed_defined
  f_LFib_reseed_fun_num =
#line 826 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("reseed", f_LFib_reseed, tFunc("\10\200\0\0\0\177\377\377\377",tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_LFib_reseed_defined */

#ifdef f_LFib_get_defined
  f_LFib_get_fun_num =
#line 833 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("get", f_LFib_get, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_LFib_get_defined */

#ifdef f_LFib_get_string_defined
  f_LFib_get_string_fun_num =
    ADD_FUNCTION2("get_string", f_LFib_get_string, tFunc("\10\200\0\0\0\177\377\377\377",tString), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_LFib_get_string_defined */
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  LFib_program=end_program();
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
  LFib_program_fun_num=add_program_constant("LFib",LFib_program,0);

#endif /* class_LFib_defined */

#ifdef f_crypt_md5_defined
  f_crypt_md5_fun_num =
#line 216 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    ADD_FUNCTION2("crypt_md5", f_crypt_md5, tFunc(tString tString,tString), 0, OPT_TRY_OPTIMIZE);

#endif /* f_crypt_md5_defined */
#line 864 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
;
#ifdef HAVE_LIBNETTLE
  hash_init();
  cipher_init();
#endif /* HAVE_LIBNETTLE */
#ifdef __NT__
  start_new_program();
  nt_init();
  nt_program = end_program();
  add_object_constant("NT", nt_object=clone_object(nt_program,0), 0);
  free_object(nt_object);
  free_program(nt_program);
#endif /* __NT__ */
}

PIKE_MODULE_EXIT
{
#ifdef HAVE_LIBNETTLE
  cipher_exit();
  hash_exit();
#endif /* HAVE_LIBNETTLE */
#ifdef __NT__
  nt_exit();
#endif /* __NT__ */
  
#ifdef class_Yarrow_defined
  if(Yarrow_program) {
#line 44 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    free_program(Yarrow_program);
    Yarrow_program=0;
  }

#endif /* class_Yarrow_defined */

#ifdef class_CBC_defined
  if(CBC_program) {
#line 307 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    free_program(CBC_program);
    CBC_program=0;
  }

#endif /* class_CBC_defined */

#ifdef class_Proxy_defined
  if(Proxy_program) {
#line 531 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    free_program(Proxy_program);
    Proxy_program=0;
  }

#endif /* class_Proxy_defined */

#ifdef class_LFib_defined
  if(LFib_program) {
#line 802 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
    free_program(LFib_program);
    LFib_program=0;
  }

#endif /* class_LFib_defined */
#line 888 "/export/aphraelraid/home/peter/hack/Pike/7.6/src/post_modules/Nettle/nettle.cmod"
;
}

