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 Fri Aug 13 09:56:55 2004 for Crypto++ by doxygen 1.3.7