[sci.crypt] cryptext.c mix subroutine

Jon Boede jon at walt.cc.utexas.edu
Thu Apr 12 07:36:18 AEST 1990


Archive-name: cryptext/11-Apr-90
Original-posting-by: jon at walt.cc.utexas.edu (Jon Boede)
Original-subject: cryptext.c mix subroutine
Reposted-by: emv at 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 at math.lsa.umich.edu 
(Edward Vielmetti).]


I'd posted a message a while back looking for an encryption routine that had
a number of less-than-usual characteristics.  Istvan Mohos was kind enough to
send me his "mix" program suite which I am enjoying quite a bit.  All I needed
out of the whole program suite was just a subroutine to encrypt a string.  I
whipped something up and am posting it here for anyone who might be interested.

The most charming characteristics of the cryptext subroutine are the fact that
the resultant string is the same length and of the same character set as the
input string.  In what follows, "text" is a NUL terminated string of any
length, "kstring" is the key also of any length, and "encrypt" is a flag where
1=encrypt and 0=decrypt.

The only odd thing is FUDGE, which had to be added to the length of the input
string as not to corrupt the malloc() heap... apparently unmix() runs off the
end of the string by a little (I suspect sizeof(struct keychar) but have not
investigated it further).

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	cryptext.c
# This archive created: Wed Apr 11 14:33:57 1990
echo shar: extracting cryptext.c '(3132 characters)'
sed 's/^XX//' << \SHAR_EOF > cryptext.c
XX#include <stdio.h>
XX
XXstruct keychar {       /* links to form chain of key bytes */
XX    int val;
XX    struct keychar *next;
XX};
XX
XX/* this seems necessary to keep the heap from being corrupted by unmix */
XX#define FUDGE 10
XX
XX/* should be in a header file */
XX#define CRYPTKEYLEN 40
XX
XXcryptext(text,kstring,encrypt)
XXchar *text, *kstring;
XXint encrypt;
XX{
XX	int len, loop, klen;
XX	char *out_text, *malloc();
XX	register char *cs;
XX	struct keychar key[CRYPTKEYLEN];
XX
XX	len = strlen(text);
XX	klen = strlen(kstring);
XX
XX	if ((out_text = malloc(len + FUDGE)) == NULL) {
XX		printf("\nOut of memory... couldn't crypt.\n");
XX		return(1);
XX	}
XX
XX	for (loop=klen, cs=kstring+klen; --loop; ) {
XX		key[loop].next = key + loop - 1;
XX		key[loop].val = *--cs;
XX	}
XX	key[0].next = key + klen - 1;
XX	key[0].val = *--cs;
XX
XX	if (encrypt)
XX		mix(key,text,out_text);
XX	else {
XX		for (loop=0; loop < len; loop++)
XX			out_text[loop] = '\0';
XX		unmix(key,text,out_text);
XX	}
XX	strncpy(text,out_text,len);
XX	text[len] = '\0';
XX	free(out_text);
XX	return(0);
XX}
XX
XX/*  mix:
XX	Author          : Istvan Mohos, March 1987
XX	Rev A Apr 14 87 : Do not mix last byte
XX	Rev B Apr 27 87 : by Ira Chayut; R & D Associates
XX
XX	given key byte ASCII values "a b c ... n" in circularly linked list,
XX	and plaintext char pointer ptr initially at plaintext[0],
XX
XX	advance ptr "a" bytes;
XX	install its value as the first byte of cyphertext;
XX	zero out plaintext byte pointed to by ptr;
XX	decrement value of "a";
XX
XX	while (not done) {
XX		advance to next link of key;
XX		advance ptr by the value of the link;
XX		install ptr value as the next byte of cyphertext;
XX		zero out plaintext byte pointed to by ptr;
XX		decrement value of link;
XX	}
XX
XX	Throughout, plaintext is assumed to be a circular list of bytes:
XX	ptr increments beyond the buffer continue from the beginning.
XX	If ptr value is null (byte already assigned to cyphertext), ptr is
XX	incremented until the next non-null plaintext byte.
XX	When key link value reaches zero, the just assigned plaintext byte
XX	is swapped into its position.
XX*/
XX
XXmix(key,plain,cipher)
XXstruct keychar key[];
XXchar *plain, *cipher;
XX{
XX	register struct keychar *K;
XX	register char *here, *cip;
XX	char *head, *tail;
XX	int regi, loop, flen;
XX
XX	flen = strlen(plain);
XX
XX	head = plain;
XX	here = head + flen - 1;
XX	tail = here - 1;
XX	loop = head - tail - 1; /* always negative */
XX	cip = cipher;
XX	K = key;
XX
XX	for (regi=flen-1; --regi >= 0; ) {
XX		if ((here = here + K->val) > tail)
XX			here += loop;
XX		while (!*here)
XX			if (++here > tail)
XX				here = head;
XX		if (!--K->val)
XX			K->val = *here;
XX		K = K->next;
XX		*cip++ = *here;
XX		*here = 0;
XX	}
XX	*cip = *++tail;
XX}
XX
XXunmix(key,cipher,plain)
XXstruct keychar key[];
XXchar *cipher, *plain;
XX{
XX	register struct keychar *K;
XX	register char *here, *cip;
XX	char *head, *tail;
XX	int regi, flen, loop;
XX
XX	flen = strlen(cipher);
XX
XX	head = plain;
XX	K = key;
XX	here = head + K->val;
XX	tail = head + flen -2;
XX	loop = head - tail -1; /* always negative */
XX	cip = cipher;
XX
XX	for (regi = flen -1; --regi >= 0; ) {
XX		while (*here)
XX			if (++here > tail)
XX				here = head;
XX		*here = *cip++;
XX		if (!--K->val)
XX			K->val = *here;
XX		K = K->next;
XX		if ((here = here + K->val) > tail)
XX			here += loop;
XX	}
XX	*(tail +1) = *cip;
XX}
SHAR_EOF
if test 3132 -ne "`wc -c cryptext.c`"
then
echo shar: error transmitting cryptext.c '(should have been 3132 characters)'
fi
#	End of shell archive
exit 0
Jon Boede    jon at bodedo.ucm.org   ...!{uunet,texbell}!cs.utexas.edu!bodedo!jon
7117 Wood Hollow #726, People's Republic of Austin, TX  78731  +1 512 346-3142



More information about the Alt.sources mailing list