summaryrefslogtreecommitdiff
path: root/src/modules/common/sapphire.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/common/sapphire.cpp')
-rw-r--r--src/modules/common/sapphire.cpp231
1 files changed, 0 insertions, 231 deletions
diff --git a/src/modules/common/sapphire.cpp b/src/modules/common/sapphire.cpp
deleted file mode 100644
index 1c97934..0000000
--- a/src/modules/common/sapphire.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* sapphire.cpp -- the Saphire II stream cipher class.
- Dedicated to the Public Domain the author and inventor:
- (Michael Paul Johnson). This code comes with no warranty.
- Use it at your own risk.
- Ported from the Pascal implementation of the Sapphire Stream
- Cipher 9 December 1994.
- Added hash pre- and post-processing 27 December 1994.
- Modified initialization to make index variables key dependent,
- made the output function more resistant to cryptanalysis,
- and renamed to Sapphire II 2 January 1995
-*/
-
-
-#ifdef WIN32
-#include <memory.h>
-#endif
-
-#ifdef UNIX
-#include <memory.h>
-#include <unistd.h>
-#else
-#ifndef _MSC_VER
-#include <mem.h>
-#endif
-#endif
-
-#ifdef _WIN32_WCE
-#include <string.h>
-#endif
-
-#include "sapphire.h"
-
-SWORD_NAMESPACE_START
-
-unsigned char sapphire::keyrand(int limit,
- unsigned char *user_key,
- unsigned char keysize,
- unsigned char *rsum,
- unsigned *keypos)
- {
- unsigned u, // Value from 0 to limit to return.
- retry_limiter, // No infinite loops allowed.
- mask; // Select just enough bits.
-
- if (!limit) return 0; // Avoid divide by zero error.
- retry_limiter = 0;
- mask = 1; // Fill mask with enough bits to cover
- while (mask < (unsigned)limit) // the desired range.
- mask = (mask << 1) + 1;
- do
- {
- *rsum = cards[*rsum] + user_key[(*keypos)++];
- if (*keypos >= keysize)
- {
- *keypos = 0; // Recycle the user key.
- *rsum += keysize; // key "aaaa" != key "aaaaaaaa"
- }
- u = mask & *rsum;
- if (++retry_limiter > 11)
- u %= limit; // Prevent very rare long loops.
- }
- while (u > (unsigned)limit);
- return u;
- }
-
-void sapphire::initialize(unsigned char *key, unsigned char keysize)
- {
- // Key size may be up to 256 bytes.
- // Pass phrases may be used directly, with longer length
- // compensating for the low entropy expected in such keys.
- // Alternatively, shorter keys hashed from a pass phrase or
- // generated randomly may be used. For random keys, lengths
- // of from 4 to 16 bytes are recommended, depending on how
- // secure you want this to be.
-
- int i;
- unsigned char toswap, swaptemp, rsum;
- unsigned keypos;
-
- // If we have been given no key, assume the default hash setup.
-
- if (keysize < 1)
- {
- hash_init();
- return;
- }
-
- // Start with cards all in order, one of each.
-
- for (i=0;i<256;i++)
- cards[i] = i;
-
- // Swap the card at each position with some other card.
-
- toswap = 0;
- keypos = 0; // Start with first byte of user key.
- rsum = 0;
- for (i=255;i>=0;i--)
- {
- toswap = keyrand(i, key, keysize, &rsum, &keypos);
- swaptemp = cards[i];
- cards[i] = cards[toswap];
- cards[toswap] = swaptemp;
- }
-
- // Initialize the indices and data dependencies.
- // Indices are set to different values instead of all 0
- // to reduce what is known about the state of the cards
- // when the first byte is emitted.
-
- rotor = cards[1];
- ratchet = cards[3];
- avalanche = cards[5];
- last_plain = cards[7];
- last_cipher = cards[rsum];
-
- toswap = swaptemp = rsum = 0;
- keypos = 0;
- }
-
-void sapphire::hash_init(void)
- {
- // This function is used to initialize non-keyed hash
- // computation.
-
- int i, j;
-
- // Initialize the indices and data dependencies.
-
- rotor = 1;
- ratchet = 3;
- avalanche = 5;
- last_plain = 7;
- last_cipher = 11;
-
- // Start with cards all in inverse order.
-
- for (i=0, j=255;i<256;i++,j--)
- cards[i] = (unsigned char) j;
- }
-
-sapphire::sapphire(unsigned char *key, unsigned char keysize)
- {
- if (key && keysize)
- initialize(key, keysize);
- }
-
-void sapphire::burn(void)
- {
- // Destroy the key and state information in RAM.
- memset(cards, 0, 256);
- rotor = ratchet = avalanche = last_plain = last_cipher = 0;
- }
-
-sapphire::~sapphire()
- {
- burn();
- }
-
-unsigned char sapphire::encrypt(unsigned char b)
- {
-#ifdef USBINARY
- // Picture a single enigma rotor with 256 positions, rewired
- // on the fly by card-shuffling.
-
- // This cipher is a variant of one invented and written
- // by Michael Paul Johnson in November, 1993.
-
- unsigned char swaptemp;
-
- // Shuffle the deck a little more.
-
- ratchet += cards[rotor++];
- swaptemp = cards[last_cipher];
- cards[last_cipher] = cards[ratchet];
- cards[ratchet] = cards[last_plain];
- cards[last_plain] = cards[rotor];
- cards[rotor] = swaptemp;
- avalanche += cards[swaptemp];
-
- // Output one byte from the state in such a way as to make it
- // very hard to figure out which one you are looking at.
-
- last_cipher = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
- cards[cards[(cards[last_plain] +
- cards[last_cipher] +
- cards[avalanche])&0xFF]];
- last_plain = b;
- return last_cipher;
-#else
- return b;
-#endif
- }
-
-unsigned char sapphire::decrypt(unsigned char b)
- {
- unsigned char swaptemp;
-
- // Shuffle the deck a little more.
-
- ratchet += cards[rotor++];
- swaptemp = cards[last_cipher];
- cards[last_cipher] = cards[ratchet];
- cards[ratchet] = cards[last_plain];
- cards[last_plain] = cards[rotor];
- cards[rotor] = swaptemp;
- avalanche += cards[swaptemp];
-
- // Output one byte from the state in such a way as to make it
- // very hard to figure out which one you are looking at.
-
- last_plain = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
- cards[cards[(cards[last_plain] +
- cards[last_cipher] +
- cards[avalanche])&0xFF]];
- last_cipher = b;
- return last_plain;
- }
-
-void sapphire::hash_final(unsigned char *hash, // Destination
- unsigned char hashlength) // Size of hash.
- {
- int i;
-
- for (i=255;i>=0;i--)
- encrypt((unsigned char) i);
- for (i=0;i<hashlength;i++)
- hash[i] = encrypt(0);
- }
-
-SWORD_NAMESPACE_END