/*
 *-----------------------------------------------------------------------------
 * Copyright 1994 DeltaLink bv
 *-----------------------------------------------------------------------------
 * Module Name : encrypt.c
 * Version/Rev : 1.00
 * Author/Date : Leon Westervoort
 * Description : This is a library of encryption and decryption routines
 *
 *-----------------------------------------------------------------------------
 */
#pragma warning( disable : 4121 )
#include <stdio.h>
#include <string.h>
#include <flib.h>

#include "encrypt.h"

char *  _tr_crypt   ( char *, char *, i32);
i32     _tr_pnum    ( char *);

#define PW_MIN_LEN   3                          /* minimum number of chars in password */
#define PW_MIN_NUM   10000000                   /* number of digits in password return number */

/*
 *-----------------------------------------------------------------------------
 * Function/Type: _trp_crypt
 * Description  : called by _tr_crypt for encrypt() and decrypt(), and by
 *                password()
 *
 *------------------- Parameters, Variables, & Conditions ---------------------
 * Enter with   : 
 *
 * Exits with   : 
 *
 *          The following encryption algorithm handles the full
 *          international ASCII character set. Passnum is an 
 *          integer between 1 and 254 that receives a value
 *          returned from _tr_pnum based on the password.
 *
 *          Passnum is a seed for the encryption-key variable
 *          that is modified in the for-loop by the position
 *          of the current character in reference to the total 
 *          string (i - len). This produces a non-repeating 
 *          pattern even if all the characters are the same, 
 *          thus hiding the length of the password key.
 *
 *          The password characters are always being rotated
 *          in a circular manner (que).
 * 
 *          ret[i] gets the bitwise XOR of the character with 
 *          the XOR of passnum and the current character in the 
 *          password que. This gives 24 bits of encryption for
 *          each character. 
 *
 *          This encryption/decryption program can be broken 
 *          by any computer-literate person with access to this
 *          source code or a knowledge of cryptography.
 *
 *-----------------------------------------------------------------------------
 */

char *_tr_crypt( char *instr, char *pwstr, i32 len ) {

  short j,
        pwlen =  (short)strlen( pwstr),
        passnum;
  i32 i;
  char buff;


  /* get seed value */

  passnum = ( short) (((( _tr_pnum( pwstr) / 997) - 1) % 254 ) + 1);

  for( i = j = 0; i < len; i++ ) {                         /* process whole string */
  
    passnum = ( short) ((( passnum + ( i - len )) - 1 ) % 254) + 1;
     
    buff = ( instr[i] ^ ( ( char)passnum ^ pwstr[j]) );     /* XOR 3 var's */

    instr[i] = ( buff ? buff : instr[i]);                  /* if NULL return char */

    if( j >= pwlen) j = 0;
    else            j++;
  }

  return instr;                                            /* send back encrypted string */
}

/*
 *-----------------------------------------------------------------------------
 * Function/Type: _trp_num
 * Description  : 
 *
 *------------------- Parameters, Variables, & Conditions ---------------------
 * Enter with   : 
 *
 * Exits with   : <expC> of <string> encoded according to <password>.
 *                Return string will be same length as <string>.
 *                Unchanged <string> if <password> is less than 3 characters.
 *
 *-----------------------------------------------------------------------------
 */

void k_encrypt( char *pwstr, char *instr, long len ) {

  /*
   * password string must be minimal three characters
   */
  if( strlen( pwstr) < PW_MIN_LEN ) return;

  /* return encrypted string */

  _tr_crypt( instr, pwstr, (i32)len );

  return;
}

/*
 *-----------------------------------------------------------------------------
 * Function/Type: _trp_num
 * Description  : called by _tr_crypt for encrypt() and decrypt(), and by
 *                password()
 *
 *------------------- Parameters, Variables, & Conditions ---------------------
 * Enter with   : 
 *
 * Exits with   : 
 *
 *-----------------------------------------------------------------------------
 */

i32 _tr_pnum( char *s ) {

 i32 ret = 1L;
 int i;

 if( s[0] && s[1] && s[2] ) {                         /* 3 char minimum password len */

    /* sum the ascii values of each char */

    for( i = 0; s[i]; i++ ) ret += ( i32)( s[i] + i);


    /* bit shift ret 1 position to the left until ret exceeds PW_MIN_NUM */

    for( ; ret < PW_MIN_NUM; ret <<= 1 ) ;

    return ret;
  }
  else
    return -1L;     
}
