scheme

Timothy Newsham newsham at wiliki.eng.hawaii.edu
Tue Feb 23 15:46:40 PST 1993



I posted this to sci.crypt,  I would also like the opinion
of the people on this list:

---------------------------------------
I have posted about this before, but this time I decided
to whip up some code so you can all see what I'm talking
about and all the details.

This encryption scheme uses XOR to encrypt data 1 character
at a time.  Because of this it is suitable for protocols
where you need to send single bytes (or less) at a time.
Examples of this would be interactive ascii.  Also it
is easily applicable to crippled lines like 7 bit lines.
This is because if the plaintext is 7 bits you can send
just the 7 bits after the XOR.  Even more general you can
use it to encrypt any size at a time, down to single bits
if you just have 1 bit to send immediately and dont want
to wait for more data to become applicable.

Ok.  So what are its disavantages?  Syncronization, as
soon as synchronization is gone thats it, its all over.  Each
block of 'pad' is generated from previous plaintext,  if you
cant figure out the previous plaintext you are lost.

Notice it uses a hash() function,  this could be anything, ie
DES,  or perhaps a one way function (no unhash() is ever needed).
The algorithm is fairly simple, the beginning is a bit wierd
and could have been done several ways.  The first 8 bits in
this implementation are used for synchronization.

prog -e key <file >file2
prog -d key <file2 >file3

ok.. here it is..  poke holes in it.  What are the weaknesses,
is it totally unsecure?  Is it as secure as the hash function
(ie. if DES was used, is strength equivalent to the strength of
DES?)


-------------cut here---------------------------------------------

#define SIZE 8
#ifdef MEMCPY
#define bcopy(s,d,l)   memcpy(d,s,l)
#endif

usage(s)
char *s;
{
  printf("%s [-e|e|-d|d] key\n",s);
  exit(1);
}

main(argc,argv)
char **argv;
int argc;
{
  char data[SIZE],pad[SIZE],c[1],c1[1],*p,key[SIZE];
  int cnt,encrypt=0;
  
  if(argc!=3) 
   usage(argv[0]);
  for(cnt=0;cnt<SIZE;cnt++)  /* fill in extra characters in key */
    key[cnt]=0xaa;
  strncpy(key,argv[2],SIZE);
  p=argv[1];
  if(*p=='-') p++;
  if(*p=='e')
    encrypt++;
  else
    if(*p!='d') usage(argv[0]);

  if(encrypt) {
  /* to start off encryption, we send a bunch of random bits */
  /* then we hash those bits and use them as pad             */
    blkrand(data,SIZE);
    write(1,data,SIZE);
    hash(data,key);
  } else {
  /* to start off decryption, we receive the random bits and */
  /* hash them (just like the encryptor did) and we should   */
  /* have the same starting pad as the encryptor             */
    read(0,data,SIZE);
    hash(data,key);
  }
  bcopy(data,pad,SIZE);
  
  cnt=0;
  while(read(0,c,1)>0) {
  /* read characters, send them with our pad       */
  /* every time we run out of pad, we make new pad */
  /* by hashing old data                           */
    *c1 = *c ^ pad[cnt]; 
    if(encrypt)        /* data is the plain text always */
      data[cnt]=*c;
    else
      data[cnt]=*c1;
    write(1,c1,1);
    if(++cnt==SIZE) {
      cnt=0;
      bcopy(data,pad,SIZE);
      hash(pad,key);
    }
  } 
}   
  
/* provide a block of random bits */
blkrand(block,len)
int len;
char *block;
{
  srand(time(0));
  while(len--) 
    *block++ = (rand() >>7)&0xff;
}

/* hash a block, could be DES, or even a one way function */
hash(block,key)
char *block,*key;
{
  char b2[SIZE];
  int i=SIZE;  

  while(i--) 
    b2[i] = *block++ ^ *key++;
  bcopy(b2,block,SIZE);
}


  
  







More information about the cypherpunks-legacy mailing list