diff -C 2 -P -r tontine-0.3/version.h tontine-0.3p3/version.h
*** tontine-0.3/version.h	Thu Jan  1 01:00:00 1970
--- tontine-0.3p3/version.h	Thu Nov 11 14:48:21 1999
***************
*** 0 ****
--- 1 ----
+ static char version_string[] = "tontine-0.3p3";
diff -C 2 -P -r tontine-0.3/FIOstream.cpp tontine-0.3p3/FIOstream.cpp
*** tontine-0.3/FIOstream.cpp	Thu Jan  1 01:00:00 1970
--- tontine-0.3p3/FIOstream.cpp	Mon Aug 30 10:12:04 1999
***************
*** 0 ****
--- 1,363 ----
+ // Formatted streams.
+ // Norman Gray <norman@astro.gla.ac.uk>
+ //
+ // Produces output, and reads input, in one of the formats listed in
+ // FIOstream::Formats.
+ //
+ // Reasonably thorough, but rather primitive, error checking,
+ // mostly in the form of assertions which dump core when they fail.
+ 
+ #ifndef NULL
+ #define NULL 0			// gcc include files seem to have some errors
+ #endif
+ 
+ #include "FIOstream.h"
+ #include "btoe.h"
+ #include <ctype.h>
+ 
+ FIOstream::Formats FIOstream::ioType_ = FIOstream::Binary;
+ const char *FIOstream::base64Coding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ char *FIOstream::base64DeCoding = 0;
+ 
+ FIOstream::~FIOstream()
+ {
+   if (isOpen_)
+   {
+     close();
+     isOpen_ = false;
+   }
+   moreInput_ = false;
+ }
+ 
+ // Will _not_ reopen a file if it's already open
+ bool FIOstream::open (string name, Mode RW)
+ {
+   if (!isOpen_)
+   {
+     isWrite_ = (RW == Write);
+     F_ = fopen (name.c_str(), (isWrite_ ? "w" : "r"));
+     isOpen_ = (F_ != NULL);
+     moreInput_ = isOpen_;
+   }
+   return isOpen_;
+ }
+ 
+ void FIOstream::close()
+ {
+   if (isOpen_)
+   {
+     if (isWrite_)
+     {
+       if (ioType_ == Base64)
+ 	flushBase64();
+       else if (ioType_ == Words)
+ 	flushWords();
+       fflush (F_);		// largely unnecessary, but...
+     }
+     fclose(F_);
+     F_ = NULL;
+     isOpen_ = false;
+     // don't fiddle with moreInput_ here!
+   }
+ }
+ 
+ bool FIOstream::eof() const
+ {
+   // readers below immediately close file when they find EOF
+   return !moreInput_;
+ }
+ 
+ void FIOstream::write (unsigned char ch)
+ {
+   assert (isWrite_);		// wrong: better would be to throw an exception
+ 
+   if (isOpen_)
+     if (ioType_ == Binary)
+       fputc (ch, F_);
+     else if (ioType_ == Base64)
+       toBase64(ch);
+     else if (ioType_ == Words)
+       toWords(ch);
+ }
+ 
+ unsigned char FIOstream::read ()
+ {
+   assert (!isWrite_);		// wrong: better would be to throw an exception
+ 
+   unsigned char t;
+   if (!eof())
+   {
+     if (ioType_ == Binary)
+     {
+       int ti = fgetc (F_);
+       if (ti == EOF)
+       {
+ 	close ();
+ 	moreInput_ = false;
+ 	t = 0;			// always succeed
+       }
+       else
+ 	t = static_cast<unsigned char>(ti);
+     }
+     else if (ioType_ == Base64)
+       t = fromBase64();
+     else
+     {
+       assert (ioType_ == Words);
+       t = fromWords();
+     }
+   }
+   else
+     t = 0;
+ 
+   return t;
+ }
+ 
+ // See RFC 2045, section 6.8
+ void FIOstream::toBase64 (unsigned char ch)
+ {
+   assert (nochars_ < 3);
+   assert (isWrite_);
+ 
+   ochars_[nochars_] = ch;
+   nochars_++;
+   if (nochars_ == 3)		// write them
+   {
+     unsigned char t;
+     fputc (base64Coding[(ochars_[0] & 0xfc) >> 2], F_);
+     t = ((ochars_[0] & 0x03) << 4) | ((ochars_[1] & 0xf0) >> 4);
+     fputc (base64Coding[t], F_);
+     t = ((ochars_[1] & 0x0f) << 2) | ((ochars_[2] & 0xc0) >> 6);
+     fputc (base64Coding[t], F_);
+     fputc (base64Coding[ochars_[2] & 0x3f], F_);
+ 
+     nochars_ = 0;
+ 
+     nquartets_++;
+     if (nquartets_ >= 19)
+     {
+       fputs ("\r\n", F_);
+       nquartets_ = 0;
+     }
+   }
+ }
+ 
+ void FIOstream::flushBase64 ()
+ {
+   assert (isWrite_);
+ 
+   for (unsigned int i=nochars_; i<3; i++)
+     ochars_[i] = 0;		// fill with zero bytes
+ 
+   if (nochars_ == 0)
+   {
+     fputs ("\r\n", F_);
+     return;
+   }
+ 
+   if (nochars_ > 0)
+   {
+     unsigned char t;
+     fputc (base64Coding[(ochars_[0] & 0xfc) >> 2], F_);
+     t = ((ochars_[0] & 0x03) << 4) | ((ochars_[1] & 0xf0) >> 4);
+     fputc (base64Coding[t], F_);
+   }
+ 
+   if (nochars_ > 1)
+   {
+     unsigned char t;
+     t = ((ochars_[1] & 0x0f) << 2) | ((ochars_[2] & 0xc0) >> 6);
+     fputc (base64Coding[t], F_);
+   }
+   else
+     fputc ('=', F_);
+ 
+   fputs ("=\r\n", F_);
+ 
+   nochars_ = 0;
+ }
+ 
+ // Decode base64.  Little error checking, since we assume we wrote the file 
+ // correctly!
+ unsigned char FIOstream::fromBase64 (void)
+ {
+   assert (!isWrite_);
+   if (! moreInput_)
+     return 0;
+ 
+   // nochars_ is the number of converted but unread characters in the buffer
+   assert (nochars_ < 3);
+   if (nochars_ == 0)		// read some more
+   {
+     if (! isOpen_)		// end of file and end of buffer: all gone!
+     {
+       moreInput_ = false;
+       return 0;
+     }
+     unsigned char c[4];
+     int nequals = 0;
+     for (unsigned int i=0; i<4; i++)
+       c[i] = getBase64Character();
+     if (!isOpen_)
+       return 0;
+     for (unsigned int i=0; i<4; i++)
+     {
+       if (c[i] == '=')		// EOD pad character
+ 	nequals++;		// '=' maps to \0, so nothing else to do
+       c[i] = base64DeCoding[c[i]];
+     }
+     ochars_[0] = ((c[0] << 2) | ((c[1] & 0x30) >> 4));
+     ochars_[1] = (((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2));
+     ochars_[2] = (((c[2] & 0x03) << 6) | c[3]);
+ 
+     if (nequals == 0)		// normal case
+       nochars_ = 3;
+     else			// we found the pad characters at end of file
+     {
+       // discard pad characters, and shuffle so that there are only
+       // (3-nequals) characters left to read
+       if (nequals == 2)
+       {
+ 	ochars_[2] = ochars_[0];
+ 	nochars_ = 1;
+       }
+       else
+       {
+ 	assert (nequals == 1);
+ 	ochars_[2] = ochars_[1];
+ 	ochars_[1] = ochars_[0];
+ 	nochars_ = 2;
+       }
+     }
+   }
+   return ochars_[3-(nochars_--)];
+ }
+ 
+ // Get a base64 character from the input, skipping all non-base64
+ // characters, and also skipping any `#...' comments.
+ unsigned char FIOstream::getBase64Character()
+ {
+   if (! isOpen_)
+     return 0;			// always succeed
+ 
+   if (base64DeCoding == 0)	// initialise it
+   {
+     base64DeCoding = new char[256];
+     for (unsigned int i=0; i<256; i++) // set everything to charIgnore
+       base64DeCoding[i] = charIgnore;
+     for (unsigned int i=0; i<64; i++) // ... except legal characters
+       base64DeCoding[base64Coding[i]] = i;
+     base64DeCoding[static_cast<unsigned int>('=')] = 0;
+ 			// ... the pad character (actual map value irrelevant)
+     base64DeCoding[static_cast<unsigned int>('#')] = charComment;
+     base64DeCoding[static_cast<unsigned int>('\r')] = charEOL;
+     base64DeCoding[static_cast<unsigned int>('\n')] = charEOL;
+ 			// ... and special characters
+   }
+ 
+   int ic;
+   do
+   {
+     ic = fgetc (F_);
+     if (base64DeCoding[ic] == charComment)
+       do			// read to end-of-line
+ 	ic = fgetc (F_);
+       while (ic != EOF && base64DeCoding[ic] != charEOL);
+ 
+     if (ic == EOF)
+     {
+       close ();
+       return 0;			// JUMP OUT
+     }
+   }
+   while (base64DeCoding[ic] > 63);
+   return static_cast<unsigned char>(ic);
+ }
+   
+ void FIOstream::toWords (unsigned char ch)
+ {
+   assert (isWrite_);
+ 
+   ochars_[nochars_] = ch;
+   nochars_++;
+   if (nochars_ == 8)		// write them
+   {
+     btoe (ebuf_, ochars_);
+     fputs (ebuf_, F_);
+     fputc ('\n', F_);
+     nochars_ = 0;
+   }
+ }
+ 
+ void FIOstream::flushWords ()
+ {
+   assert (isWrite_);
+   if (nochars_ == 0)
+     return;
+ 
+   for (unsigned int i=nochars_; i<8; i++)
+     ochars_[i] = 0;		// fill with zero bytes -- OK for string input
+   btoe (ebuf_, ochars_);
+   fputs (ebuf_, F_);
+   fputc ('\n', F_);
+   nochars_ = 0;
+ }
+ 
+ unsigned char FIOstream::fromWords ()
+ {
+   assert (!isWrite_);
+ 
+   if (! moreInput_)
+     return 0;			// always succeed
+ 
+   // nochars_ is the number of converted but unread characters in the buffer
+   assert (nochars_ < 8);
+   if (nochars_ == 0)		// read some more
+   {
+     if (!isOpen_)		// ... but no more available
+     {
+       moreInput_ = false;
+       return 0;			// always succeed
+     }
+ 
+     char words[6*5+2];
+     int buflen = sizeof(words);
+     int wi = 0;
+     for (int nowords=0; nowords < 6; nowords++)
+     {
+       int ic;
+       do
+ 	ic = fgetc (F_);
+       while (isspace(ic));
+       if (ic == EOF)
+       {
+ 	assert (nowords == 0);	// should only happen at beginning of block
+ 	close();
+ 	return 0;		// LEAP OUT
+       }
+       do
+       {
+ 	words[wi++] = static_cast<char>(ic);
+ 	assert (wi < buflen);	// 6 well-formed words (<= 4 chars) should fit
+ 	ic = fgetc (F_);
+       }
+       while (isalpha(ic));
+       if (ic == EOF)
+       {
+ 	assert (nowords == 5);	// should be only when we've found 6 words
+ 	close();
+       }
+       words[wi++] = ' ';
+     }
+     words[wi-1] = '\0';
+ 
+     int etob_ret = etob (ochars_, words);
+     if (etob_ret != 1)
+     {
+       cerr << "Error converting words '" << words << "'\n";
+       return 0;
+     }
+     nochars_ = 8;
+   }
+   return ochars_[8-(nochars_--)];
+ }
diff -C 2 -P -r tontine-0.3/FIOstream.h tontine-0.3p3/FIOstream.h
*** tontine-0.3/FIOstream.h	Thu Jan  1 01:00:00 1970
--- tontine-0.3p3/FIOstream.h	Mon Aug 30 10:12:04 1999
***************
*** 0 ****
--- 1,67 ----
+ // Formatted output stream
+ #ifndef _FIOstream_h
+ #define _FIOstream_h
+ 
+ #include <cstdio>
+ #include <string>
+ 
+ class FIOstream {
+  public:
+   enum Formats { Binary, Base64, Words };
+   enum Mode { Read, Write };
+ 
+   FIOstream (string name, Mode RW = Write)
+     : isOpen_(false), moreInput_(false), nquartets_(0), nochars_(0)
+     { open (name, RW); };
+   ~FIOstream();
+   bool open (string name, Mode RW = Write);
+   // write a byte to the output
+   void write (unsigned char ch);
+   // Read a byte from the input.
+   // Attempts to read past EOF will succeed, but return zero and set EOF.
+   unsigned char read ();
+   // eof() true means characters from read() are fake
+   bool eof () const;
+   // This is so we can do the weird test in SecretShare
+   //bool weirdTest () const { return (!Stream_); };
+   bool weirdTest () const { return eof(); };
+   //fstream& stream () const { return Stream_; };
+   static void setFormat (Formats t) { ioType_ = t; }
+ 
+  private:
+   FILE *F_;
+   bool isOpen_;			// input file is open and not at EOF
+   bool isWrite_;
+   bool moreInput_;		// more input available
+   // moreInput_ can be true even when isOpen_ is false, if there are 
+   // still buffered characters available.
+ 
+   static Formats ioType_;
+ 
+   void close ();
+ 
+   // Following for the Base64 encoder
+   // This needs ochars_ to be only [3], but if we make it [8], the words
+   // encoder/decoder can use it too.
+   int nquartets_;
+   unsigned char ochars_[8];
+   int nochars_;
+   static const char *base64Coding;
+   static char *base64DeCoding;
+   static const int charComment = 64;
+   static const int charEOL = 65;
+   static const int charIgnore = 66;
+ 
+   void toBase64 (unsigned char ch);
+   void flushBase64();
+   unsigned char fromBase64 ();
+   unsigned char getBase64Character();
+ 
+   // Following for the english-words encoder/decoder
+   char ebuf_[6*5+1];		// six * (word + space) plus termination
+   void toWords (unsigned char ch);
+   void flushWords ();
+   unsigned char fromWords ();
+ };
+ 
+ #endif
diff -C 2 -P -r tontine-0.3/Makefile tontine-0.3p3/Makefile
*** tontine-0.3/Makefile	Sun Oct  4 08:42:18 1998
--- tontine-0.3p3/Makefile	Fri Sep 17 15:04:46 1999
***************
*** 1,9 ****
! LIBS = -L../prng 
! CXXFLAGS = $(DEBUG) -Wall -O3 -fguiding-decls
  
  OBJ = GF256.o LagrangePolynomialInterpolation.o \
!       Point.o Polynomial.o RNGenerator.o SecretShare.o
  
! %.o: %.cpp %.h
  	$(CXX) $(CXXFLAGS) $< -c -o $@
  
--- 1,12 ----
! #LIBS = -L../prng 
! LIBS = 
! # What does -fguiding-decls do?
! CXXFLAGS = -O3 -fguiding-decls
! #CXXFLAGS = -g -Wall -fguiding-decls
  
  OBJ = GF256.o LagrangePolynomialInterpolation.o \
!       Point.o Polynomial.o RNGenerator.o SecretShare.o FIOstream.o btoe.o
  
! %.o: %.cpp
  	$(CXX) $(CXXFLAGS) $< -c -o $@
  
***************
*** 12,15 ****
--- 15,30 ----
  tontine: $(OBJ) main.cpp
  	$(CXX) $(CXXFLAGS) $(OBJ) main.cpp -o $@ $(LIBS)
+ 
+ GF256.o: GF256.cpp GF256.h GF256tables.h
+ LagrangePolynomialInterpolation.o: LagrangePolynomialInterpolation.cpp\
+ 		 LagrangePolynomialInterpolation.h
+ Point.o: Point.cpp Point.h
+ Polynomial.o: Polynomial.cpp Polynomial.h
+ RNGenerator.o: RNGenerator.cpp RNGenerator.h
+ SecretShare.o: SecretShare.cpp SecretShare.h FIOstream.h\
+ 		 LagrangePolynomialInterpolation.h
+ main.o: main.cpp RNGenerator.h SecretShare.h FIOstream.h
+ FIOstream.o: FIOstream.cpp FIOstream.h btoe.h
+ btoe.o: btoe.c btoe.h
  
  clean:
diff -C 2 -P -r tontine-0.3/Polynomial.i tontine-0.3p3/Polynomial.i
*** tontine-0.3/Polynomial.i	Sun Oct  4 08:10:50 1998
--- tontine-0.3p3/Polynomial.i	Mon Sep 13 12:42:03 1999
***************
*** 11,17 ****
  template <class NUMBER>
  inline Polynomial<NUMBER>::
! Polynomial(int degree=0) : degree(0), allocated(degree)
  {
!   coefficient = new NUMBER[degree + 1];
    
    // for (int i = 0; i <= allocated; i++)
--- 11,17 ----
  template <class NUMBER>
  inline Polynomial<NUMBER>::
! Polynomial(int newdegree=0) : degree(0), allocated(newdegree)
  {
!   coefficient = new NUMBER[newdegree + 1];
    
    // for (int i = 0; i <= allocated; i++)
diff -C 2 -P -r tontine-0.3/README tontine-0.3p3/README
*** tontine-0.3/README	Sun Oct  4 08:40:05 1998
--- tontine-0.3p3/README	Thu Nov 11 14:47:17 1999
***************
*** 55,56 ****
--- 55,90 ----
  solution is to add (0,R), where R is a random byte, and in decoding, we
  simply skip this pair.
+ 
+ ---
+ 
+ Note added by Norman Gray <norman@astro.gla.ac.uk>, 11 November 1999.
+ 
+ I've patched tontine-0.3 to add variant output types, and to allow the
+ `secret' to be specified on the command line.  As well as the `binary'
+ format in the original version, it can now write and read the shares
+ as base64-encoded files, or using the `english-words' encoding used
+ for S/Key passwords.  The first is so that folk can store the shares
+ cross-platform, the other so that they can store the shares on paper
+ (obviously, this is reasonable only for very short secrets such as a
+ password).
+ 
+ I've added the following options:
+ 
+   -t [binary | base64 | words]
+         specify the format of the split files.  The type `binary' is
+         the original. `base64' produces base-64-encoded files, as
+         described in RFC 2045, section 6.8.  `words' produces the
+         `english words' encoding used for S/Key passwords.
+ 
+   -S string
+         Encode the specified string rather than reading a file as
+         described above.  The above warning about command-line
+         arguments applies here, too.
+ 
+   -s   Switch on the steganography option of the original version of
+        tontine, since it's switched off by default.
+ 
+   -V   Show version and exit
+ 
+ Any problems with these options, please get in touch with me.  The
+ version of tontine with these patches is tontine 0.3p3
diff -C 2 -P -r tontine-0.3/RNGenerator.h tontine-0.3p3/RNGenerator.h
*** tontine-0.3/RNGenerator.h	Sun Oct  4 08:10:50 1998
--- tontine-0.3p3/RNGenerator.h	Mon Sep 13 12:42:03 1999
***************
*** 3,6 ****
--- 3,7 ----
  
  #include <string>
+ using namespace std;		// some C++ compilers are fussy
  
  extern "C" {
diff -C 2 -P -r tontine-0.3/SecretShare.cpp tontine-0.3p3/SecretShare.cpp
*** tontine-0.3/SecretShare.cpp	Sun Oct  4 08:10:50 1998
--- tontine-0.3p3/SecretShare.cpp	Mon Sep 13 12:42:03 1999
***************
*** 1,11 ****
  #include <strstream.h>
! #include <fstream.h>
  #include <stdlib.h>
  #include "SecretShare.h"
  
  #include "LagrangePolynomialInterpolation.h"
  
! SecretShare::SecretShare(int keys, int keysNeeded) :
!   keys(keys), keysNeeded(keysNeeded), rand(), prefix("key.")
  {
  }
--- 1,12 ----
  #include <strstream.h>
! //#include <fstream.h>
  #include <stdlib.h>
  #include "SecretShare.h"
+ #include "FIOstream.h"
  
  #include "LagrangePolynomialInterpolation.h"
  
! SecretShare::SecretShare(int keys, int keysNeeded, bool stego) :
!   keys(keys), keysNeeded(keysNeeded), stego(stego), rand(), prefix("key.")
  {
  }
***************
*** 23,37 ****
    rand.open();
  
    for (int i = 0; i < keys; i++) {
!     ofstream file;
!     
!     outfile(file, i);
!     file.close();
    }
  
    char ch;
  
-   createBuffers();
- 
    while (stream) {
      stream.get(ch);
--- 24,38 ----
    rand.open();
  
+   //ofiles = new (FIOstream*)[keys];
+   // Sun CC objects to above -- should it?
+   ofiles = new FIOstreamp[keys];
    for (int i = 0; i < keys; i++) {
!     ostrstream name;
!     name << prefix.c_str() << i << ends;
!     ofiles[i] = new FIOstream (name.str());
    }
  
    char ch;
  
    while (stream) {
      stream.get(ch);
***************
*** 41,54 ****
    }
  
!   flush();
!   deleteBuffers();
  
-   for (int i = 0; i < keys; i++) {
-     ofstream file; 
-     outfile(file, i, true);
-     appendNoise(file);
-     file.close();
-   }
-   
    rand.close();
  }
--- 42,54 ----
    }
  
!   if (stego)
!     for (int i = 0; i < keys; i++) {
!       appendNoise(ofiles[i]);
!     }
! 
!   for (int i=0; i<keys; i++)
!     delete ofiles[i];
!   delete[] ofiles;
  
    rand.close();
  }
***************
*** 96,109 ****
        // byte is never 0.  So, we put the 0 there, and then throw in a second
        // random byte.  Then, in decoding, if we spot a 0, we skip that pair.
!       if ( x == 0 ) {
  	cout << "BOGUS CHAR PUSHED ON KEY " << i << endl;
! 	buffer[i][charsPushed[i]] = 0;
  	assert(rand.read(ch));
! 	buffer[i][charsPushed[i] + 1 ] = ch;
! 	charsPushed[i] += 2;
! 	
! 	if ( charsPushed[i] >= bufferSize )
! 	  flush();
! 
        } else { 
  	y = p[x];
--- 96,104 ----
        // byte is never 0.  So, we put the 0 there, and then throw in a second
        // random byte.  Then, in decoding, if we spot a 0, we skip that pair.
!       if ( x == 0 && stego ) {
  	cout << "BOGUS CHAR PUSHED ON KEY " << i << endl;
! 	ofiles[i]->write(0);
  	assert(rand.read(ch));
! 	ofiles[i]->write(ch);
        } else { 
  	y = p[x];
***************
*** 114,124 ****
      usedKeys[i] = x;
  
!     buffer[i][charsPushed[i]] = x;
!     buffer[i][charsPushed[i] + 1] = y;
! 
!     charsPushed[i] += 2;
! 
!     if (charsPushed[i] >= bufferSize)
!       flush();
    }
  
--- 109,114 ----
      usedKeys[i] = x;
  
!     ofiles[i]->write(x);
!     ofiles[i]->write(y);
    }
  
***************
*** 129,133 ****
  // extraction.
  bool
! SecretShare::decode(ostream& out, ifstream* inputs)
  {
    Point<GF256>* p = new Point<GF256>[keysNeeded];
--- 119,124 ----
  // extraction.
  bool
! //SecretShare::decode(ostream& out, ifstream* inputs)
! SecretShare::decode(ostream& out, FIOstream** inputs)
  {
    Point<GF256>* p = new Point<GF256>[keysNeeded];
***************
*** 140,159 ****
    do {
      for (int i = 0; i < keysNeeded; i++) {
!       inputs[i].get(ch);
        x = GF256((int) ch);
  
        // If we encounter a case where x is 0, this is a bogus pair, simply
        // included to maintain stream entropy.
!       while ( x == 0 ) {
  	// Get the bogus y and a new x.
! 	inputs[i].get(ch);
! 	inputs[i].get(ch);
  	x = GF256((int) ch);
        }
  
!       inputs[i].get(ch);
        y = GF256((int) ch);
!       
!       if (!inputs[i])
  	done = true;
        else {
--- 131,155 ----
    do {
      for (int i = 0; i < keysNeeded; i++) {
!       //inputs[i].get(ch);
!       ch = inputs[i]->read();
        x = GF256((int) ch);
  
        // If we encounter a case where x is 0, this is a bogus pair, simply
        // included to maintain stream entropy.
!       while ( x == 0 && !inputs[0]->eof()) {
  	// Get the bogus y and a new x.
! 	//inputs[i].get(ch);
! 	//inputs[i].get(ch);
! 	ch = inputs[i]->read();
! 	ch = inputs[i]->read();
  	x = GF256((int) ch);
        }
  
!       //inputs[i].get(ch);
!       ch = inputs[i]->read();
        y = GF256((int) ch);
! 
!       //if (!inputs[i])
!       if (inputs[i]->weirdTest())// what does this test do?  EOF?
  	done = true;
        else {
***************
*** 224,227 ****
--- 220,224 ----
  }
  
+ /*
  void
  SecretShare::createBuffers()
***************
*** 264,267 ****
--- 261,265 ----
    delete[] buffer;
  }
+ */
  
  // Add a variable amount of noise from the RNG.  This amount should be
***************
*** 275,284 ****
  // If this is not an issue, simply set the variable amount to 0.  Well, 
  // when that feature's implemented, anyway.
  void
- 
  SecretShare::appendNoise(ofstream& /* out */)
  {    
  }
! 
  void 
  SecretShare::outfile(ofstream& file, int i, bool append)
--- 273,286 ----
  // If this is not an issue, simply set the variable amount to 0.  Well, 
  // when that feature's implemented, anyway.
+ #if 0
  void
  SecretShare::appendNoise(ofstream& /* out */)
  {    
  }
! #endif
! void SecretShare::appendNoise (FIOstream *f)
! {
! }
! /*
  void 
  SecretShare::outfile(ofstream& file, int i, bool append)
***************
*** 307,310 ****
--- 309,313 ----
    name.rdbuf()->freeze(0);
  }
+ */
  
  bool 
diff -C 2 -P -r tontine-0.3/SecretShare.h tontine-0.3p3/SecretShare.h
*** tontine-0.3/SecretShare.h	Sun Oct  4 08:10:50 1998
--- tontine-0.3p3/SecretShare.h	Mon Sep 13 12:42:03 1999
***************
*** 8,11 ****
--- 8,14 ----
  #include <iostream.h>
  #include "Point.h"
+ #include "FIOstream.h"
+ 
+ using namespace std;		// for fussy compilers
  
  // It's desirable for this secret sharing algorithm to have the following
***************
*** 58,62 ****
  class SecretShare {
  public:
!   SecretShare(int keys, int keysNeeded);
    ~SecretShare();
  
--- 61,65 ----
  class SecretShare {
  public:
!   SecretShare(int keys, int keysNeeded, bool stego = false);
    ~SecretShare();
  
***************
*** 65,69 ****
    void createKeys(const Polynomial<GF256>& p);
  
!   bool decode(ostream& out, ifstream* inputs);
    bool decode(ostream& out, const Point<GF256>* inputs);
  
--- 68,73 ----
    void createKeys(const Polynomial<GF256>& p);
  
!   //bool decode(ostream& out, ifstream* inputs);
!   bool decode(ostream& out, FIOstream** inputs);
    bool decode(ostream& out, const Point<GF256>* inputs);
  
***************
*** 77,84 ****
    int keys;
    int keysNeeded;
  
    // This value must be even, because we push characters two at a time, and
    // don't check overflow before this.
!   const int bufferSize = 4096;
  
  
--- 81,89 ----
    int keys;
    int keysNeeded;
+   bool stego;
  
    // This value must be even, because we push characters two at a time, and
    // don't check overflow before this.
!   static const int bufferSize = 4096;
  
  
***************
*** 89,100 ****
    string prefix;
  
    void createBuffers();
    void flush();
    void deleteBuffers();
   
!   void appendNoise(ofstream& out);
  
!   void outfile(ofstream& file, int i, bool append =false);
!   void infile(ifstream& file, int i);
  
    bool keyUsed(int* usedKeys, int index, int x) const;
--- 94,110 ----
    string prefix;
  
+   typedef FIOstream* FIOstreamp;
+   //FIOstream **ofiles;
+   FIOstreamp *ofiles;
+ 
    void createBuffers();
    void flush();
    void deleteBuffers();
   
!   //void appendNoise(ofstream& out);
!   void appendNoise(FIOstream*);
  
!   //void outfile(ofstream& file, int i, bool append =false);
!   //void infile(ifstream& file, int i);
  
    bool keyUsed(int* usedKeys, int index, int x) const;
diff -C 2 -P -r tontine-0.3/btoe.c tontine-0.3p3/btoe.c
*** tontine-0.3/btoe.c	Thu Jan  1 01:00:00 1970
--- tontine-0.3p3/btoe.c	Sun Aug 29 19:23:16 1999
***************
*** 0 ****
--- 1,2279 ----
+ /*
+  * Convert binary to English words.
+  * This is adapted from the file put.c in Wietse Venema's S/Key distribution
+  * (see ftp://ftp.porcupine.org/pub/security/logdaemon-5.6.tar.gz).
+  *
+  * The adaptations consisted merely of changing the header file, ANSIfying 
+  * the result by losing the __ARGS gymnastics, and being specific about
+  * signedness of char by declaring typedef Byte. 
+  */ 
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <assert.h>
+ #include <ctype.h>
+ #include "btoe.h"
+ 
+ static unsigned long extract (char *s,int start,int length);
+ static void standard (char *word);
+ static void insert (char *s, int x, int start, int length);
+ static int wsrch (char *w,int low,int high);
+ 
+ /* Dictionary for integer-word translations */
+ char Wp[2048][4] = {
+ "A",
+ "ABE",
+ "ACE",
+ "ACT",
+ "AD",
+ "ADA",
+ "ADD",
+ "AGO",
+ "AID",
+ "AIM",
+ "AIR",
+ "ALL",
+ "ALP",
+ "AM",
+ "AMY",
+ "AN",
+ "ANA",
+ "AND",
+ "ANN",
+ "ANT",
+ "ANY",
+ "APE",
+ "APS",
+ "APT",
+ "ARC",
+ "ARE",
+ "ARK",
+ "ARM",
+ "ART",
+ "AS",
+ "ASH",
+ "ASK",
+ "AT",
+ "ATE",
+ "AUG",
+ "AUK",
+ "AVE",
+ "AWE",
+ "AWK",
+ "AWL",
+ "AWN",
+ "AX",
+ "AYE",
+ "BAD",
+ "BAG",
+ "BAH",
+ "BAM",
+ "BAN",
+ "BAR",
+ "BAT",
+ "BAY",
+ "BE",
+ "BED",
+ "BEE",
+ "BEG",
+ "BEN",
+ "BET",
+ "BEY",
+ "BIB",
+ "BID",
+ "BIG",
+ "BIN",
+ "BIT",
+ "BOB",
+ "BOG",
+ "BON",
+ "BOO",
+ "BOP",
+ "BOW",
+ "BOY",
+ "BUB",
+ "BUD",
+ "BUG",
+ "BUM",
+ "BUN",
+ "BUS",
+ "BUT",
+ "BUY",
+ "BY",
+ "BYE",
+ "CAB",
+ "CAL",
+ "CAM",
+ "CAN",
+ "CAP",
+ "CAR",
+ "CAT",
+ "CAW",
+ "COD",
+ "COG",
+ "COL",
+ "CON",
+ "COO",
+ "COP",
+ "COT",
+ "COW",
+ "COY",
+ "CRY",
+ "CUB",
+ "CUE",
+ "CUP",
+ "CUR",
+ "CUT",
+ "DAB",
+ "DAD",
+ "DAM",
+ "DAN",
+ "DAR",
+ "DAY",
+ "DEE",
+ "DEL",
+ "DEN",
+ "DES",
+ "DEW",
+ "DID",
+ "DIE",
+ "DIG",
+ "DIN",
+ "DIP",
+ "DO",
+ "DOE",
+ "DOG",
+ "DON",
+ "DOT",
+ "DOW",
+ "DRY",
+ "DUB",
+ "DUD",
+ "DUE",
+ "DUG",
+ "DUN",
+ "EAR",
+ "EAT",
+ "ED",
+ "EEL",
+ "EGG",
+ "EGO",
+ "ELI",
+ "ELK",
+ "ELM",
+ "ELY",
+ "EM",
+ "END",
+ "EST",
+ "ETC",
+ "EVA",
+ "EVE",
+ "EWE",
+ "EYE",
+ "FAD",
+ "FAN",
+ "FAR",
+ "FAT",
+ "FAY",
+ "FED",
+ "FEE",
+ "FEW",
+ "FIB",
+ "FIG",
+ "FIN",
+ "FIR",
+ "FIT",
+ "FLO",
+ "FLY",
+ "FOE",
+ "FOG",
+ "FOR",
+ "FRY",
+ "FUM",
+ "FUN",
+ "FUR",
+ "GAB",
+ "GAD",
+ "GAG",
+ "GAL",
+ "GAM",
+ "GAP",
+ "GAS",
+ "GAY",
+ "GEE",
+ "GEL",
+ "GEM",
+ "GET",
+ "GIG",
+ "GIL",
+ "GIN",
+ "GO",
+ "GOT",
+ "GUM",
+ "GUN",
+ "GUS",
+ "GUT",
+ "GUY",
+ "GYM",
+ "GYP",
+ "HA",
+ "HAD",
+ "HAL",
+ "HAM",
+ "HAN",
+ "HAP",
+ "HAS",
+ "HAT",
+ "HAW",
+ "HAY",
+ "HE",
+ "HEM",
+ "HEN",
+ "HER",
+ "HEW",
+ "HEY",
+ "HI",
+ "HID",
+ "HIM",
+ "HIP",
+ "HIS",
+ "HIT",
+ "HO",
+ "HOB",
+ "HOC",
+ "HOE",
+ "HOG",
+ "HOP",
+ "HOT",
+ "HOW",
+ "HUB",
+ "HUE",
+ "HUG",
+ "HUH",
+ "HUM",
+ "HUT",
+ "I",
+ "ICY",
+ "IDA",
+ "IF",
+ "IKE",
+ "ILL",
+ "INK",
+ "INN",
+ "IO",
+ "ION",
+ "IQ",
+ "IRA",
+ "IRE",
+ "IRK",
+ "IS",
+ "IT",
+ "ITS",
+ "IVY",
+ "JAB",
+ "JAG",
+ "JAM",
+ "JAN",
+ "JAR",
+ "JAW",
+ "JAY",
+ "JET",
+ "JIG",
+ "JIM",
+ "JO",
+ "JOB",
+ "JOE",
+ "JOG",
+ "JOT",
+ "JOY",
+ "JUG",
+ "JUT",
+ "KAY",
+ "KEG",
+ "KEN",
+ "KEY",
+ "KID",
+ "KIM",
+ "KIN",
+ "KIT",
+ "LA",
+ "LAB",
+ "LAC",
+ "LAD",
+ "LAG",
+ "LAM",
+ "LAP",
+ "LAW",
+ "LAY",
+ "LEA",
+ "LED",
+ "LEE",
+ "LEG",
+ "LEN",
+ "LEO",
+ "LET",
+ "LEW",
+ "LID",
+ "LIE",
+ "LIN",
+ "LIP",
+ "LIT",
+ "LO",
+ "LOB",
+ "LOG",
+ "LOP",
+ "LOS",
+ "LOT",
+ "LOU",
+ "LOW",
+ "LOY",
+ "LUG",
+ "LYE",
+ "MA",
+ "MAC",
+ "MAD",
+ "MAE",
+ "MAN",
+ "MAO",
+ "MAP",
+ "MAT",
+ "MAW",
+ "MAY",
+ "ME",
+ "MEG",
+ "MEL",
+ "MEN",
+ "MET",
+ "MEW",
+ "MID",
+ "MIN",
+ "MIT",
+ "MOB",
+ "MOD",
+ "MOE",
+ "MOO",
+ "MOP",
+ "MOS",
+ "MOT",
+ "MOW",
+ "MUD",
+ "MUG",
+ "MUM",
+ "MY",
+ "NAB",
+ "NAG",
+ "NAN",
+ "NAP",
+ "NAT",
+ "NAY",
+ "NE",
+ "NED",
+ "NEE",
+ "NET",
+ "NEW",
+ "NIB",
+ "NIL",
+ "NIP",
+ "NIT",
+ "NO",
+ "NOB",
+ "NOD",
+ "NON",
+ "NOR",
+ "NOT",
+ "NOV",
+ "NOW",
+ "NU",
+ "NUN",
+ "NUT",
+ "O",
+ "OAF",
+ "OAK",
+ "OAR",
+ "OAT",
+ "ODD",
+ "ODE",
+ "OF",
+ "OFF",
+ "OFT",
+ "OH",
+ "OIL",
+ "OK",
+ "OLD",
+ "ON",
+ "ONE",
+ "OR",
+ "ORB",
+ "ORE",
+ "ORR",
+ "OS",
+ "OTT",
+ "OUR",
+ "OUT",
+ "OVA",
+ "OW",
+ "OWE",
+ "OWL",
+ "OWN",
+ "OX",
+ "PA",
+ "PAD",
+ "PAL",
+ "PAM",
+ "PAN",
+ "PAP",
+ "PAR",
+ "PAT",
+ "PAW",
+ "PAY",
+ "PEA",
+ "PEG",
+ "PEN",
+ "PEP",
+ "PER",
+ "PET",
+ "PEW",
+ "PHI",
+ "PI",
+ "PIE",
+ "PIN",
+ "PIT",
+ "PLY",
+ "PO",
+ "POD",
+ "POE",
+ "POP",
+ "POT",
+ "POW",
+ "PRO",
+ "PRY",
+ "PUB",
+ "PUG",
+ "PUN",
+ "PUP",
+ "PUT",
+ "QUO",
+ "RAG",
+ "RAM",
+ "RAN",
+ "RAP",
+ "RAT",
+ "RAW",
+ "RAY",
+ "REB",
+ "RED",
+ "REP",
+ "RET",
+ "RIB",
+ "RID",
+ "RIG",
+ "RIM",
+ "RIO",
+ "RIP",
+ "ROB",
+ "ROD",
+ "ROE",
+ "RON",
+ "ROT",
+ "ROW",
+ "ROY",
+ "RUB",
+ "RUE",
+ "RUG",
+ "RUM",
+ "RUN",
+ "RYE",
+ "SAC",
+ "SAD",
+ "SAG",
+ "SAL",
+ "SAM",
+ "SAN",
+ "SAP",
+ "SAT",
+ "SAW",
+ "SAY",
+ "SEA",
+ "SEC",
+ "SEE",
+ "SEN",
+ "SET",
+ "SEW",
+ "SHE",
+ "SHY",
+ "SIN",
+ "SIP",
+ "SIR",
+ "SIS",
+ "SIT",
+ "SKI",
+ "SKY",
+ "SLY",
+ "SO",
+ "SOB",
+ "SOD",
+ "SON",
+ "SOP",
+ "SOW",
+ "SOY",
+ "SPA",
+ "SPY",
+ "SUB",
+ "SUD",
+ "SUE",
+ "SUM",
+ "SUN",
+ "SUP",
+ "TAB",
+ "TAD",
+ "TAG",
+ "TAN",
+ "TAP",
+ "TAR",
+ "TEA",
+ "TED",
+ "TEE",
+ "TEN",
+ "THE",
+ "THY",
+ "TIC",
+ "TIE",
+ "TIM",
+ "TIN",
+ "TIP",
+ "TO",
+ "TOE",
+ "TOG",
+ "TOM",
+ "TON",
+ "TOO",
+ "TOP",
+ "TOW",
+ "TOY",
+ "TRY",
+ "TUB",
+ "TUG",
+ "TUM",
+ "TUN",
+ "TWO",
+ "UN",
+ "UP",
+ "US",
+ "USE",
+ "VAN",
+ "VAT",
+ "VET",
+ "VIE",
+ "WAD",
+ "WAG",
+ "WAR",
+ "WAS",
+ "WAY",
+ "WE",
+ "WEB",
+ "WED",
+ "WEE",
+ "WET",
+ "WHO",
+ "WHY",
+ "WIN",
+ "WIT",
+ "WOK",
+ "WON",
+ "WOO",
+ "WOW",
+ "WRY",
+ "WU",
+ "YAM",
+ "YAP",
+ "YAW",
+ "YE",
+ "YEA",
+ "YES",
+ "YET",
+ "YOU",
+ "ABED",
+ "ABEL",
+ "ABET",
+ "ABLE",
+ "ABUT",
+ "ACHE",
+ "ACID",
+ "ACME",
+ "ACRE",
+ "ACTA",
+ "ACTS",
+ "ADAM",
+ "ADDS",
+ "ADEN",
+ "AFAR",
+ "AFRO",
+ "AGEE",
+ "AHEM",
+ "AHOY",
+ "AIDA",
+ "AIDE",
+ "AIDS",
+ "AIRY",
+ "AJAR",
+ "AKIN",
+ "ALAN",
+ "ALEC",
+ "ALGA",
+ "ALIA",
+ "ALLY",
+ "ALMA",
+ "ALOE",
+ "ALSO",
+ "ALTO",
+ "ALUM",
+ "ALVA",
+ "AMEN",
+ "AMES",
+ "AMID",
+ "AMMO",
+ "AMOK",
+ "AMOS",
+ "AMRA",
+ "ANDY",
+ "ANEW",
+ "ANNA",
+ "ANNE",
+ "ANTE",
+ "ANTI",
+ "AQUA",
+ "ARAB",
+ "ARCH",
+ "AREA",
+ "ARGO",
+ "ARID",
+ "ARMY",
+ "ARTS",
+ "ARTY",
+ "ASIA",
+ "ASKS",
+ "ATOM",
+ "AUNT",
+ "AURA",
+ "AUTO",
+ "AVER",
+ "AVID",
+ "AVIS",
+ "AVON",
+ "AVOW",
+ "AWAY",
+ "AWRY",
+ "BABE",
+ "BABY",
+ "BACH",
+ "BACK",
+ "BADE",
+ "BAIL",
+ "BAIT",
+ "BAKE",
+ "BALD",
+ "BALE",
+ "BALI",
+ "BALK",
+ "BALL",
+ "BALM",
+ "BAND",
+ "BANE",
+ "BANG",
+ "BANK",
+ "BARB",
+ "BARD",
+ "BARE",
+ "BARK",
+ "BARN",
+ "BARR",
+ "BASE",
+ "BASH",
+ "BASK",
+ "BASS",
+ "BATE",
+ "BATH",
+ "BAWD",
+ "BAWL",
+ "BEAD",
+ "BEAK",
+ "BEAM",
+ "BEAN",
+ "BEAR",
+ "BEAT",
+ "BEAU",
+ "BECK",
+ "BEEF",
+ "BEEN",
+ "BEER",
+ "BEET",
+ "BELA",
+ "BELL",
+ "BELT",
+ "BEND",
+ "BENT",
+ "BERG",
+ "BERN",
+ "BERT",
+ "BESS",
+ "BEST",
+ "BETA",
+ "BETH",
+ "BHOY",
+ "BIAS",
+ "BIDE",
+ "BIEN",
+ "BILE",
+ "BILK",
+ "BILL",
+ "BIND",
+ "BING",
+ "BIRD",
+ "BITE",
+ "BITS",
+ "BLAB",
+ "BLAT",
+ "BLED",
+ "BLEW",
+ "BLOB",
+ "BLOC",
+ "BLOT",
+ "BLOW",
+ "BLUE",
+ "BLUM",
+ "BLUR",
+ "BOAR",
+ "BOAT",
+ "BOCA",
+ "BOCK",
+ "BODE",
+ "BODY",
+ "BOGY",
+ "BOHR",
+ "BOIL",
+ "BOLD",
+ "BOLO",
+ "BOLT",
+ "BOMB",
+ "BONA",
+ "BOND",
+ "BONE",
+ "BONG",
+ "BONN",
+ "BONY",
+ "BOOK",
+ "BOOM",
+ "BOON",
+ "BOOT",
+ "BORE",
+ "BORG",
+ "BORN",
+ "BOSE",
+ "BOSS",
+ "BOTH",
+ "BOUT",
+ "BOWL",
+ "BOYD",
+ "BRAD",
+ "BRAE",
+ "BRAG",
+ "BRAN",
+ "BRAY",
+ "BRED",
+ "BREW",
+ "BRIG",
+ "BRIM",
+ "BROW",
+ "BUCK",
+ "BUDD",
+ "BUFF",
+ "BULB",
+ "BULK",
+ "BULL",
+ "BUNK",
+ "BUNT",
+ "BUOY",
+ "BURG",
+ "BURL",
+ "BURN",
+ "BURR",
+ "BURT",
+ "BURY",
+ "BUSH",
+ "BUSS",
+ "BUST",
+ "BUSY",
+ "BYTE",
+ "CADY",
+ "CAFE",
+ "CAGE",
+ "CAIN",
+ "CAKE",
+ "CALF",
+ "CALL",
+ "CALM",
+ "CAME",
+ "CANE",
+ "CANT",
+ "CARD",
+ "CARE",
+ "CARL",
+ "CARR",
+ "CART",
+ "CASE",
+ "CASH",
+ "CASK",
+ "CAST",
+ "CAVE",
+ "CEIL",
+ "CELL",
+ "CENT",
+ "CERN",
+ "CHAD",
+ "CHAR",
+ "CHAT",
+ "CHAW",
+ "CHEF",
+ "CHEN",
+ "CHEW",
+ "CHIC",
+ "CHIN",
+ "CHOU",
+ "CHOW",
+ "CHUB",
+ "CHUG",
+ "CHUM",
+ "CITE",
+ "CITY",
+ "CLAD",
+ "CLAM",
+ "CLAN",
+ "CLAW",
+ "CLAY",
+ "CLOD",
+ "CLOG",
+ "CLOT",
+ "CLUB",
+ "CLUE",
+ "COAL",
+ "COAT",
+ "COCA",
+ "COCK",
+ "COCO",
+ "CODA",
+ "CODE",
+ "CODY",
+ "COED",
+ "COIL",
+ "COIN",
+ "COKE",
+ "COLA",
+ "COLD",
+ "COLT",
+ "COMA",
+ "COMB",
+ "COME",
+ "COOK",
+ "COOL",
+ "COON",
+ "COOT",
+ "CORD",
+ "CORE",
+ "CORK",
+ "CORN",
+ "COST",
+ "COVE",
+ "COWL",
+ "CRAB",
+ "CRAG",
+ "CRAM",
+ "CRAY",
+ "CREW",
+ "CRIB",
+ "CROW",
+ "CRUD",
+ "CUBA",
+ "CUBE",
+ "CUFF",
+ "CULL",
+ "CULT",
+ "CUNY",
+ "CURB",
+ "CURD",
+ "CURE",
+ "CURL",
+ "CURT",
+ "CUTS",
+ "DADE",
+ "DALE",
+ "DAME",
+ "DANA",
+ "DANE",
+ "DANG",
+ "DANK",
+ "DARE",
+ "DARK",
+ "DARN",
+ "DART",
+ "DASH",
+ "DATA",
+ "DATE",
+ "DAVE",
+ "DAVY",
+ "DAWN",
+ "DAYS",
+ "DEAD",
+ "DEAF",
+ "DEAL",
+ "DEAN",
+ "DEAR",
+ "DEBT",
+ "DECK",
+ "DEED",
+ "DEEM",
+ "DEER",
+ "DEFT",
+ "DEFY",
+ "DELL",
+ "DENT",
+ "DENY",
+ "DESK",
+ "DIAL",
+ "DICE",
+ "DIED",
+ "DIET",
+ "DIME",
+ "DINE",
+ "DING",
+ "DINT",
+ "DIRE",
+ "DIRT",
+ "DISC",
+ "DISH",
+ "DISK",
+ "DIVE",
+ "DOCK",
+ "DOES",
+ "DOLE",
+ "DOLL",
+ "DOLT",
+ "DOME",
+ "DONE",
+ "DOOM",
+ "DOOR",
+ "DORA",
+ "DOSE",
+ "DOTE",
+ "DOUG",
+ "DOUR",
+ "DOVE",
+ "DOWN",
+ "DRAB",
+ "DRAG",
+ "DRAM",
+ "DRAW",
+ "DREW",
+ "DRUB",
+ "DRUG",
+ "DRUM",
+ "DUAL",
+ "DUCK",
+ "DUCT",
+ "DUEL",
+ "DUET",
+ "DUKE",
+ "DULL",
+ "DUMB",
+ "DUNE",
+ "DUNK",
+ "DUSK",
+ "DUST",
+ "DUTY",
+ "EACH",
+ "EARL",
+ "EARN",
+ "EASE",
+ "EAST",
+ "EASY",
+ "EBEN",
+ "ECHO",
+ "EDDY",
+ "EDEN",
+ "EDGE",
+ "EDGY",
+ "EDIT",
+ "EDNA",
+ "EGAN",
+ "ELAN",
+ "ELBA",
+ "ELLA",
+ "ELSE",
+ "EMIL",
+ "EMIT",
+ "EMMA",
+ "ENDS",
+ "ERIC",
+ "EROS",
+ "EVEN",
+ "EVER",
+ "EVIL",
+ "EYED",
+ "FACE",
+ "FACT",
+ "FADE",
+ "FAIL",
+ "FAIN",
+ "FAIR",
+ "FAKE",
+ "FALL",
+ "FAME",
+ "FANG",
+ "FARM",
+ "FAST",
+ "FATE",
+ "FAWN",
+ "FEAR",
+ "FEAT",
+ "FEED",
+ "FEEL",
+ "FEET",
+ "FELL",
+ "FELT",
+ "FEND",
+ "FERN",
+ "FEST",
+ "FEUD",
+ "FIEF",
+ "FIGS",
+ "FILE",
+ "FILL",
+ "FILM",
+ "FIND",
+ "FINE",
+ "FINK",
+ "FIRE",
+ "FIRM",
+ "FISH",
+ "FISK",
+ "FIST",
+ "FITS",
+ "FIVE",
+ "FLAG",
+ "FLAK",
+ "FLAM",
+ "FLAT",
+ "FLAW",
+ "FLEA",
+ "FLED",
+ "FLEW",
+ "FLIT",
+ "FLOC",
+ "FLOG",
+ "FLOW",
+ "FLUB",
+ "FLUE",
+ "FOAL",
+ "FOAM",
+ "FOGY",
+ "FOIL",
+ "FOLD",
+ "FOLK",
+ "FOND",
+ "FONT",
+ "FOOD",
+ "FOOL",
+ "FOOT",
+ "FORD",
+ "FORE",
+ "FORK",
+ "FORM",
+ "FORT",
+ "FOSS",
+ "FOUL",
+ "FOUR",
+ "FOWL",
+ "FRAU",
+ "FRAY",
+ "FRED",
+ "FREE",
+ "FRET",
+ "FREY",
+ "FROG",
+ "FROM",
+ "FUEL",
+ "FULL",
+ "FUME",
+ "FUND",
+ "FUNK",
+ "FURY",
+ "FUSE",
+ "FUSS",
+ "GAFF",
+ "GAGE",
+ "GAIL",
+ "GAIN",
+ "GAIT",
+ "GALA",
+ "GALE",
+ "GALL",
+ "GALT",
+ "GAME",
+ "GANG",
+ "GARB",
+ "GARY",
+ "GASH",
+ "GATE",
+ "GAUL",
+ "GAUR",
+ "GAVE",
+ "GAWK",
+ "GEAR",
+ "GELD",
+ "GENE",
+ "GENT",
+ "GERM",
+ "GETS",
+ "GIBE",
+ "GIFT",
+ "GILD",
+ "GILL",
+ "GILT",
+ "GINA",
+ "GIRD",
+ "GIRL",
+ "GIST",
+ "GIVE",
+ "GLAD",
+ "GLEE",
+ "GLEN",
+ "GLIB",
+ "GLOB",
+ "GLOM",
+ "GLOW",
+ "GLUE",
+ "GLUM",
+ "GLUT",
+ "GOAD",
+ "GOAL",
+ "GOAT",
+ "GOER",
+ "GOES",
+ "GOLD",
+ "GOLF",
+ "GONE",
+ "GONG",
+ "GOOD",
+ "GOOF",
+ "GORE",
+ "GORY",
+ "GOSH",
+ "GOUT",
+ "GOWN",
+ "GRAB",
+ "GRAD",
+ "GRAY",
+ "GREG",
+ "GREW",
+ "GREY",
+ "GRID",
+ "GRIM",
+ "GRIN",
+ "GRIT",
+ "GROW",
+ "GRUB",
+ "GULF",
+ "GULL",
+ "GUNK",
+ "GURU",
+ "GUSH",
+ "GUST",
+ "GWEN",
+ "GWYN",
+ "HAAG",
+ "HAAS",
+ "HACK",
+ "HAIL",
+ "HAIR",
+ "HALE",
+ "HALF",
+ "HALL",
+ "HALO",
+ "HALT",
+ "HAND",
+ "HANG",
+ "HANK",
+ "HANS",
+ "HARD",
+ "HARK",
+ "HARM",
+ "HART",
+ "HASH",
+ "HAST",
+ "HATE",
+ "HATH",
+ "HAUL",
+ "HAVE",
+ "HAWK",
+ "HAYS",
+ "HEAD",
+ "HEAL",
+ "HEAR",
+ "HEAT",
+ "HEBE",
+ "HECK",
+ "HEED",
+ "HEEL",
+ "HEFT",
+ "HELD",
+ "HELL",
+ "HELM",
+ "HERB",
+ "HERD",
+ "HERE",
+ "HERO",
+ "HERS",
+ "HESS",
+ "HEWN",
+ "HICK",
+ "HIDE",
+ "HIGH",
+ "HIKE",
+ "HILL",
+ "HILT",
+ "HIND",
+ "HINT",
+ "HIRE",
+ "HISS",
+ "HIVE",
+ "HOBO",
+ "HOCK",
+ "HOFF",
+ "HOLD",
+ "HOLE",
+ "HOLM",
+ "HOLT",
+ "HOME",
+ "HONE",
+ "HONK",
+ "HOOD",
+ "HOOF",
+ "HOOK",
+ "HOOT",
+ "HORN",
+ "HOSE",
+ "HOST",
+ "HOUR",
+ "HOVE",
+ "HOWE",
+ "HOWL",
+ "HOYT",
+ "HUCK",
+ "HUED",
+ "HUFF",
+ "HUGE",
+ "HUGH",
+ "HUGO",
+ "HULK",
+ "HULL",
+ "HUNK",
+ "HUNT",
+ "HURD",
+ "HURL",
+ "HURT",
+ "HUSH",
+ "HYDE",
+ "HYMN",
+ "IBIS",
+ "ICON",
+ "IDEA",
+ "IDLE",
+ "IFFY",
+ "INCA",
+ "INCH",
+ "INTO",
+ "IONS",
+ "IOTA",
+ "IOWA",
+ "IRIS",
+ "IRMA",
+ "IRON",
+ "ISLE",
+ "ITCH",
+ "ITEM",
+ "IVAN",
+ "JACK",
+ "JADE",
+ "JAIL",
+ "JAKE",
+ "JANE",
+ "JAVA",
+ "JEAN",
+ "JEFF",
+ "JERK",
+ "JESS",
+ "JEST",
+ "JIBE",
+ "JILL",
+ "JILT",
+ "JIVE",
+ "JOAN",
+ "JOBS",
+ "JOCK",
+ "JOEL",
+ "JOEY",
+ "JOHN",
+ "JOIN",
+ "JOKE",
+ "JOLT",
+ "JOVE",
+ "JUDD",
+ "JUDE",
+ "JUDO",
+ "JUDY",
+ "JUJU",
+ "JUKE",
+ "JULY",
+ "JUNE",
+ "JUNK",
+ "JUNO",
+ "JURY",
+ "JUST",
+ "JUTE",
+ "KAHN",
+ "KALE",
+ "KANE",
+ "KANT",
+ "KARL",
+ "KATE",
+ "KEEL",
+ "KEEN",
+ "KENO",
+ "KENT",
+ "KERN",
+ "KERR",
+ "KEYS",
+ "KICK",
+ "KILL",
+ "KIND",
+ "KING",
+ "KIRK",
+ "KISS",
+ "KITE",
+ "KLAN",
+ "KNEE",
+ "KNEW",
+ "KNIT",
+ "KNOB",
+ "KNOT",
+ "KNOW",
+ "KOCH",
+ "KONG",
+ "KUDO",
+ "KURD",
+ "KURT",
+ "KYLE",
+ "LACE",
+ "LACK",
+ "LACY",
+ "LADY",
+ "LAID",
+ "LAIN",
+ "LAIR",
+ "LAKE",
+ "LAMB",
+ "LAME",
+ "LAND",
+ "LANE",
+ "LANG",
+ "LARD",
+ "LARK",
+ "LASS",
+ "LAST",
+ "LATE",
+ "LAUD",
+ "LAVA",
+ "LAWN",
+ "LAWS",
+ "LAYS",
+ "LEAD",
+ "LEAF",
+ "LEAK",
+ "LEAN",
+ "LEAR",
+ "LEEK",
+ "LEER",
+ "LEFT",
+ "LEND",
+ "LENS",
+ "LENT",
+ "LEON",
+ "LESK",
+ "LESS",
+ "LEST",
+ "LETS",
+ "LIAR",
+ "LICE",
+ "LICK",
+ "LIED",
+ "LIEN",
+ "LIES",
+ "LIEU",
+ "LIFE",
+ "LIFT",
+ "LIKE",
+ "LILA",
+ "LILT",
+ "LILY",
+ "LIMA",
+ "LIMB",
+ "LIME",
+ "LIND",
+ "LINE",
+ "LINK",
+ "LINT",
+ "LION",
+ "LISA",
+ "LIST",
+ "LIVE",
+ "LOAD",
+ "LOAF",
+ "LOAM",
+ "LOAN",
+ "LOCK",
+ "LOFT",
+ "LOGE",
+ "LOIS",
+ "LOLA",
+ "LONE",
+ "LONG",
+ "LOOK",
+ "LOON",
+ "LOOT",
+ "LORD",
+ "LORE",
+ "LOSE",
+ "LOSS",
+ "LOST",
+ "LOUD",
+ "LOVE",
+ "LOWE",
+ "LUCK",
+ "LUCY",
+ "LUGE",
+ "LUKE",
+ "LULU",
+ "LUND",
+ "LUNG",
+ "LURA",
+ "LURE",
+ "LURK",
+ "LUSH",
+ "LUST",
+ "LYLE",
+ "LYNN",
+ "LYON",
+ "LYRA",
+ "MACE",
+ "MADE",
+ "MAGI",
+ "MAID",
+ "MAIL",
+ "MAIN",
+ "MAKE",
+ "MALE",
+ "MALI",
+ "MALL",
+ "MALT",
+ "MANA",
+ "MANN",
+ "MANY",
+ "MARC",
+ "MARE",
+ "MARK",
+ "MARS",
+ "MART",
+ "MARY",
+ "MASH",
+ "MASK",
+ "MASS",
+ "MAST",
+ "MATE",
+ "MATH",
+ "MAUL",
+ "MAYO",
+ "MEAD",
+ "MEAL",
+ "MEAN",
+ "MEAT",
+ "MEEK",
+ "MEET",
+ "MELD",
+ "MELT",
+ "MEMO",
+ "MEND",
+ "MENU",
+ "MERT",
+ "MESH",
+ "MESS",
+ "MICE",
+ "MIKE",
+ "MILD",
+ "MILE",
+ "MILK",
+ "MILL",
+ "MILT",
+ "MIMI",
+ "MIND",
+ "MINE",
+ "MINI",
+ "MINK",
+ "MINT",
+ "MIRE",
+ "MISS",
+ "MIST",
+ "MITE",
+ "MITT",
+ "MOAN",
+ "MOAT",
+ "MOCK",
+ "MODE",
+ "MOLD",
+ "MOLE",
+ "MOLL",
+ "MOLT",
+ "MONA",
+ "MONK",
+ "MONT",
+ "MOOD",
+ "MOON",
+ "MOOR",
+ "MOOT",
+ "MORE",
+ "MORN",
+ "MORT",
+ "MOSS",
+ "MOST",
+ "MOTH",
+ "MOVE",
+ "MUCH",
+ "MUCK",
+ "MUDD",
+ "MUFF",
+ "MULE",
+ "MULL",
+ "MURK",
+ "MUSH",
+ "MUST",
+ "MUTE",
+ "MUTT",
+ "MYRA",
+ "MYTH",
+ "NAGY",
+ "NAIL",
+ "NAIR",
+ "NAME",
+ "NARY",
+ "NASH",
+ "NAVE",
+ "NAVY",
+ "NEAL",
+ "NEAR",
+ "NEAT",
+ "NECK",
+ "NEED",
+ "NEIL",
+ "NELL",
+ "NEON",
+ "NERO",
+ "NESS",
+ "NEST",
+ "NEWS",
+ "NEWT",
+ "NIBS",
+ "NICE",
+ "NICK",
+ "NILE",
+ "NINA",
+ "NINE",
+ "NOAH",
+ "NODE",
+ "NOEL",
+ "NOLL",
+ "NONE",
+ "NOOK",
+ "NOON",
+ "NORM",
+ "NOSE",
+ "NOTE",
+ "NOUN",
+ "NOVA",
+ "NUDE",
+ "NULL",
+ "NUMB",
+ "OATH",
+ "OBEY",
+ "OBOE",
+ "ODIN",
+ "OHIO",
+ "OILY",
+ "OINT",
+ "OKAY",
+ "OLAF",
+ "OLDY",
+ "OLGA",
+ "OLIN",
+ "OMAN",
+ "OMEN",
+ "OMIT",
+ "ONCE",
+ "ONES",
+ "ONLY",
+ "ONTO",
+ "ONUS",
+ "ORAL",
+ "ORGY",
+ "OSLO",
+ "OTIS",
+ "OTTO",
+ "OUCH",
+ "OUST",
+ "OUTS",
+ "OVAL",
+ "OVEN",
+ "OVER",
+ "OWLY",
+ "OWNS",
+ "QUAD",
+ "QUIT",
+ "QUOD",
+ "RACE",
+ "RACK",
+ "RACY",
+ "RAFT",
+ "RAGE",
+ "RAID",
+ "RAIL",
+ "RAIN",
+ "RAKE",
+ "RANK",
+ "RANT",
+ "RARE",
+ "RASH",
+ "RATE",
+ "RAVE",
+ "RAYS",
+ "READ",
+ "REAL",
+ "REAM",
+ "REAR",
+ "RECK",
+ "REED",
+ "REEF",
+ "REEK",
+ "REEL",
+ "REID",
+ "REIN",
+ "RENA",
+ "REND",
+ "RENT",
+ "REST",
+ "RICE",
+ "RICH",
+ "RICK",
+ "RIDE",
+ "RIFT",
+ "RILL",
+ "RIME",
+ "RING",
+ "RINK",
+ "RISE",
+ "RISK",
+ "RITE",
+ "ROAD",
+ "ROAM",
+ "ROAR",
+ "ROBE",
+ "ROCK",
+ "RODE",
+ "ROIL",
+ "ROLL",
+ "ROME",
+ "ROOD",
+ "ROOF",
+ "ROOK",
+ "ROOM",
+ "ROOT",
+ "ROSA",
+ "ROSE",
+ "ROSS",
+ "ROSY",
+ "ROTH",
+ "ROUT",
+ "ROVE",
+ "ROWE",
+ "ROWS",
+ "RUBE",
+ "RUBY",
+ "RUDE",
+ "RUDY",
+ "RUIN",
+ "RULE",
+ "RUNG",
+ "RUNS",
+ "RUNT",
+ "RUSE",
+ "RUSH",
+ "RUSK",
+ "RUSS",
+ "RUST",
+ "RUTH",
+ "SACK",
+ "SAFE",
+ "SAGE",
+ "SAID",
+ "SAIL",
+ "SALE",
+ "SALK",
+ "SALT",
+ "SAME",
+ "SAND",
+ "SANE",
+ "SANG",
+ "SANK",
+ "SARA",
+ "SAUL",
+ "SAVE",
+ "SAYS",
+ "SCAN",
+ "SCAR",
+ "SCAT",
+ "SCOT",
+ "SEAL",
+ "SEAM",
+ "SEAR",
+ "SEAT",
+ "SEED",
+ "SEEK",
+ "SEEM",
+ "SEEN",
+ "SEES",
+ "SELF",
+ "SELL",
+ "SEND",
+ "SENT",
+ "SETS",
+ "SEWN",
+ "SHAG",
+ "SHAM",
+ "SHAW",
+ "SHAY",
+ "SHED",
+ "SHIM",
+ "SHIN",
+ "SHOD",
+ "SHOE",
+ "SHOT",
+ "SHOW",
+ "SHUN",
+ "SHUT",
+ "SICK",
+ "SIDE",
+ "SIFT",
+ "SIGH",
+ "SIGN",
+ "SILK",
+ "SILL",
+ "SILO",
+ "SILT",
+ "SINE",
+ "SING",
+ "SINK",
+ "SIRE",
+ "SITE",
+ "SITS",
+ "SITU",
+ "SKAT",
+ "SKEW",
+ "SKID",
+ "SKIM",
+ "SKIN",
+ "SKIT",
+ "SLAB",
+ "SLAM",
+ "SLAT",
+ "SLAY",
+ "SLED",
+ "SLEW",
+ "SLID",
+ "SLIM",
+ "SLIT",
+ "SLOB",
+ "SLOG",
+ "SLOT",
+ "SLOW",
+ "SLUG",
+ "SLUM",
+ "SLUR",
+ "SMOG",
+ "SMUG",
+ "SNAG",
+ "SNOB",
+ "SNOW",
+ "SNUB",
+ "SNUG",
+ "SOAK",
+ "SOAR",
+ "SOCK",
+ "SODA",
+ "SOFA",
+ "SOFT",
+ "SOIL",
+ "SOLD",
+ "SOME",
+ "SONG",
+ "SOON",
+ "SOOT",
+ "SORE",
+ "SORT",
+ "SOUL",
+ "SOUR",
+ "SOWN",
+ "STAB",
+ "STAG",
+ "STAN",
+ "STAR",
+ "STAY",
+ "STEM",
+ "STEW",
+ "STIR",
+ "STOW",
+ "STUB",
+ "STUN",
+ "SUCH",
+ "SUDS",
+ "SUIT",
+ "SULK",
+ "SUMS",
+ "SUNG",
+ "SUNK",
+ "SURE",
+ "SURF",
+ "SWAB",
+ "SWAG",
+ "SWAM",
+ "SWAN",
+ "SWAT",
+ "SWAY",
+ "SWIM",
+ "SWUM",
+ "TACK",
+ "TACT",
+ "TAIL",
+ "TAKE",
+ "TALE",
+ "TALK",
+ "TALL",
+ "TANK",
+ "TASK",
+ "TATE",
+ "TAUT",
+ "TEAL",
+ "TEAM",
+ "TEAR",
+ "TECH",
+ "TEEM",
+ "TEEN",
+ "TEET",
+ "TELL",
+ "TEND",
+ "TENT",
+ "TERM",
+ "TERN",
+ "TESS",
+ "TEST",
+ "THAN",
+ "THAT",
+ "THEE",
+ "THEM",
+ "THEN",
+ "THEY",
+ "THIN",
+ "THIS",
+ "THUD",
+ "THUG",
+ "TICK",
+ "TIDE",
+ "TIDY",
+ "TIED",
+ "TIER",
+ "TILE",
+ "TILL",
+ "TILT",
+ "TIME",
+ "TINA",
+ "TINE",
+ "TINT",
+ "TINY",
+ "TIRE",
+ "TOAD",
+ "TOGO",
+ "TOIL",
+ "TOLD",
+ "TOLL",
+ "TONE",
+ "TONG",
+ "TONY",
+ "TOOK",
+ "TOOL",
+ "TOOT",
+ "TORE",
+ "TORN",
+ "TOTE",
+ "TOUR",
+ "TOUT",
+ "TOWN",
+ "TRAG",
+ "TRAM",
+ "TRAY",
+ "TREE",
+ "TREK",
+ "TRIG",
+ "TRIM",
+ "TRIO",
+ "TROD",
+ "TROT",
+ "TROY",
+ "TRUE",
+ "TUBA",
+ "TUBE",
+ "TUCK",
+ "TUFT",
+ "TUNA",
+ "TUNE",
+ "TUNG",
+ "TURF",
+ "TURN",
+ "TUSK",
+ "TWIG",
+ "TWIN",
+ "TWIT",
+ "ULAN",
+ "UNIT",
+ "URGE",
+ "USED",
+ "USER",
+ "USES",
+ "UTAH",
+ "VAIL",
+ "VAIN",
+ "VALE",
+ "VARY",
+ "VASE",
+ "VAST",
+ "VEAL",
+ "VEDA",
+ "VEIL",
+ "VEIN",
+ "VEND",
+ "VENT",
+ "VERB",
+ "VERY",
+ "VETO",
+ "VICE",
+ "VIEW",
+ "VINE",
+ "VISE",
+ "VOID",
+ "VOLT",
+ "VOTE",
+ "WACK",
+ "WADE",
+ "WAGE",
+ "WAIL",
+ "WAIT",
+ "WAKE",
+ "WALE",
+ "WALK",
+ "WALL",
+ "WALT",
+ "WAND",
+ "WANE",
+ "WANG",
+ "WANT",
+ "WARD",
+ "WARM",
+ "WARN",
+ "WART",
+ "WASH",
+ "WAST",
+ "WATS",
+ "WATT",
+ "WAVE",
+ "WAVY",
+ "WAYS",
+ "WEAK",
+ "WEAL",
+ "WEAN",
+ "WEAR",
+ "WEED",
+ "WEEK",
+ "WEIR",
+ "WELD",
+ "WELL",
+ "WELT",
+ "WENT",
+ "WERE",
+ "WERT",
+ "WEST",
+ "WHAM",
+ "WHAT",
+ "WHEE",
+ "WHEN",
+ "WHET",
+ "WHOA",
+ "WHOM",
+ "WICK",
+ "WIFE",
+ "WILD",
+ "WILL",
+ "WIND",
+ "WINE",
+ "WING",
+ "WINK",
+ "WINO",
+ "WIRE",
+ "WISE",
+ "WISH",
+ "WITH",
+ "WOLF",
+ "WONT",
+ "WOOD",
+ "WOOL",
+ "WORD",
+ "WORE",
+ "WORK",
+ "WORM",
+ "WORN",
+ "WOVE",
+ "WRIT",
+ "WYNN",
+ "YALE",
+ "YANG",
+ "YANK",
+ "YARD",
+ "YARN",
+ "YAWL",
+ "YAWN",
+ "YEAH",
+ "YEAR",
+ "YELL",
+ "YOGA",
+ "YOKE"
+ };
+ 
+ /* Encode 8 bytes in 'c' as a string of English words.
+  * Returns a pointer to a static buffer [CHANGED: returns nothing]
+  */
+ void btoe(char *engout, Byte *c)
+ {
+ 	char cp[10];	/* add in room for the parity 2 bits + extract() slop */
+ 	int p,i ;
+ 
+ 	engout[0] = '\0';
+ 	/* workaround for extract() reads beyond end of data */
+ 	memset(cp, 0, sizeof(cp));
+ 	memcpy(cp, c,8);
+ 	/* compute parity */
+ 	for(p = 0,i = 0; i < 64;i += 2)
+ 		p += extract(cp,i,2);
+ 
+ 	cp[8] = (char)p << 6;
+ 	strncat(engout,&Wp[extract(cp, 0,11)][0],4);
+ 	strcat(engout," ");
+ 	strncat(engout,&Wp[extract(cp,11,11)][0],4);
+ 	strcat(engout," ");
+ 	strncat(engout,&Wp[extract(cp,22,11)][0],4);
+ 	strcat(engout," ");
+ 	strncat(engout,&Wp[extract(cp,33,11)][0],4);
+ 	strcat(engout," ");
+ 	strncat(engout,&Wp[extract(cp,44,11)][0],4);
+ 	strcat(engout," ");
+ 	strncat(engout,&Wp[extract(cp,55,11)][0],4);
+ #ifdef	notdef
+ 	printf("engout is %s\n\r",engout);
+ #endif
+ 	return;
+ }
+ 
+ /* convert English to binary   
+  * returns 1 OK - all good words and parity is OK   
+  *         0 word not in data base
+  *        -1 badly formed in put ie > 4 char word
+  *        -2 words OK but parity is wrong
+  */
+ int etob(Byte *out, char *e)
+ {
+ 	char *word;
+ 	int i, p, v,l, low,high;
+ 	char b[9];
+ 	char input[36];
+ 
+ 	if(e == NULL)
+ 		return -1;
+ 
+ 	strncpy(input,e,sizeof(input));
+ 	memset(b, 0, sizeof(b));
+ 	memset(out, 0, 8);
+ 	for(i=0,p=0;i<6;i++,p+=11){
+ 		if((word = strtok(i == 0 ? input : NULL," ,")) == NULL)
+ 			return -1;
+ 		l = strlen(word);
+ 		if(l > 4 || l < 1){
+ 			return -1;
+ 		} else if(l < 4){
+ 			low = 0;
+ 			high = 570;
+ 		} else {
+ 			low = 571;
+ 			high = 2047;
+ 		}
+ 		standard(word);
+ 		if( (v = wsrch(word,low,high)) < 0 )
+ 			return 0;
+ 		insert(b,v,p,11);
+ 	}
+ 
+ 	/* now check the parity of what we got */
+ 	for(p = 0, i = 0; i < 64; i +=2)
+ 		p += extract(b, i, 2);
+ 
+ 	if( (p & 3) != extract(b, 64,2) )
+ 		return -2;
+ 
+ 	memcpy(out,b,8);
+ 
+ 	return 1;
+ }
+ /* Display 8 bytes as a series of 16-bit hex digits */
+ char *put8(char *out, char *s)
+ {
+ 	sprintf(out,"%02X%02X %02X%02X %02X%02X %02X%02X",
+ 		s[0] & 0xff,s[1] & 0xff,s[2] & 0xff,
+ 		s[3] & 0xff,s[4] & 0xff,s[5] & 0xff,
+ 		s[6] & 0xff,s[7] & 0xff);
+ 	return out;
+ }
+ #ifdef	notdef
+ /* Encode 8 bytes in 'cp' as stream of ascii letters.
+  * Provided as a possible alternative to btoe()
+  */
+ char *btoc(char *cp)
+ {
+ 	int i;
+ 	static char out[31];
+ 
+ 	/* code out put by characters 6 bits each added to 0x21 (!)*/
+ 	for(i=0;i <= 10;i++){
+ 		/* last one is only 4 bits not 6*/
+ 		out[i] = '!'+ extract(cp,6*i,i >= 10 ? 4:6);
+ 	}
+ 	out[i] = '\0';
+ 	return(out);
+ }
+ #endif
+ 
+ /* Internal subroutines for word encoding/decoding */
+ 
+ /* Dictionary binary search */
+ static int wsrch(char *w, int low, int high)
+ {
+ 	int i,j;
+ 
+ 	for(;;){
+ 		i = (low + high)/2;
+ 		if((j = strncmp(w,Wp[i],4)) == 0)
+ 			return i;	/* Found it */
+ 		if(high == low+1){
+ 			/* Avoid effects of integer truncation in /2 */
+ 			if(strncmp(w,Wp[high],4) == 0)
+ 				return high;
+ 			else
+ 				return -1;
+ 		}
+ 		if(low >= high)
+ 			return -1;	/* I don't *think* this can happen...*/
+ 		if(j < 0)
+ 			high = i;	/* Search lower half */
+ 		else
+ 			low = i;	/* Search upper half */
+ 	}
+ }
+ static void insert(char *s, int x, int start, int length)
+ {
+ 	unsigned char cl;
+ 	unsigned char cc;
+ 	unsigned char cr;
+ 	unsigned long y;
+ 	int shift;
+ 
+ 	assert(length <= 11);
+ 	assert(start >= 0);
+ 	assert(length >= 0);
+ 	assert(start +length <= 66);
+ 
+ 	shift = ((8  -(( start + length) % 8))%8);
+ 	y = (long) x << shift;
+ 	cl = (y >> 16) & 0xff;
+ 	cc = (y >> 8) & 0xff;
+ 	cr = y & 0xff;
+ 	if(shift + length > 16){
+ 		s[start /8] |= cl;
+ 		s[start/8 +1] |= cc;
+ 		s[start/8 +2] |= cr;
+ 	} else if(shift +length > 8){
+ 		s[start/8] |= cc;
+ 		s[start/8 + 1] |= cr;
+ 	} else {
+ 		s[start/8] |= cr;
+ 	}
+ }
+ 
+ static void standard(char *word)
+ {
+ 	while(*word){
+ 		if(!isascii(*word))
+ 			break;
+ 		if(islower(*word))
+ 			*word = toupper(*word);
+ 		if(*word == '1')
+ 			*word = 'L';
+ 		if(*word == '0')
+ 			*word = 'O';
+ 		if(*word == '5')
+ 			*word = 'S';
+ 		word++;
+ 	}
+ }
+ 
+ /* Extract 'length' bits from the char array 's' starting with bit 'start' */
+ static unsigned long extract(char *s, int start, int length)
+ {
+ 	unsigned char cl;
+ 	unsigned char cc;
+ 	unsigned char cr;
+ 	unsigned long x;
+ 
+ 	assert(length <= 11);
+ 	assert(start >= 0);
+ 	assert(length >= 0);
+ 	assert(start +length <= 66);
+ 
+ 	cl = s[start/8];
+ 	cc = s[start/8 +1];
+ 	cr = s[start/8 +2];
+ 	x = ((long)(cl<<8 | cc) <<8  | cr) ;
+ 	x = x >> (24 - (length + (start %8)));
+ 	x =( x & (0xffff >> (16-length) )   );
+ 	return(x);
+ }
+ 
diff -C 2 -P -r tontine-0.3/btoe.h tontine-0.3p3/btoe.h
*** tontine-0.3/btoe.h	Thu Jan  1 01:00:00 1970
--- tontine-0.3p3/btoe.h	Sun Aug 29 13:57:09 1999
***************
*** 0 ****
--- 1,16 ----
+ #ifndef _btoe_h
+ #define _btoe_h
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+     typedef unsigned char Byte;
+ 
+     void btoe(char *engout, Byte *c);
+     int etob(Byte *out, char *e);
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif
diff -C 2 -P -r tontine-0.3/main.cpp tontine-0.3p3/main.cpp
*** tontine-0.3/main.cpp	Sun Oct  4 08:31:01 1998
--- tontine-0.3p3/main.cpp	Fri Sep 17 15:05:13 1999
***************
*** 10,17 ****
  #include "RNGenerator.h"
  #include "SecretShare.h"
  
  static void decode(int argc, char** argv, const string& output, int k);
! static void encode(int argc, char** argv, const string& prefix, int N, 
! 		   int k, bool isExecutable, const string& randomSource);
  static void setInt(const char* str, int& val);
  static void usage();
--- 10,21 ----
  #include "RNGenerator.h"
  #include "SecretShare.h"
+ #include "FIOstream.h"
+ #include "version.h"
  
  static void decode(int argc, char** argv, const string& output, int k);
! static void encode(char* name, bool isFilename,
! 		   const string& prefix, int N, 
! 		   int k, bool isExecutable, const string& randomSource,
! 		   bool useStego);
  static void setInt(const char* str, int& val);
  static void usage();
***************
*** 19,32 ****
  main(int argc, char** argv)
  {
!   string output("decoded");
    string prefix("key.");
    string randomSource("/dev/random");
    char ch;
    bool doDecode = false;
    bool isExecutable = false;
    int k = -1;
    int N = -1;
  
!   while ((ch = getopt(argc, argv, "b:N:k:o:p:r:R:d")) != EOF) {
      switch (ch) {
  
--- 23,44 ----
  main(int argc, char** argv)
  {
!   //string output("decoded");
!   string output("");
    string prefix("key.");
    string randomSource("/dev/random");
+   int ich;
    char ch;
    bool doDecode = false;
    bool isExecutable = false;
+   bool isFilename = true;
+   bool useStego = false;
    int k = -1;
    int N = -1;
  
!   FIOstream::setFormat (FIOstream::Binary);	// default
! 
!   while ((ich = getopt(argc, argv, "b:N:k:o:p:r:R:t:dsSV")) != EOF) {
!     ch = static_cast<char>(ich);
!     // ich must be int for compilers where `char' is unsigned
      switch (ch) {
  
***************
*** 61,64 ****
--- 73,100 ----
        break;
  
+      case 's':
+       useStego = true;
+       break;
+ 
+      case 'S':
+       isFilename = false;
+       break;
+ 
+      case 't':
+       if (strcmp (optarg, "binary") == 0)
+ 	FIOstream::setFormat (FIOstream::Binary);
+       else if (strcmp (optarg, "base64") == 0)
+ 	FIOstream::setFormat (FIOstream::Base64);
+       else if (strcmp (optarg, "words") == 0)
+ 	FIOstream::setFormat (FIOstream::Words);
+       else
+ 	usage();
+       break;
+ 
+      case 'V':
+       cout << version_string << endl;
+       exit (0);
+       break;
+ 
      default:
        usage();
***************
*** 82,96 ****
      decode(argc, argv, output, k);
    } else {
!     encode(argc, argv, prefix, N, k, isExecutable, randomSource);
    }
  }
  
! static void encode(int argc, char** argv, const string& prefix, 
! 		   int N, int k, bool isExecutable, const string& randomSource)
  {
!   if (!argc)
!     usage();
! 
!   SecretShare ss(N, k);
  
    if (k > N) {
--- 118,133 ----
      decode(argc, argv, output, k);
    } else {
!     if (!argc)
!       usage();
!     encode(argv[0], isFilename, prefix, N, k, isExecutable, randomSource, useStego);
    }
  }
  
! static void encode(char* name, bool isFilename,
! 		   const string& prefix, 
! 		   int N, int k, bool isExecutable, const string& randomSource,
! 		   bool useStego)
  {
!   SecretShare ss(N, k, useStego);
  
    if (k > N) {
***************
*** 119,148 ****
    ss.setRNG(rand);
  
!   ifstream input(argv[0]);
  
!   if (!input) {
!     cout << "Error: Cannot open '" << argv[0] << "'" << endl;
!     return;
    }
  
-   ss.encode(input);
  }
  
! static void decode(int argc, char** argv, const string& output, int k)
  {
    SecretShare ss(k, k);
  
!   ifstream* files = new ifstream[argc];
!   ofstream out(output.c_str());
   
!   for (int i = 0; i < argc; i++) {
!     files[i].open(argv[i]);
      if (!files[i]) {
!       cout << "Error: Cannot open '" << argv[i] << "'." << endl;
        goto error;
      }
    }
  
!   if (!ss.decode(out, files)) {
      cout << "Error: Stream did not decode properly." << endl;
      cout << "       Perhaps -k is not set properly, or the wrong "
--- 156,204 ----
    ss.setRNG(rand);
  
!   if (isFilename)
!   {
!     ifstream input(name);
!     if (!input) {
!       cout << "Error: Cannot open '" << name << "'" << endl;
!       return;
!     }
  
!     ss.encode(input);
!   }
!   else
!   {
!     istrstream input(name);
!     ss.encode(input);
    }
  
  }
  
! static void decode(int nfiles, char** filenames, const string& output, int k)
  {
    SecretShare ss(k, k);
  
!   //ifstream* files = new ifstream[nfiles];
!   FIOstream** files = new (FIOstream*)[nfiles];
!   ofstream outstream;
!   ostream *out;
!   // if output string present, redirect output to a file, otherwise cout
!   if (output.length() == 0)
!     out = dynamic_cast<ostream*>(&cout);
!   else
!   {
!     outstream.open(output.c_str());
!     out = dynamic_cast<ostream*>(&outstream);
!   }
   
!   for (int i = 0; i < nfiles; i++) {
!     //files[i].open(filenames[i]);
!     files[i] = new FIOstream (filenames[i], FIOstream::Read);
      if (!files[i]) {
!       cout << "Error: Cannot open '" << filenames[i] << "'." << endl;
        goto error;
      }
    }
  
!   if (!ss.decode(*out, files)) {
      cout << "Error: Stream did not decode properly." << endl;
      cout << "       Perhaps -k is not set properly, or the wrong "
***************
*** 152,155 ****
--- 208,213 ----
    }
  
+   for (int i=0; i<nfiles; i++)
+     delete files[i];
    delete[] files;
  
***************
*** 159,163 ****
  
  error:
!   out.close();
    // unlink(output.c_str());
    return;
--- 217,221 ----
  
  error:
!   //out->close();			// let exit() close the file
    // unlink(output.c_str());
    return;
***************
*** 176,179 ****
--- 234,241 ----
    cout << "General options:" << endl;
    cout << "   -d           Decode (Encoding is default)" << endl;
+   cout << "   -S [string]  Encode string rather than file" << endl;
+   cout << "   -t [binary|base64|words] Specify format of split files" << endl;
+   cout << "   -s           Use steganography to conceal secrets" << endl;
+   cout << "   -V           Show version and exit" << endl;
    cout << endl;
  
