//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
/// Ahmed Alfaresi ///
/// Zia Kamawal ///
/// ///
/// ECE 575 Final Project ///
/// ///
/// Common Scrambling Algorithm ///
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
//////////////////////////////////////////
/****************************************************************************
This code was taken from csa.irde.to. It was made optimized and usable for out project. We created the user interface and allow for creating and reading of files. We have also incorporated a functionality that check two files for equivalency. This does the quivalency check in a way that would ensure that the same data data is always recoginzed as the same. We also have the functionality of receiving characters or 8 bit hex values in the form 0xFF.
Basically the user is given three options: encrypt, decrypt and compare.
encrypt:
Will first ask the user for a file in the current directory that contains a plaintext, up to 256 byte hex value. Then will ask for a file that contains a key, 8 byte hex value. The program will then encrypt the plaintext with the key and will output the ciphertext. The user will then be prompted to give a new filename to where the ciphertext will be saved. The user will then be directed back to the main menu.
decrypt:
Will first ask the user for a file in the current directory that contains a ciphertext, up to 256 byte hex value. Then will ask for a file that contains a key, 8 byte hex value. The program will then decrypt the ciphertext with the key and will output the original plaintext. The user will then be prompted to give a new filename to where the plaintext will be saved. The user will then be directed back to the main menu.
compare:
Will ask the user to input two filenames to be compared. The program will compare the two files. If they are the same, it will display PASSED!!. If they are different, it will display FAILED!!.
******************************************************************************/
/*
dvb common scrambling algorithm
refs:
uk patent: gb 2322 994
uk patent: gb 2322 995
freedec v2.1
iso/iec 13818-1
etr289 / dvb document a007
*/
#include <stdio.h>
//stream cypher
// 107 state bits
// 26 nibbles (4 bit)
// + 3 bits
// reg A[1]-A[10], 10 nibbles
// reg B[1]-B[10], 10 nibbles
// reg X, 1 nibble
// reg Y, 1 nibble
// reg Z, 1 nibble
// reg D, 1 nibble
// reg E, 1 nibble
// reg F, 1 nibble
// reg p, 1 bit
// reg q, 1 bit
// reg r, 1 bit
int sbox1[0x20] = {2,0,1,1,2,3,3,0, 3,2,2,0,1,1,0,3, 0,3,3,0,2,2,1,1, 2,2,0,3,1,1,3,0};
int sbox2[0x20] = {3,1,0,2,2,3,3,0, 1,3,2,1,0,0,1,2, 3,1,0,3,3,2,0,2, 0,0,1,2,2,1,3,1};
int sbox3[0x20] = {2,0,1,2,2,3,3,1, 1,1,0,3,3,0,2,0, 1,3,0,1,3,0,2,2, 2,0,1,2,0,3,3,1};
int sbox4[0x20] = {3,1,2,3,0,2,1,2, 1,2,0,1,3,0,0,3, 1,0,3,1,2,3,0,3, 0,3,2,0,1,2,2,1};
int sbox5[0x20] = {2,0,0,1,3,2,3,2, 0,1,3,3,1,0,2,1, 2,3,2,0,0,3,1,1, 1,0,3,2,3,1,0,2};
int sbox6[0x20] = {0,1,2,3,1,2,2,0, 0,1,3,0,2,3,1,3, 2,3,0,2,3,0,1,1, 2,1,1,2,0,3,3,0};
int sbox7[0x20] = {0,3,2,2,3,0,0,1, 3,0,1,3,1,2,2,1, 1,0,3,3,0,1,1,2, 2,3,1,0,2,3,0,2};
int stream_cypher(int init, unsigned char *CK, unsigned char *sb, unsigned char *cb)
{
int i,j;
int in1; // most significant nibble of input byte
int in2; // least significant nibble of input byte
int op;
int extra_B;
int s1,s2,s3,s4,s5,s6,s7;
int next_A1;
int next_B1;
int next_E;
static int A[11];
static int B[11];
static int X;
static int Y;
static int Z;
static int D;
static int E;
static int F;
static int p;
static int q;
static int r;
// reset
if (init)
{
// load first 32 bits of CK into A[1]..A[8]
// load last 32 bits of CK into B[1]..B[8]
// all other regs = 0
A[1] = (CK[0] >> 4) & 0xf;
A[2] = (CK[0] >> 0) & 0xf;
A[3] = (CK[1] >> 4) & 0xf;
A[4] = (CK[1] >> 0) & 0xf;
A[5] = (CK[2] >> 4) & 0xf;
A[6] = (CK[2] >> 0) & 0xf;
A[7] = (CK[3] >> 4) & 0xf;
A[8] = (CK[3] >> 0) & 0xf;
A[9] = 0;
A[10] = 0;
B[1] = (CK[4] >> 4) & 0xf;
B[2] = (CK[4] >> 0) & 0xf;
B[3] = (CK[5] >> 4) & 0xf;
B[4] = (CK[5] >> 0) & 0xf;
B[5] = (CK[6] >> 4) & 0xf;
B[6] = (CK[6] >> 0) & 0xf;
B[7] = (CK[7] >> 4) & 0xf;
B[8] = (CK[7] >> 0) & 0xf;
B[9] = 0;
B[10] = 0;
X=0;
Y=0;
Z=0;
D=0;
E=0;
F=0;
p=0;
q=0;
r=0;
}
// 8 bytes per operation
for(i=0; i<8; i++)
{
if (init)
{
in1 = (sb[i] >> 4) & 0x0f;
in2 = (sb[i] >> 0) & 0x0f;
}
op = 0;
// 2 bits per iteration
for(j=0; j<4; j++)
{
// from A[1]..A[10], 35 bits are selected as inputs to 7 s-boxes
// 5 bits input per s-box, 2 bits output per s-box
s1 = sbox1[ (((A[4]>>0)&1)<<4) | (((A[1]>>2)&1)<<3) | (((A[6]>>1)&1)<<2) | (((A[7]>>3)&1)<<1) | (((A[9]>>0)&1)<<0) ];
s2 = sbox2[ (((A[2]>>1)&1)<<4) | (((A[3]>>2)&1)<<3) | (((A[6]>>3)&1)<<2) | (((A[7]>>0)&1)<<1) | (((A[9]>>1)&1)<<0) ];
s3 = sbox3[ (((A[1]>>3)&1)<<4) | (((A[2]>>0)&1)<<3) | (((A[5]>>1)&1)<<2) | (((A[5]>>3)&1)<<1) | (((A[6]>>2)&1)<<0) ];
s4 = sbox4[ (((A[3]>>3)&1)<<4) | (((A[1]>>1)&1)<<3) | (((A[2]>>3)&1)<<2) | (((A[4]>>2)&1)<<1) | (((A[8]>>0)&1)<<0) ];
s5 = sbox5[ (((A[5]>>2)&1)<<4) | (((A[4]>>3)&1)<<3) | (((A[6]>>0)&1)<<2) | (((A[8]>>1)&1)<<1) | (((A[9]>>2)&1)<<0) ];
s6 = sbox6[ (((A[3]>>1)&1)<<4) | (((A[4]>>1)&1)<<3) | (((A[5]>>0)&1)<<2) | (((A[7]>>2)&1)<<1) | (((A[9]>>3)&1)<<0) ];
s7 = sbox7[ (((A[2]>>2)&1)<<4) | (((A[3]>>0)&1)<<3) | (((A[7]>>1)&1)<<2) | (((A[8]>>2)&1)<<1) | (((A[8]>>3)&1)<<0) ];
// use 4x4 xor to produce extra nibble for T3
extra_B = ( ((B[3]&1)<<3) ^ ((B[6]&2)<<2) ^ ((B[7]&4)<<1) ^ ((B[9]&8)>>0) ) |
( ((B[6]&1)<<2) ^ ((B[8]&2)<<1) ^ ((B[3]&8)>>1) ^ ((B[4]&4)>>0) ) |
( ((B[5]&8)>>2) ^ ((B[8]&4)>>1) ^ ((B[4]&1)<<1) ^ ((B[5]&2)>>0) ) |
( ((B[9]&4)>>2) ^ ((B[6]&8)>>3) ^ ((B[3]&2)>>1) ^ ((B[8]&1)>>0) ) ;
// T1 = xor all inputs
// in1,in2, D are only used in T1 during initialisation, not generation
next_A1 = A[10] ^ X;
if (init) next_A1 = next_A1 ^ D ^ ((j % 2) ? in2 : in1);
// T2 = xor all inputs
// in1,in2 are only used in T1 during initialisation, not generation
// if p=0, use this, if p=1, rotate the result left
next_B1 = B[7] ^ B[10] ^ Y;
if (init) next_B1 = next_B1 ^ ((j % 2) ? in1 : in2);
// if p=1, rotate left
if (p) next_B1 = ( (next_B1 << 1) | ((next_B1 >> 3) & 1) ) & 0xf;
// T3 = xor all inputs
D = E ^ Z ^ extra_