📄 sapphire.cpp.svn-base
字号:
#include "stdafx.h"
#include "sapphire.h"
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//// Sapphire implementation starts here
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
/*
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.
*/
unsigned char CSapphire::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=0, // No infinite loops allowed.
mask=1; // Select just enough bits.
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)
if(limit) u%=limit; // Prevent very rare long loops.
} while(u>limit);
return u; }
void CSapphire::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; rsum=0; // Start with first byte of user key.
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 CSapphire::hash_init(void) {
// This function is used to initialize non-keyed hash computation.
// 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(int i=0,j=255;i<256;i++,j--) cards[i]=(unsigned char)j; }
CSapphire::CSapphire(unsigned char *key, unsigned char keysize) {
if(key&&keysize) initialize(key, keysize); }
void CSapphire::burn(void) {
// Destroy the key and state information in RAM.
memset(cards, 0, 256); rotor=ratchet=avalanche=last_plain=last_cipher=0; }
CSapphire::~CSapphire() { burn(); }
unsigned char CSapphire::encrypt(unsigned char b) {
// 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; }
unsigned char CSapphire::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 CSapphire::hash_final(unsigned char *hash, unsigned char hashlength) {
int i; for(i=255;i>=0;i--) encrypt((unsigned char)i);
for(i=0;i<hashlength;i++) hash[i]=encrypt(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -