1
/* sapphire.cpp -- the Saphire II stream cipher class.
2
Dedicated to the Public Domain the author and inventor:
3
(Michael Paul Johnson). This code comes with no warranty.
4
Use it at your own risk.
5
Ported from the Pascal implementation of the Sapphire Stream
6
Cipher 9 December 1994.
7
Added hash pre- and post-processing 27 December 1994.
8
Modified initialization to make index variables key dependent,
9
made the output function more resistant to cryptanalysis,
10
and renamed to Sapphire II 2 January 1995
20
unsigned char sapphire::keyrand(int limit,
21
unsigned char *user_key,
22
unsigned char keysize,
26
unsigned u, // Value from 0 to limit to return.
27
retry_limiter, // No infinite loops allowed.
28
mask; // Select just enough bits.
30
if (!limit) return 0; // Avoid divide by zero error.
32
mask = 1; // Fill mask with enough bits to cover
33
while (mask < (unsigned)limit) // the desired range.
34
mask = (mask << 1) + 1;
37
*rsum = cards[*rsum] + user_key[(*keypos)++];
38
if (*keypos >= keysize)
40
*keypos = 0; // Recycle the user key.
41
*rsum += keysize; // key "aaaa" != key "aaaaaaaa"
44
if (++retry_limiter > 11)
45
u %= limit; // Prevent very rare long loops.
47
while (u > (unsigned)limit);
51
void sapphire::initialize(unsigned char *key, unsigned char keysize)
53
// Key size may be up to 256 bytes.
54
// Pass phrases may be used directly, with longer length
55
// compensating for the low entropy expected in such keys.
56
// Alternatively, shorter keys hashed from a pass phrase or
57
// generated randomly may be used. For random keys, lengths
58
// of from 4 to 16 bytes are recommended, depending on how
59
// secure you want this to be.
62
unsigned char toswap, swaptemp, rsum;
65
// If we have been given no key, assume the default hash setup.
73
// Start with cards all in order, one of each.
78
// Swap the card at each position with some other card.
81
keypos = 0; // Start with first byte of user key.
85
toswap = keyrand(i, key, keysize, &rsum, &keypos);
87
cards[i] = cards[toswap];
88
cards[toswap] = swaptemp;
91
// Initialize the indices and data dependencies.
92
// Indices are set to different values instead of all 0
93
// to reduce what is known about the state of the cards
94
// when the first byte is emitted.
99
last_plain = cards[7];
100
last_cipher = cards[rsum];
102
toswap = swaptemp = rsum = 0;
106
void sapphire::hash_init(void)
108
// This function is used to initialize non-keyed hash
113
// Initialize the indices and data dependencies.
121
// Start with cards all in inverse order.
123
for (i=0, j=255;i<256;i++,j--)
124
cards[i] = (unsigned char) j;
127
sapphire::sapphire(unsigned char *key, unsigned char keysize)
130
initialize(key, keysize);
133
void sapphire::burn(void)
135
// Destroy the key and state information in RAM.
136
memset(cards, 0, 256);
137
rotor = ratchet = avalanche = last_plain = last_cipher = 0;
140
sapphire::~sapphire()
145
unsigned char sapphire::encrypt(unsigned char b)
148
// Picture a single enigma rotor with 256 positions, rewired
149
// on the fly by card-shuffling.
151
// This cipher is a variant of one invented and written
152
// by Michael Paul Johnson in November, 1993.
154
unsigned char swaptemp;
156
// Shuffle the deck a little more.
158
ratchet += cards[rotor++];
159
swaptemp = cards[last_cipher];
160
cards[last_cipher] = cards[ratchet];
161
cards[ratchet] = cards[last_plain];
162
cards[last_plain] = cards[rotor];
163
cards[rotor] = swaptemp;
164
avalanche += cards[swaptemp];
166
// Output one byte from the state in such a way as to make it
167
// very hard to figure out which one you are looking at.
169
last_cipher = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
170
cards[cards[(cards[last_plain] +
172
cards[avalanche])&0xFF]];
180
unsigned char sapphire::decrypt(unsigned char b)
182
unsigned char swaptemp;
184
// Shuffle the deck a little more.
186
ratchet += cards[rotor++];
187
swaptemp = cards[last_cipher];
188
cards[last_cipher] = cards[ratchet];
189
cards[ratchet] = cards[last_plain];
190
cards[last_plain] = cards[rotor];
191
cards[rotor] = swaptemp;
192
avalanche += cards[swaptemp];
194
// Output one byte from the state in such a way as to make it
195
// very hard to figure out which one you are looking at.
197
last_plain = b^cards[(cards[ratchet] + cards[rotor]) & 0xFF] ^
198
cards[cards[(cards[last_plain] +
200
cards[avalanche])&0xFF]];
205
void sapphire::hash_final(unsigned char *hash, // Destination
206
unsigned char hashlength) // Size of hash.
211
encrypt((unsigned char) i);
212
for (i=0;i<hashlength;i++)
213
hash[i] = encrypt(0);