Request For Comments - Simple Encryption.
I've been working on an Stream Cipher for about 2 weeks and I've gotten along way
I'm going to use this to protect files with my Check Book Program. At the request of a few friends.
Good, Bad, Ugly. What Do you Think?
I like ALL feedback.
Full Source zip is available with VS2003 Solution and project files.
Sorry but I don't have my 'make' file handy I'll load it onto my web server as soon as I get a chance.
Full Source
SimpleCipher_v0.1.zip
For the Winzip Impaired I've setup a Folder Containing all the files
SimpleCipher_v0.1/
If the links stop working then check it out here.
http://thedivinedude.home.comcast.net
This code works great on my
Mandrake Linux 32bit,
Slackware 12 Linux 32bit,
Windows Vista 64bit,
Windows Vista 32,
Windows XP,
Windows 98
I can encode a message on any machine and it be read without problems on the others.
I've been developing with Visual Studio 2003.net
And I've had no problems building under GCC g++ version 4.3.3
Red shows where i've made changes 2-16-09
SimpleCypher.h
Code:
#pragma once
#define CIPHER_ROUNDS 16
#include <iostream>
//#include "MyFileBuffer.h"
class SimpleCipher
{
public:
SimpleCipher(void);
~SimpleCipher(void);
void makeKey(unsigned char* key, size_t length);
unsigned char* makeKeyFile(unsigned char* key, size_t keylength, size_t count);
void cipher(void* data, size_t length);
void encrypt(void* data, size_t length);
void decrypt(void* data, size_t length);
private:
unsigned char ring_a[8];
unsigned char ring_b[8];
unsigned char ring_c[8];
unsigned char s_box[256];
size_t counter_a, counter_b, counter_c;
size_t a,b,c;
unsigned char* _key;
size_t _length;
bool _lock;
unsigned char rand();
void shiftbit(unsigned char* ring);
void MakeCheckSum(unsigned char* checksum, const void* data, unsigned int size);
};
SimpleCipher.cpp
Code:
#include ".\simplecipher.h"
void SimpleCipher::shiftbit(unsigned char* ring){
unsigned __int32 temp[2];
unsigned __int32* p = (unsigned __int32*) ring;
temp[0] = (*p) >> 1;
p++;
temp[1] = (*p) >> 1;
p--;
temp[1] |= (*p) << 31;
p++;
temp[0] |= (*p) << 31;
*p = temp[1];
p--;
*p = temp[0];
}
void SimpleCipher::MakeCheckSum(unsigned char* checksum, const void* data, unsigned int size)
{
//error check
if(checksum == NULL) return;
if(data == NULL) return;
if(size == 0 ) return;
unsigned char temp, carry;
unsigned char* d = (unsigned char*)data;
unsigned char* p;
carry = 0;
do{
temp = *d;
temp ^= carry;
p = checksum;
p += 7;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
p--;
temp >>= 1;
*p += (temp & 0x01);
d++;
size--;
carry ^= ( checksum[0] ^ checksum[1] ^ checksum[2] ^ checksum[3] ^
checksum[4] ^ checksum[5] ^ checksum[6] ^ checksum[7]);
shiftbit(checksum);
}while(size);
}
SimpleCipher::SimpleCipher(void)
{
_lock = false;
_key = 0;
_length = 0;
}
SimpleCipher::~SimpleCipher(void)
{
if(_key)
delete _key;
}
void SimpleCipher::makeKey(unsigned char* key, size_t length){
unsigned char temp;
if(_key)
delete _key;
_key = new unsigned char[length];
if(!_key) return;
_length = length;
this->counter_a = 64;
this->counter_b = 64;
this->counter_c = 64;
this->a = 0;
this->b = 0;
this->c = 0;
memset(&ring_a[0], 0, 8);
memset(&ring_b[0], 0, 8);
memset(&ring_c[0], 0, 8);
//Make key from user input.
for(int x = 0; x != 255; x++){
MakeCheckSum(&ring_a[0], key, length);
MakeCheckSum(&ring_b[0], &ring_a[0], 8);
MakeCheckSum(&ring_c[0], &ring_b[0], 8);
MakeCheckSum(&ring_a[0], &ring_c[0], 8);
}
//Prep s_boxes
for(int x = 0; x != 256; x++)
s_box[x] = x;
_lock = true;
for(int x = 0; x != 256; x++){
temp = this->rand();
for(int y = 0; y != 256; y++){
s_box[y] ^= temp;
rand();
}
}
this->encrypt(_key, _length);
_lock = false;
}
unsigned char* SimpleCipher::makeKeyFile(unsigned char* key, size_t keylength, size_t count){
return 0;
}
void SimpleCipher::cipher(void* data, size_t length){
unsigned char* p = (unsigned char*)data;
for(;length != 0;length--,p++)
*p ^= this->rand();
}
void SimpleCipher::encrypt(void* data, size_t length){
unsigned char* p = (unsigned char*)data;
for( ;length;length--){
for(int x=0; x != CIPHER_ROUNDS; x++){
*p += this->rand();
*p = s_box[(*p)];
*p -= s_box[this->rand()];
*p ^= this->rand();
}
p++;
}
}
void SimpleCipher::decrypt(void* data, size_t length){
unsigned char temp[CIPHER_ROUNDS*3], *p;
unsigned char s[256];
p = (unsigned char*)data;
for(int x = 0; x != 256; x++)
s[s_box[x]] = x;
for(;length;length--){
for(int x = 0; x != CIPHER_ROUNDS*3; x++)
temp[x] = this->rand();
for(int x = CIPHER_ROUNDS*3-1; x >= 0; x-=3){
*p ^= temp[x];
*p += s_box[temp[x-1]];
*p = s[(*p)];
*p -= temp[x-2];
}
p++;
}
}
unsigned char SimpleCipher::rand(){
unsigned char result;
a = (ring_a[c] & 0x07);
b = (ring_b[a] & 0x07);
c = (ring_c[b] & 0x07);
result = ring_a[a] ^ ring_b[b] ^ ring_c[c];
shiftbit(&ring_c[0]); counter_c--;
if(counter_c == 0){
counter_c = 64;
shiftbit(&ring_b[0]);
counter_b--;
if(counter_b == 0){
counter_b = 64;
shiftbit(&ring_a[0]);
counter_a++;
if(counter_a == 0){
counter_a = 64;
if(!_lock){
_lock = true;
for(int x = CIPHER_ROUNDS; x; x--){
this->encrypt(_key, _length);
MakeCheckSum(&ring_a[0], _key, _length);
MakeCheckSum(&ring_b[0], &ring_a[0], 8);
MakeCheckSum(&ring_c[0], &ring_b[0], 8);
MakeCheckSum(&ring_a[0], &ring_c[0], 8); }
_lock = false;
}
}
}
}
return result;
}