/* @(#)cypher.h	11.1 13 May 1995 17:27:12 */
/*
 * cypher - Noll Lightning Cypher based on SHS
 *
 * This file was Modified by:
 *
 *	 Landon Curt Noll  (chongo@toad.com)	chongo <was here> /\../\
 *
 * This code has been placed in the public domain.  Please do not
 * copyright this code.
 *
 * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH  REGARD  TO
 * THIS  SOFTWARE,  INCLUDING  ALL IMPLIED WARRANTIES OF MER-
 * CHANTABILITY AND FITNESS.  IN NO EVENT SHALL  LANDON  CURT
 * NOLL  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM  LOSS  OF
 * USE,  DATA  OR  PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR  IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * WARNING: This code, and the algorithm that it claims to implement
 *	    are under-going peer review.  During peer review, both
 *	    source and algorithm may be modified extensively.
 *
 * WARNING: Certain US Regulations may restrict and/or prohibit 
 *	    the exportation of this software.  Please consult the
 *	    proper Federal authorities and/or seek legal advice
 *	    if you desire to export this software!
 *
 * See krypt.c for version and modification history.
 */

#if !defined(NLC_H)
#define NLC_H

/*
 * determine if we are checked in
 */
#define NLC_H_WHAT "@(#)"	/* @(#) if checked in */

/*
 * Useful defines/typedefs
 */
typedef unsigned char BYTE;	/* must be a 1 byte unsigned value */
typedef unsigned long UINT;	/* must be a 2 byte unsigned value */
typedef unsigned long ULONG;	/* must be a 4 byte unsigned value */

/* NLC_CHUNKSIZE must be a power of 2 - fixed value defined by the algorithm */
#define NLC_CHUNKSIZE (1<<6)
#define NLC_CHUNKWORDS (NLC_CHUNKSIZE/sizeof(ULONG))

/* NLC_DIGESTSIZE is a the length of the digest as defined by the algorithm */
#define NLC_DIGESTSIZE (20)
#define NLC_DIGESTWORDS (NLC_DIGESTSIZE/sizeof(ULONG))

/*
 * MAXBLOCK - maximum blocking factor
 *
 * must be power of 2 > NLC_CHUNKSIZE and <= READSIZE and < 2^29
 */
#define MAXBLOCK (NLC_CHUNKSIZE<<9)

/* READSIZE must be a multiple of NLC_CHUNKSIZE >= MAXBLOCK */
#define READSIZE (NLC_CHUNKSIZE<<9)
#define READWORDS (READSIZE/sizeof(ULONG))

/* maximum part of pre_file used - must be <= MAXBLOCK */
#define MAX_PRE_FILE MAXBLOCK

/*
 * SWAP_BYTE_SEX(ULONG *dest, ULONG *src)
 *
 *	dest	- array of NLC_CHUNKWORDS ULONG of fixed data (may be src)
 *	src	- array of NLC_CHUNKWORDS ULONG of what to fix
 *
 * This macro will either switch to the opposite byte sex (Big Endian vs.
 *  Little Endian).
 */
#define SWAP_BYTE_SEX(dest, src) {	/* swap byte sex if needed */	\
    int tmp_i;	/* index */						\
    for (tmp_i=0; tmp_i < NLC_CHUNKWORDS; ++tmp_i) {			\
	((ULONG*)(dest))[tmp_i] =					\
	  (((ULONG*)(src))[tmp_i] << 16) |				\
	  (((ULONG*)(src))[tmp_i] >> 16);				\
	((ULONG*)(dest))[tmp_i] =					\
	  ((((ULONG*)(dest))[tmp_i] & 0xff00ff00UL) >> 8) |		\
	  ((((ULONG*)(dest))[tmp_i] & 0x00ff00ffUL) << 8);		\
    }									\
}

/*
 * ROUNDUP(x,y) - round x up to the next multiple of y
 */
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))

/*
 * The structure for storing NLC info
 *
 * We will assume that bit count is a multiple of 8.
 */
typedef struct {
    ULONG digest[NLC_DIGESTWORDS];	/* message digest */
    ULONG datalen;			/* bytes unprocessed in data */
    ULONG data[NLC_CHUNKWORDS];		/* data chunk buffer */
    ULONG out[NLC_CHUNKWORDS];		/* output chunk buffer */
    ULONG ring[2*NLC_CHUNKWORDS];	/* shuffle/xor buf digest expansion */
    ULONG sum_dig[NLC_DIGESTWORDS];	/* sum of previous digest states */
    int dcrypt;				/* 0 => encrypt, 1 => decrypt */
    int output_sex;			/* output byte sex */
    int output_ok;			/* 1 => ok to output */
    FILE *stream;			/* where to write output */
} NLC_INFO;

/*
 * Used to remove arguments in function prototypes for non-ANSI C
 */
#if defined(__STDC__) && __STDC__ == 1
# define PROTO
#endif
#ifdef PROTO
# define P(a) a
#else	/* !PROTO */
# define P(a) ()
#endif	/* ?PROTO */

/* cypher.c */
void nlcInitCypher P((NLC_INFO*, int, int, FILE*));
void nlcCypher P((NLC_INFO*, BYTE*, ULONG));
void nlcFullCypher P((NLC_INFO*, BYTE*, ULONG));
void nlcFinalCypher P((NLC_INFO*));
extern char *nlc_what;

#endif /* NLC_H */
