Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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         {
00113                 *inoutString = SapphireEncryption::ProcessByte(*inoutString);
00114                 inoutString++;
00115         }
00116 }
00117 
00118 void SapphireDecryption::ProcessString(byte *outString, const byte *inString, unsigned int length)
00119 {
00120         while(length--)
00121                 *outString++ = SapphireDecryption::ProcessByte(*inString++);
00122 }
00123 
00124 void SapphireDecryption::ProcessString(byte *inoutString, unsigned int length)
00125 {
00126         while(length--)
00127         {
00128                 *inoutString = SapphireDecryption::ProcessByte(*inoutString);
00129                 inoutString++;
00130         }
00131 }
00132 
00133 SapphireHash::SapphireHash(unsigned int hashLength)
00134         : hashLength(hashLength)
00135 {
00136         Init();
00137 }
00138 
00139 void SapphireHash::Init()
00140 {
00141         // This function is used to initialize non-keyed hash
00142         // computation.
00143 
00144         int i, j;
00145 
00146         // Initialize the indices and data dependencies.
00147 
00148         rotor = 1;
00149         ratchet = 3;
00150         avalanche = 5;
00151         last_plain = 7;
00152         last_cipher = 11;
00153 
00154         // Start with cards all in inverse order.
00155 
00156         for (i=0, j=255;i<256;i++,j--)
00157                 cards[i] = (byte) j;
00158 }
00159 
00160 void SapphireHash::Update(const byte *input, unsigned int length)
00161 {
00162         while(length--)
00163                 SapphireEncryption::ProcessByte(*input++);
00164 }
00165 
00166 void SapphireHash::TruncatedFinal(byte *hash, unsigned int size)
00167 {
00168         ThrowIfInvalidTruncatedSize(size);
00169 
00170         for (int i=255; i>=0; i--)
00171                 ProcessByte((byte) i);
00172 
00173         for (unsigned int j=0; j<size; j++)
00174                 hash[j] = ProcessByte(0);
00175 
00176         Init();
00177 }
00178 
00179 NAMESPACE_END

Generated on Mon Apr 19 18:12:32 2004 for Crypto++ by doxygen 1.3.6-20040222