Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

sapphire.cpp

00001 /* sapphire.cpp -- the Saphire II stream cipher class.
00002    Dedicated to the Public Domain the author and inventor:
00003    (Michael Paul Johnson).  This code comes with no warranty.
00004    Use it at your own risk.
00005    Ported from the Pascal implementation of the Sapphire Stream
00006    Cipher 9 December 1994.
00007    Added hash pre- and post-processing 27 December 1994.
00008    Modified initialization to make index variables key dependent,
00009    made the output function more resistant to cryptanalysis,
00010    and renamed to Sapphire II 2 January 1995
00011 */
00012 
00013 
00014 #ifdef WIN32
00015 #include <memory.h>
00016 #endif
00017 
00018 #ifdef UNIX
00019 #include <memory.h>
00020 #include <unistd.h>
00021 #else
00022 #ifndef _MSC_VER
00023 #include <mem.h>
00024 #endif
00025 #endif
00026 
00027 #ifdef _WIN32_WCE
00028 #include <string.h>
00029 #endif
00030 
00031 #include "sapphire.h"
00032 
00033 unsigned char sapphire::keyrand(int limit,
00034                                 unsigned char *user_key,
00035                                 unsigned char keysize,
00036                                 unsigned char *rsum,
00037                                 unsigned *keypos)
00038     {
00039     unsigned u,             // Value from 0 to limit to return.
00040         retry_limiter,      // No infinite loops allowed.
00041         mask;               // Select just enough bits.
00042 
00043     if (!limit) return 0;   // Avoid divide by zero error.
00044     retry_limiter = 0;
00045     mask = 1;               // Fill mask with enough bits to cover
00046     while (mask < (unsigned)limit)    // the desired range.
00047         mask = (mask << 1) + 1;
00048     do
00049         {
00050         *rsum = cards[*rsum] + user_key[(*keypos)++];
00051         if (*keypos >= keysize)
00052             {
00053             *keypos = 0;            // Recycle the user key.
00054             *rsum += keysize;   // key "aaaa" != key "aaaaaaaa"
00055             }
00056         u = mask & *rsum;
00057         if (++retry_limiter > 11)
00058             u %= limit;     // Prevent very rare long loops.
00059         }
00060     while (u > (unsigned)limit);
00061     return u;
00062     }
00063 
00064 void sapphire::initialize(unsigned char *key, unsigned char keysize)
00065     {
00066     // Key size may be up to 256 bytes.
00067     // Pass phrases may be used directly, with longer length
00068     // compensating for the low entropy expected in such keys.
00069     // Alternatively, shorter keys hashed from a pass phrase or
00070     // generated randomly may be used. For random keys, lengths
00071     // of from 4 to 16 bytes are recommended, depending on how
00072     // secure you want this to be.
00073 
00074     int i;
00075     unsigned char toswap, swaptemp, rsum;
00076     unsigned keypos;
00077 
00078     // If we have been given no key, assume the default hash setup.
00079 
00080     if (keysize < 1)
00081         {
00082         hash_init();
00083         return;
00084         }
00085 
00086     // Start with cards all in order, one of each.
00087 
00088     for (i=0;i<256;i++)
00089         cards[i] = i;
00090 
00091     // Swap the card at each position with some other card.
00092 
00093     toswap = 0;
00094     keypos = 0;         // Start with first byte of user key.
00095     rsum = 0;
00096     for (i=255;i>=0;i--)
00097         {
00098         toswap = keyrand(i, key, keysize, &rsum, &keypos);
00099         swaptemp = cards[i];
00100         cards[i] = cards[toswap];
00101         cards[toswap] = swaptemp;
00102         }
00103 
00104     // Initialize the indices and data dependencies.
00105     // Indices are set to different values instead of all 0
00106     // to reduce what is known about the state of the cards
00107     // when the first byte is emitted.
00108 
00109     rotor = cards[1];
00110     ratchet = cards[3];
00111     avalanche = cards[5];
00112     last_plain = cards[7];
00113     last_cipher = cards[rsum];
00114 
00115     toswap = swaptemp = rsum = 0;
00116     keypos = 0;
00117     }
00118 
00119 void sapphire::hash_init(void)
00120     {
00121     // This function is used to initialize non-keyed hash
00122     // computation.
00123 
00124     int i, j;
00125 
00126     // Initialize the indices and data dependencies.
00127 
00128     rotor = 1;
00129     ratchet = 3;
00130     avalanche = 5;
00131     last_plain = 7;
00132     last_cipher = 11;
00133 
00134     // Start with cards all in inverse order.
00135 
00136     for (i=0, j=255;i<256;i++,j--)
00137         cards[i] = (unsigned char) j;
00138     }
00139 
00140 sapphire::sapphire(unsigned char *key, unsigned char keysize)
00141     {
00142     if (key && keysize)
00143         initialize(key, keysize);
00144     }
00145 
00146 void sapphire::burn(void)
00147     {
00148     // Destroy the key and state information in RAM.
00149     memset(cards, 0, 256);
00150     rotor = ratchet = avalanche = last_plain = last_cipher = 0;
00151     }
00152 
00153 sapphire::~sapphire()
00154     {
00155     burn();
00156     }
00157 
00158 unsigned char sapphire::encrypt(unsigned char b)
00159     {
00160 #ifdef USBINARY
00161     // Picture a single enigma rotor with 256 positions, rewired
00162     // on the fly by card-shuffling.
00163 
00164     // This cipher is a variant of one invented and written
00165     // by Michael Paul Johnson in November, 1993.
00166 
00167     unsigned char swaptemp;
00168 
00169     // Shuffle the deck a little more.
00170 
00171     ratchet += cards[rotor++];
00172     swaptemp = cards[last_cipher];
00173     cards[last_cipher] = cards[ratchet];
00174     cards[ratchet] = cards[last_plain];
00175     cards[last_plain] = cards[rotor];
00176     cards[rotor] = swaptemp;
00177     avalanche += cards[swaptemp];
00178 
00179     // Output one byte from the state in such a way as to make it
00180     // very hard to figure out which one you are looking at.
00181 
00182     last_cipher = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
00183                   cards[cards[(cards[last_plain] +
00184                                cards[last_cipher] +
00185                                cards[avalanche])&0xFF]];
00186     last_plain = b;
00187     return last_cipher;
00188 #else
00189     return b;
00190 #endif
00191     }
00192 
00193 unsigned char sapphire::decrypt(unsigned char b)
00194     {
00195     unsigned char swaptemp;
00196 
00197     // Shuffle the deck a little more.
00198 
00199     ratchet += cards[rotor++];
00200     swaptemp = cards[last_cipher];
00201     cards[last_cipher] = cards[ratchet];
00202     cards[ratchet] = cards[last_plain];
00203     cards[last_plain] = cards[rotor];
00204     cards[rotor] = swaptemp;
00205     avalanche += cards[swaptemp];
00206 
00207     // Output one byte from the state in such a way as to make it
00208     // very hard to figure out which one you are looking at.
00209 
00210     last_plain = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
00211                    cards[cards[(cards[last_plain] +
00212                                 cards[last_cipher] +
00213                                 cards[avalanche])&0xFF]];
00214     last_cipher = b;
00215     return last_plain;
00216     }
00217 
00218 void sapphire::hash_final(unsigned char *hash,      // Destination
00219                           unsigned char hashlength) // Size of hash.
00220     {
00221     int i;
00222 
00223     for (i=255;i>=0;i--)
00224         encrypt((unsigned char) i);
00225     for (i=0;i<hashlength;i++)
00226         hash[i] = encrypt(0);
00227     }
00228 

Generated on Thu Jun 20 22:13:00 2002 for The Sword Project by doxygen1.2.15