00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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,
00040 retry_limiter,
00041 mask;
00042
00043 if (!limit) return 0;
00044 retry_limiter = 0;
00045 mask = 1;
00046 while (mask < (unsigned)limit)
00047 mask = (mask << 1) + 1;
00048 do
00049 {
00050 *rsum = cards[*rsum] + user_key[(*keypos)++];
00051 if (*keypos >= keysize)
00052 {
00053 *keypos = 0;
00054 *rsum += keysize;
00055 }
00056 u = mask & *rsum;
00057 if (++retry_limiter > 11)
00058 u %= limit;
00059 }
00060 while (u > (unsigned)limit);
00061 return u;
00062 }
00063
00064 void sapphire::initialize(unsigned char *key, unsigned char keysize)
00065 {
00066
00067
00068
00069
00070
00071
00072
00073
00074 int i;
00075 unsigned char toswap, swaptemp, rsum;
00076 unsigned keypos;
00077
00078
00079
00080 if (keysize < 1)
00081 {
00082 hash_init();
00083 return;
00084 }
00085
00086
00087
00088 for (i=0;i<256;i++)
00089 cards[i] = i;
00090
00091
00092
00093 toswap = 0;
00094 keypos = 0;
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
00105
00106
00107
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
00122
00123
00124 int i, j;
00125
00126
00127
00128 rotor = 1;
00129 ratchet = 3;
00130 avalanche = 5;
00131 last_plain = 7;
00132 last_cipher = 11;
00133
00134
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
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
00162
00163
00164
00165
00166
00167 unsigned char swaptemp;
00168
00169
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
00180
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
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
00208
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,
00219 unsigned char hashlength)
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