[alt.sources] Dynamic Substitution Cipher sci.crypt

sampson@attctc.Dallas.TX.US (Steve Sampson) (01/06/90)

Archive-name: dynsub/v1.01
Original-posting-by: sampson@attctc.Dallas.TX.US (Steve Sampson)
Original-subject: Dynamic Substitution (debugged)
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[This is an experimental alt.sources re-posting from the newsgroup(s)
sci.crypt. Comments on this service to emv@math.lsa.umich.edu 
(Edward Vielmetti).]


My earlier bug question was answered by Yves Gallot who determined
that I needed 'unsigned char' for it to work.  In case anyone is
interested in trying Terry Ritter's Dynamic Substitution algorithm:

/*
 *	dynsub.c
 *
 *	Dynamic Substitution Cipher Filter
 *
 *	Evaluation Version 1.01, January 1990
 *
 *	Copyright (c) November 5, 1989, By Terry F. Ritter
 *	All Rights Reserved
 *
 *	Modified for Turbo-C by sampson@attctc.dallas.tx.us (steve)
 *	with help from cernvax!galloty@relay.EU.net (yves gallot)
 */

#include <stdio.h>

#ifdef __TURBOC__
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#else
#define	random(x)	(rand() % (x))
#endif

#define	BSIZE	256

unsigned char	f[BSIZE], finv[BSIZE], buf[BSIZE];

void ExchangeChars(x, y)
unsigned char	*x, *y;
{
	unsigned char	t;

	t = *x;
	*x = *y;
	*y = t;
}

void DynSubInit()
{
	register int	i;

	for (i = 0; i < BSIZE; i++)
		f[i] = (unsigned char)i;

	for (i = 0; i < BSIZE; i++)
		ExchangeChars(&f[i], &f[random(BSIZE)]);
}

void InvDynSubInit()
{
	register int	i;

	DynSubInit();

	for (i = 0; i < BSIZE; i++)
		finv[f[i]] = (unsigned char)i;
}

unsigned char DynSubF(xi)
unsigned char	xi;
{
	unsigned char	t;

	t = f[xi];
	ExchangeChars(&f[xi], &f[random(BSIZE)]);

	return t;
}

unsigned char InvDynSubF(yi)
unsigned char	yi;
{
	unsigned char	j, xi, yj;

	xi = finv[yi];
	j  = random(BSIZE);
	yj = f[j];

	ExchangeChars(&finv[yi], &finv[yj]);
	ExchangeChars(&f[xi], &f[j]);

	return xi;
}

void encipher()
{
	register int	i, got;

	DynSubInit();

	for (;;)  {
		if ((got = fread(buf, sizeof(char), BSIZE, stdin)) < 1)
			return;

		for (i = 0;  i < got; i++)
			buf[i] = DynSubF(buf[i]);

		fwrite(buf, sizeof(char), got, stdout);
	}
}

void decipher()
{
	register int	i, got;

	InvDynSubInit();

	for (;;)  {
		if ((got = fread(buf, sizeof(char), BSIZE, stdin)) < 1)
			return;

		for (i = 0; i < got; i++)
			buf[i] = InvDynSubF(buf[i]);

		fwrite(buf, sizeof(char), got, stdout);
	}
}

main(argc, argv)
int	argc;
char	**argv;
{

#ifdef __TURBOC__
        /*
         *      Change stdin/stdout to binary mode, big buffers
         */

        setmode(0, O_BINARY);
        setmode(1, O_BINARY);

	setvbuf(stdin,  NULL, _IOFBF, BSIZE);
	setvbuf(stdout, NULL, _IOFBF, BSIZE);
#endif

	if (argc == 3)  {
		argv++;
		srand(atoi(*argv));
	} else
		srand(1);

	argv++;
	if (**argv == 'd')
		decipher();
	else if (**argv == 'e')
		encipher();
	else  {
		puts("Usage: dynsub [key 0 - 65536] e|d <infile >outfile");
		exit(1);
	}

	exit(0);
}