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

sapphire.cpp

00001 // sapphire.cpp -- modified by Wei Dai from:
00002 
00003 /* sapphire.cpp -- the Saphire II stream cipher class.
00004    Dedicated to the Public Domain the author and inventor:
00005    (Michael Paul Johnson).  This code comes with no warranty.
00006    Use it at your own risk.
00007    Ported from the Pascal implementation of the Sapphire Stream
00008    Cipher 9 December 1994.
00009    Added hash pre- and post-processing 27 December 1994.
00010    Modified initialization to make index variables key dependent,
00011    made the output function more resistant to cryptanalysis,
00012    and renamed to Sapphire II 2 January 1995
00013 */
00014 
00015 #include "pch.h"
00016 #include "sapphire.h"
00017 
00018 NAMESPACE_BEGIN(CryptoPP)
00019 
00020 byte SapphireBase::keyrand(unsigned int limit,
00021                                                    const byte *user_key,
00022                                                    byte keysize,
00023                                                    byte *rsum,
00024                                                    unsigned *keypos)
00025 {
00026         unsigned u,             // Value from 0 to limit to return.
00027                 retry_limiter,      // No infinite loops allowed.
00028                 mask;               // Select just enough bits.
00029 
00030         retry_limiter = 0;
00031         mask = 1;               // Fill mask with enough bits to cover
00032         while (mask < limit)    // the desired range.
00033                 mask = (mask << 1) + 1;
00034         do
00035                 {
00036                 *rsum = cards[*rsum] + user_key[(*keypos)++];
00037                 if (*keypos >= keysize)
00038                         {
00039                         *keypos = 0;            // Recycle the user key.
00040                         *rsum += keysize;   // key "aaaa" != key "aaaaaaaa"
00041                         }
00042                 u = mask & *rsum;
00043                 if (++retry_limiter > 11)
00044                         u %= limit;     // Prevent very rare long loops.
00045                 }
00046         while (u > limit);
00047         return u;
00048 }
00049 
00050 SapphireBase::SapphireBase()
00051         : cards(256)
00052 {
00053 }
00054 
00055 SapphireBase::SapphireBase(const byte *key, unsigned int keysize)
00056         : cards(256)
00057 {
00058         assert(keysize < 256);
00059         // Key size may be up to 256 bytes.
00060         // Pass phrases may be used directly, with longer length
00061         // compensating for the low entropy expected in such keys.
00062         // Alternatively, shorter keys hashed from a pass phrase or
00063         // generated randomly may be used. For random keys, lengths
00064         // of from 4 to 16 bytes are recommended, depending on how
00065         // secure you want this to be.
00066 
00067         int i;
00068         byte rsum;
00069         unsigned keypos;
00070 
00071         // Start with cards all in order, one of each.
00072 
00073         for (i=0;i<256;i++)
00074                 cards[i] = i;
00075 
00076         // Swap the card at each position with some other card.
00077 
00078         keypos = 0;         // Start with first byte of user key.
00079         rsum = 0;
00080         for (i=255;i;i--)
00081                 std::swap(cards[i], cards[keyrand(i, key, keysize, &rsum, &keypos)]);
00082 
00083         // Initialize the indices and data dependencies.
00084         // Indices are set to different values instead of all 0
00085         // to reduce what is known about the state of the cards
00086         // when the first byte is emitted.
00087 
00088         rotor = cards[1];
00089         ratchet = cards[3];
00090         avalanche = cards[5];
00091         last_plain = cards[7];
00092         last_cipher = cards[rsum];
00093 
00094         rsum = 0;
00095         keypos = 0;
00096 }
00097 
00098 SapphireBase::~SapphireBase()
00099 {
00100         rotor = ratchet = avalanche = last_plain = last_cipher = 0;
00101 }
00102 
00103 void SapphireEncryption::ProcessString(byte *outString, const byte *inString, unsigned int length)
00104 {
00105         while(length--)
00106                 *outString++ = SapphireEncryption::ProcessByte(*inString++);
00107 }
00108 
00109 void SapphireEncryption::ProcessString(byte *inoutString, unsigned int length)
00110 {
00111         while(length--)
00112                 *inoutString++ = SapphireEncryption::ProcessByte(*inoutString);
00113 }
00114 
00115 void SapphireDecryption::ProcessString(byte *outString, const byte *inString, unsigned int length)
00116 {
00117         while(length--)
00118                 *outString++ = SapphireDecryption::ProcessByte(*inString++);
00119 }
00120 
00121 void SapphireDecryption::ProcessString(byte *inoutString, unsigned int length)
00122 {
00123         while(length--)
00124                 *inoutString++ = SapphireDecryption::ProcessByte(*inoutString);
00125 }
00126 
00127 SapphireHash::SapphireHash(unsigned int hashLength)
00128         : SapphireEncryption(), hashLength(hashLength)
00129 {
00130         // This function is used to initialize non-keyed hash
00131         // computation.
00132 
00133         int i, j;
00134 
00135         // Initialize the indices and data dependencies.
00136 
00137         rotor = 1;
00138         ratchet = 3;
00139         avalanche = 5;
00140         last_plain = 7;
00141         last_cipher = 11;
00142 
00143         // Start with cards all in inverse order.
00144 
00145         for (i=0, j=255;i<256;i++,j--)
00146                 cards[i] = (byte) j;
00147 }
00148 
00149 void SapphireHash::Update(const byte *input, unsigned int length)
00150 {
00151         while(length--)
00152                 SapphireEncryption::ProcessByte(*input++);
00153 }
00154 
00155 void SapphireHash::Final(byte *hash, unsigned int overrideHashLength)
00156 {
00157         for (int i=255; i>=0; i--)
00158                 ProcessByte((byte) i);
00159 
00160         for (unsigned int j=0; j<overrideHashLength; j++)
00161                 hash[j] = ProcessByte(0);
00162 }
00163 
00164 NAMESPACE_END

Generated at Mon Jan 15 01:16:36 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000