00001 #ifndef CRYPTOPP_SAPPHIRE_H
00002 #define CRYPTOPP_SAPPHIRE_H
00003
00004 #include "seckey.h"
00005 #include "secblock.h"
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009
00010 class SapphireBase : public VariableKeyLength<16, 1, 255>
00011 {
00012 protected:
00013 SapphireBase();
00014 SapphireBase(const byte *userKey, unsigned int keyLength);
00015 ~SapphireBase();
00016
00017 inline void ShuffleCards()
00018 {
00019 ratchet += cards[rotor++];
00020 byte swaptemp = cards[last_cipher];
00021 cards[last_cipher] = cards[ratchet];
00022 cards[ratchet] = cards[last_plain];
00023 cards[last_plain] = cards[rotor];
00024 cards[rotor] = swaptemp;
00025 avalanche += cards[swaptemp];
00026 }
00027
00028
00029
00030 SecByteBlock cards;
00031 byte rotor,
00032 ratchet,
00033 avalanche,
00034 last_plain,
00035 last_cipher;
00036
00037 private:
00038 byte keyrand(unsigned int limit, const byte *user_key, byte keysize, byte *rsum, unsigned *keypos);
00039 };
00040
00041
00042 class SapphireEncryption : public StreamTransformation, public SapphireBase
00043 {
00044 public:
00045 SapphireEncryption(const byte *userKey, unsigned int keyLength=DEFAULT_KEYLENGTH)
00046 : SapphireBase(userKey, keyLength) {}
00047
00048 inline byte ProcessByte(byte b)
00049 {
00050 ShuffleCards();
00051 last_cipher = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
00052 cards[cards[(cards[last_plain] +
00053 cards[last_cipher] +
00054 cards[avalanche])&0xFF]];
00055 last_plain = b;
00056 return last_cipher;
00057 }
00058
00059 void ProcessString(byte *outString, const byte *inString, unsigned int length);
00060 void ProcessString(byte *inoutString, unsigned int length);
00061
00062 protected:
00063 SapphireEncryption() {}
00064 };
00065
00066
00067 class SapphireDecryption : public StreamTransformation, public SapphireBase
00068 {
00069 public:
00070 SapphireDecryption(const byte *userKey, unsigned int keyLength=DEFAULT_KEYLENGTH)
00071 : SapphireBase(userKey, keyLength) {}
00072
00073 inline byte ProcessByte(byte b)
00074 {
00075 ShuffleCards();
00076 last_plain = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
00077 cards[cards[(cards[last_plain] +
00078 cards[last_cipher] +
00079 cards[avalanche])&0xFF]];
00080 last_cipher = b;
00081 return last_plain;
00082 }
00083
00084 void ProcessString(byte *outString, const byte *inString, unsigned int length);
00085 void ProcessString(byte *inoutString, unsigned int length);
00086 };
00087
00088
00089 class SapphireRNG : public RandomNumberGenerator, private SapphireEncryption
00090 {
00091 public:
00092 SapphireRNG(const byte *seed, unsigned int seedLength)
00093 : SapphireEncryption(seed, seedLength) {}
00094
00095 inline byte GetByte() {return SapphireEncryption::ProcessByte(0);}
00096 };
00097
00098
00099
00100 class SapphireHash : public HashTransformation, private SapphireEncryption
00101 {
00102 public:
00103 SapphireHash(unsigned int hashLength=20);
00104 void Update(const byte *input, unsigned int length);
00105 void TruncatedFinal(byte *hash, unsigned int size);
00106 unsigned int DigestSize() const {return hashLength;}
00107
00108 private:
00109 void Init();
00110 const unsigned int hashLength;
00111 };
00112
00113 NAMESPACE_END
00114
00115 #endif