jon@walt.cc.utexas.edu (Jon Boede) (04/12/90)
Archive-name: cryptext/11-Apr-90 Original-posting-by: jon@walt.cc.utexas.edu (Jon Boede) Original-subject: cryptext.c mix subroutine 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).] 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@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