⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sapphire.cpp

📁 通訊保密編碼library project code.完整library project code!
💻 CPP
字号:
// sapphire.cpp -- modified by Wei Dai from:

/* 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
*/

#include "sapphire.h"
#include "misc.h"
#include <assert.h>
#include <memory.h>

byte SapphireBase::keyrand(int limit,
                           const byte *user_key,
                           byte keysize,
                           byte *rsum,
                           unsigned *keypos)
    {
    unsigned u,             // Value from 0 to limit to return.
        retry_limiter,      // No infinite loops allowed.
        mask;               // Select just enough bits.

    retry_limiter = 0;
    mask = 1;               // Fill mask with enough bits to cover
    while (mask < 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 > limit);
    return u;
    }

SapphireBase::SapphireBase()
    : cards(SecAlloc(byte, 256))
{
}

SapphireBase::SapphireBase(const byte *key, unsigned int keysize)
    : cards(SecAlloc(byte, 256))
{
    assert(keysize < 256);
    // 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;
    byte rsum;
    unsigned keypos;

    // 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.

    keypos = 0;         // Start with first byte of user key.
    rsum = 0;
    for (i=255;i;i--)
        swap(cards[i], cards[keyrand(i, key, keysize, &rsum, &keypos)]);

    // 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];

    rsum = 0;
    keypos = 0;
}

SapphireBase::~SapphireBase()
{
    rotor = ratchet = avalanche = last_plain = last_cipher = 0;
    SecFree(cards, 256);
}

void SapphireEncryption::ProcessString(byte *outString, const byte *inString, unsigned int length)
{
    while(length--)
        *outString++ = SapphireEncryption::ProcessByte(*inString++);
}

void SapphireEncryption::ProcessString(byte *inoutString, unsigned int length)
{
    while(length--)
        *inoutString++ = SapphireEncryption::ProcessByte(*inoutString);
}

void SapphireDecryption::ProcessString(byte *outString, const byte *inString, unsigned int length)
{
    while(length--)
        *outString++ = SapphireDecryption::ProcessByte(*inString++);
}

void SapphireDecryption::ProcessString(byte *inoutString, unsigned int length)
{
    while(length--)
        *inoutString++ = SapphireDecryption::ProcessByte(*inoutString);
}

SapphireHash::SapphireHash(unsigned int hashLength)
    : SapphireEncryption(), hashLength(hashLength)
{
    // 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] = (byte) j;
}

void SapphireHash::Update(const byte *input, unsigned int length)
{
    while(length--)
        SapphireEncryption::ProcessByte(*input++);
}

void SapphireHash::Final(byte *hash, unsigned int overrideHashLength)
{
    int i;

    for (i=255;i>=0;i--)
        ProcessByte((byte) i);
    for (i=0;i<overrideHashLength;i++)
        hash[i] = ProcessByte(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -