我是一名做迷你项目的学生 - DES实施。 我之前对将64位密钥转换为56位密钥感到怀疑,并且可以成功地做到这一点,这要归功于此处收到的一些指导。
我已将我的实现划分为密钥生成阶段(我为16轮中的每一轮生成新密钥)和加密阶段。
但是,我无法生成正确的密钥。 我使用“abcdefgh”作为键手动做了一个例子,我无法在程序中重现结果。
DES keygen阶段涉及:
将56位密钥分成2个28位密钥。我将4个字节中的28位存储为leftkey28[4]
(最后4位为0)& rightkey28[4]
(前4位为0)
使用(<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" 2然而,由于这个问题,我现在废弃了左移2,并且只剩下循环移位1.然而,这个问题的根本无法追踪。
问题似乎出现在我的输出行Round#2 Byte#2
中。
对于找出根本原因的任何指导或暗示,我将不胜感激。 ( 附:我之前从未做过那么多的操作! 代码没有根据Java规则/约定进行优化或编写,因为我只是想在做任何其他事情之前使其工作 )
提前致谢。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author krish 2nd Aug, 2011
*/
class DES {
final static int KEY_LENGTH = 8; // 8 byte key, 64 bits
final static int BLOCK_SIZE = 8; // 8 byte blocks, 64 bits
final static int NUM_ROUNDS = 16; // 16 rounds per block
// =======================================================================
// FOR KEY TRANSFORMATION
int[] compressionPermutation = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21,
10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,
55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36,
29, 32 };
// int[] keyShiftValue = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
// ---
// don't need this
// =======================================================================
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter an 8 char key: ");
String inputKey, inputMsg;
char[] inputArray;
byte[] key64 = new byte[8];
byte[] key56 = new byte[7];
int counter;
try {
// get key, key length() >= 8 chars
// inputKey = br.readLine();// uncomment later!!$$$$$$$
inputKey = "abcdefgh";
System.out.println(inputKey);
if (inputKey.length() < 8) {
System.out.println("Key < 8 B. Exiting. . .");
System.exit(1);
}
// java char has 16 bits instead of 8 bits as in C,
// so convert it to 8 bit char by getting lower order byte &
// discarding higher order byte; &
// consider only first 8 chars even if input > 8
inputArray = inputKey.toCharArray();
for (counter = 0; counter < 8; counter++)
key64[counter] = (byte) inputArray[counter];
// converting 64bit key to 56 bit key
for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
key64[counter] = (byte) (key64[counter] >>> 1);
key64[counter] = (byte) (key64[counter] << 1);
}
for (counter = 0; counter < KEY_LENGTH - 1; counter++) {
key56[counter] = (byte) (key64[counter] << counter);
key56[counter] = (byte) (key56[counter] | (key64[counter + 1] >>> (KEY_LENGTH - 1 - counter)));
}
/*
* Conversion from 64 to 56 bit testing code
*
* System.out.println("64 to 56 test:"); System.out.println(new
* String(key56)); System.out.println(); for (int counter1 = 0;
* counter1 < 7; counter1++) { for (int counter2 = 7; counter2 >= 0;
* counter2--) { System.out.println(key56[counter1] & (1 <<
* counter2)); } System.out.println(); }
*/
// end of obtaining 56bit key
// KEY GENERATION PHASE
// DS USED - compressionPermutation
byte[] leftKey28 = new byte[4];
byte[] rightKey28 = new byte[4];
byte circularBit;
byte[][] newKey56 = new byte[16][7];
// new 56 bit key for the first round, then loop for other rounds
leftKey28[0] = key56[0];
leftKey28[1] = key56[1];
leftKey28[2] = key56[2];
leftKey28[3] = (byte) (key56[3] & 11110000);
// rightKey28[0] = (byte) (key56[3] & 00001111);
// prob here, doesnt work as given above??
rightKey28[0] = (byte) (key56[3] - leftKey28[3]);
rightKey28[1] = key56[4];
rightKey28[2] = key56[5];
rightKey28[3] = key56[6];
/*
* // printing starts here System.out.print("1 Byte # 0" + " ");
* for (int counter2 = 7; counter2 >= 0; counter2--) {
* System.out.print(leftKey28[0] & (1 << counter2));
* System.out.print(", "); } System.out.println(); // printing ends
* here
*/
circularBit = (byte) (leftKey28[0] & (1 << 7));
leftKey28[0] = (byte) (leftKey28[0] << 1);
leftKey28[0] = (byte) (leftKey28[0] | ((((int) leftKey28[1]) & 0xff) >>> 7));
leftKey28[1] = (byte) (leftKey28[1] << 1);
leftKey28[1] = (byte) (leftKey28[1] | ((((int) leftKey28[2]) & 0xff) >>> 7));
leftKey28[2] = (byte) (leftKey28[2] << 1);
leftKey28[2] = (byte) (leftKey28[2] | ((((int) leftKey28[3]) & 0xff) >>> 7));
leftKey28[3] = (byte) (leftKey28[3] << 1);
leftKey28[3] = (byte) (leftKey28[3] | ((((int) circularBit) & 0xff) >>> 3));
circularBit = (byte) (rightKey28[0] & (1 << 3));
circularBit <<= 4;
rightKey28[0] = (byte) (rightKey28[0] << 1);
rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));
rightKey28[1] = (byte) (rightKey28[1] << 1);
rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));
rightKey28[2] = (byte) (rightKey28[2] << 1);
rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));
rightKey28[3] = (byte) (rightKey28[3] << 1);
rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 3));
newKey56[0][0] = leftKey28[0];
newKey56[0][1] = leftKey28[1];
newKey56[0][2] = leftKey28[2];
newKey56[0][3] = (byte) (leftKey28[3] | rightKey28[0]);
newKey56[0][4] = rightKey28[1];
newKey56[0][5] = rightKey28[2];
newKey56[0][6] = rightKey28[3];
// we have a new left circular shifted key in newKey56
// done testing for newkey56[0] // left and right testing code
for (int counter1 = 0; counter1 < 7; counter1++) {
System.out.print("Round#0 Byte#" + counter1 + " ");
for (int counter2 = 7; counter2 >= 0; counter2--) {
if (counter2 == 3)
System.out.print(" ");
if ((newKey56[0][counter1] & (1 << counter2)) > 0) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println();
}
// left and right testing code ends here
// for round 1 to 15: left circular shift each 28 bit block by 1{
for (int round = 1; round < NUM_ROUNDS; round++) {
// for the first round, then loop for other rounds
leftKey28[0] = newKey56[round - 1][0];
leftKey28[1] = newKey56[round - 1][1];
leftKey28[2] = newKey56[round - 1][2];
leftKey28[3] = (byte) (newKey56[round - 1][3] & 11110000);
// rightKey28[0] = (byte) (newKey56[round - 1][3] & 00001111);
rightKey28[0] = (byte) (newKey56[round - 1][3] - leftKey28[3]);
rightKey28[1] = newKey56[round - 1][4];
rightKey28[2] = newKey56[round - 1][5];
rightKey28[3] = newKey56[round - 1][6];
// if (round == 1 || round == 8 || round == 15) {
// left circular shift by 1
circularBit = (byte) (leftKey28[0] & (1 << 7));
leftKey28[0] <<= 1;
leftKey28[0] |= ((((int) leftKey28[1]) & 0xff) >>> 7);
leftKey28[1] <<= 1;
leftKey28[1] |= ((((int) leftKey28[2]) & 0xff) >>> 7);
// ////////////////////////error here ////////////////////////////
leftKey28[2] <<= 1;
leftKey28[2] |= ((((int) leftKey28[3]) & 0xff) >>> 7);
// ////////////////////////error here //////////////////////////
leftKey28[3] <<= 1;
leftKey28[3] |= ((((int) circularBit) & 0xff) >>> 3);
circularBit = (byte) (rightKey28[0] & (1 << 3));
circularBit <<= 4;
// //////////////////////////////////////////////////
rightKey28[0] = (byte) (rightKey28[0] << 1);
rightKey28[0] &= 00001111;
rightKey28[0] = (byte) (rightKey28[0] | ((((int) rightKey28[1]) & 0xff) >>> 7));
// //////////////////////////////////////////////////
rightKey28[1] = (byte) (rightKey28[1] << 1);
rightKey28[1] = (byte) (rightKey28[1] | ((((int) rightKey28[2]) & 0xff) >>> 7));
rightKey28[2] = (byte) (rightKey28[2] << 1);
rightKey28[2] = (byte) (rightKey28[2] | ((((int) rightKey28[3]) & 0xff) >>> 7));
rightKey28[3] = (byte) (rightKey28[3] << 1);
rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 7));
// } else {
// // left circular shift by 2
// }
newKey56[round][0] = leftKey28[0];
newKey56[round][1] = leftKey28[1];
newKey56[round][2] = leftKey28[2];
newKey56[round][3] = (byte) (leftKey28[3] | rightKey28[0]);
newKey56[round][4] = rightKey28[1];
newKey56[round][5] = rightKey28[2];
newKey56[round][6] = rightKey28[3];
// testing code for all keys for rounds 1 to 15
System.out.println();
for (int counter1 = 0; counter1 < 7; counter1++) {
System.out.print("Round#" + round + " Byte#" + counter1
+ " ");
for (int counter2 = 7; counter2 >= 0; counter2--) {
if (counter2 == 3)
System.out.print(" ");
if ((newKey56[round][counter1] & (1 << counter2)) > 0) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println();
}
if (round == 2)
break;
// testing code ends
}// for loop ends
/*
* // newKey56 testing code
* System.out.println("new56key testing here"); for (counter = 0;
* counter < NUM_ROUNDS; counter++) { System.out.println(new
* String(newKey56[counter])); System.out.println();
*
* for (int counter1 = 0; counter1 < 7; counter1++) {
* System.out.print("Round # " + counter + " Byte # " + counter1 +
* " "); for (int counter2 = 7; counter2 >= 0; counter2--) {
* System.out.print(newKey56[counter][counter1] & (1 << counter2));
* System.out.print(", "); } System.out.println(); } }
*/
// DO KEY COMPRESSION ROUTINE HERE
} catch (Exception e) {
e.printStackTrace();
}
}
}
Enter an 8 char key:
abcdefgh
Round#0 Byte#0 1100 0001
Round#0 Byte#1 1000 1011
Round#0 Byte#2 0001 0110
Round#0 Byte#3 0100 1100
Round#0 Byte#4 1001 1001
Round#0 Byte#5 1011 0011
Round#0 Byte#6 0110 1000
Round#1 Byte#0 1000 0011
Round#1 Byte#1 0001 0110
Round#1 Byte#2 0010 1100
Round#1 Byte#3 1001 1001
Round#1 Byte#4 0011 0011
Round#1 Byte#5 0110 0110
Round#1 Byte#6 1101 0001
Round#2 Byte#0 0000 0110
Round#2 Byte#1 0010 1100
Round#2 Byte#2 0101 1000 //error here => 0101 1001
Round#2 Byte#3 0011 0000 //error here => 0011 0010
Round#2 Byte#4 0110 0110
Round#2 Byte#5 1100 1101
Round#2 Byte#6 1010 0011
答案 0 :(得分:1)
使用DES的约定是假装你有64位密钥(8个字节),但如果你想真的,呃,迂腐,你用前7位的奇偶校验来破坏每个字节的第8位。
我只玩过Java,我看到Java(Sun / Oracle JRE)不打算检查奇偶校验。它只是忽略每个字节的第8位。
也许BouncyCastle中的DESEngine
会对你有所帮助。 generateWorkingKey()
方法看起来很有趣:
答案 1 :(得分:1)
看起来你在第一时间就是这样(有点):
// rightKey28[0] = (byte) (key56[3] & 00001111);
但你用减法代替它:
rightKey28[0] = (byte) (key56[3] - leftKey28[3]);
如果您希望rightKey28
的第一个字节设置其四个最低位,则原始代码(几乎)正确;新代码是错误的。
“种类”和“几乎”指的是在Java 7之前不支持二进制文字的事实。因此“11110000”是十进制整数,二进制模式为101010011000011001110000
。它几乎是巧合,但你错过了最高位;我想你想要的是0xF0
(和0x0F
的低阶位)。
此外,这些部分看起来很可疑:
circularBit = (byte) (rightKey28[0] & (1 << 3));
circularBit <<= 4;
这会将“循环”位移动到字节中的高位置:X000000
。
但后来你只将它向右移3位:
rightKey28[3] = (byte) (rightKey28[3] << 1);
rightKey28[3] = (byte) (rightKey28[3] | ((((int) circularBit) & 0xff) >>> 3));
如果rightKey28[3]
以位模式ABCDEFGH
开头,则最终会显示模式BCDYFGH0
,其中Y
是X | E
的逻辑结果。你真的不想BCDEFGHX
吗?如果是这样,您右移circularBit
7位。
最后,请注意rightKey[0]
将设置5位,因为您将其从左侧开始的4位移位1.您可能需要屏蔽以确保只有低位4位包含数据:
rightKey28[0] = (byte) ((rightKey28[0] << 1) & 0x0F);
答案 2 :(得分:1)
这是我的DES代码(在C中不完整)。 好吧,我尝试了Java 2周,并且在使用long进行整数,使用字节和短路等等(用于位操作/位移)时遇到了麻烦。 然后,放弃Java并在C中做到这一点。它只是加密代码。 希望它能帮助将来的某个人。如果我在任何地方都不正确,请告诉我。 感谢所有人的帮助。
/*
* des.c
* Created on: 2-Aug-2011
* Author: krish
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define KEY_LENGTH 8 // 8 char key, 64 bits
#define BLOCK_SIZE 8 // 8 char blocks, 64 bits
#define NUM_ROUNDS 16 // 16 uintRounds per block
// =======================================================================
// S-BOXES
int gSBox_1 = { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
}; //gSBox_1[8][8]
int getSBoxValue(int sbox,char position)
{
}
/*
int sbox_2[] = { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3,
13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11,
10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2,
11, 6, 7, 12, 0, 5, 14, 9, };
int sbox_3[] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13,
7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8,
15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4,
15, 14, 3, 11, 5, 2, 12, };
int sbox_4[] = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13,
8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12,
11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9,
4, 5, 11, 12, 7, 2, 14, };
int sbox_5[] = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14,
11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10,
13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6,
15, 0, 9, 10, 4, 5, 3, };
int sbox_6[] = { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10,
15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2,
8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11,
14, 1, 7, 6, 0, 8, 13, };
int sbox_7[] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13,
0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12,
3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9,
5, 0, 15, 14, 2, 3, 12, };
int sbox_8[] = { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1,
15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9,
12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13,
15, 12, 9, 0, 3, 5, 6, 11 };
// =======================================================================
*/
void getKey(char *key64) {
int returnValue = 0;
printf("\nEnter an 8 char key: ");
returnValue = scanf("%[a-zA-Z0-9]s", key64);
if (!returnValue) {
printf("\nError in scanf enintCountered.. Exiting...\n");
exit(1);
}
// key length() >= 8 chars
printf("\nInput key: %s\n", key64);
if (strlen(key64) != 8) {
printf("Key <> 8 bytes. Exiting. . .");
exit(3);
}
}
void getMessage(char *inputMsg) {
int returnValue = 0;
printf("\nEnter a message: ");
returnValue = scanf(" %[A-Za-z0-9. ]s", inputMsg);
if (!returnValue) {
printf("\nError in scanf enintCountered.. Exiting...\n");
exit(2);
}
}
void compressKey(char *key64, char *key56) {
int intCounter;
// conversion -64bit key to 56 bit key - starts here
for (intCounter = 0; intCounter < KEY_LENGTH; intCounter++) {
key64[intCounter] >>= 1;
key64[intCounter] <<= 1;
}
for (intCounter = 0; intCounter < KEY_LENGTH - 1; intCounter++) {
key56[intCounter] = key64[intCounter] << intCounter;
key56[intCounter] = key56[intCounter] | ((key64[intCounter + 1]
>> (KEY_LENGTH - 1 - intCounter)));
}
// conversion -64bit key to 56 bit key - ends here
}
char expandPlainText(unsigned uintCurrBits, unsigned uintPrevBit,
unsigned uintNextBit) {
char resultPtr;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
resultPtr = (char) (uintCurrBits & 0xff);
resultPtr |= (uintPrevBit << 4);
resultPtr <<= 1;
resultPtr |= (uintNextBit);
//printf("'%d'", resultPtr);
return resultPtr;
}
int main(int argc, char** argv) {
// =======================================================================
// FOR KEY TRANSFORMATION
int compressionPermutation[] = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21,
10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,
55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36,
29, 32 };
//int keyShiftValue[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };---don't need this
// =======================================================================
// =======================================================================
// FOR PLAINTEXT TRANSFORMATION
int
initialPermutation[] = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44,
36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56,
48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59,
51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7 };
/*int
finalPermutation[] = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47,
15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5,
45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35,
3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25 };
int permutationFunction[] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26,
5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11,
4, 25 };
int expansionPermutation[] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,
10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20,
21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 };
// ---
// don't need this
*/
// =======================================================================
char *key64 = (char *) calloc(9, sizeof(char)); //stores user input key
char *key56 = (char *) calloc(8, sizeof(char)); //56 bit key
char newKey56[16][7]; //used for key transformation
char compressedKey[16][6]; //stores compressed keys
char leftKey28[4], rightKey28[4];
unsigned int uintLeftTemp, uintRightTemp, uintCircularBit;
char *inputMsg = (char *) calloc(BLOCK_SIZE * 10, sizeof(char));
char *permutedPlaintextBlock =
(char *) calloc(BLOCK_SIZE + 1, sizeof(char)); //to store permuted plaintetx
char *plaintextBlock = (char *) calloc(BLOCK_SIZE + 1, sizeof(char)); // to store 1 block of plaintext
char expandedRightPlaintext[8];
//char expandedLeftPlaintext[8];// = (char *) calloc(BLOCK_SIZE + 1, sizeof(char));
char expandedPlaintext[6], XORedText[6], sboxText[8], encryptedText[4];
unsigned int uintCurrBits, uintPrevBit, uintNextBit;
int intCounter, intCounter1, intCounter2; //keep this signed!!!$$$$$$$$$$$$$
unsigned int uintNumBlocks, uintTempInteger, uintRound, uintPaddingSpaces;
getKey(key64);
getMessage(inputMsg);
//printing test code starts here
printf("\nInput key in binary:\n");
for (intCounter = 0; intCounter < 8; intCounter++) {
for (intCounter1 = 7; intCounter1 >= 0; intCounter1--) {
if ((key64[intCounter] & (1 << intCounter1)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
printf("\n");
//printing test code ends here
compressKey(key64, key56);
//printing test code starts here
printf("\n64 to 56 bit key:\n");
for (intCounter = 0; intCounter < 7; intCounter++) {
for (intCounter1 = 7; intCounter1 >= 0; intCounter1--) {
if ((key56[intCounter] & (1 << intCounter1)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
printf("\n");
//printing test code ends here
////////////////////////////////
// KEY TRANSFORMATION PHASE
////////////////////////////////
// new 56 bit key for the first uintRound, then loop for other uintRounds
leftKey28[0] = key56[0];
leftKey28[1] = key56[1];
leftKey28[2] = key56[2];
leftKey28[3] = key56[3] & 0xf0;
rightKey28[0] = key56[3] & 0x0f;
rightKey28[1] = key56[4];
rightKey28[2] = key56[5];
rightKey28[3] = key56[6];
uintLeftTemp = 0;
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[0]) & 0xff) << 24);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[1]) & 0xff) << 16);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[2]) & 0xff) << 8);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[3]) & 0xff) << 0);
uintRightTemp = 0;
uintRightTemp = uintRightTemp | ((((int) rightKey28[0]) & 0xff) << 24);
uintRightTemp = uintRightTemp | ((((int) rightKey28[1]) & 0xff) << 16);
uintRightTemp = uintRightTemp | ((((int) rightKey28[2]) & 0xff) << 8);
uintRightTemp = uintRightTemp | ((((int) rightKey28[3]) & 0xff) << 0);
uintCircularBit = uintLeftTemp & (1 << 31);
uintCircularBit = uintCircularBit >> 31;
uintLeftTemp <<= 1;
uintLeftTemp |= (uintCircularBit << 4);
uintCircularBit = uintRightTemp & (1 << 27);
uintCircularBit >>= 27;
uintRightTemp <<= 1;
uintRightTemp = uintRightTemp & 0x0fffffff;
uintRightTemp |= (uintCircularBit);
//convert uintLeftTemp to leftKey28 again
leftKey28[0] = uintLeftTemp >> 24;
leftKey28[1] = uintLeftTemp >> 16;
leftKey28[2] = uintLeftTemp >> 8;
leftKey28[3] = uintLeftTemp >> 0;
rightKey28[0] = uintRightTemp >> 24;
rightKey28[1] = uintRightTemp >> 16;
rightKey28[2] = uintRightTemp >> 8;
rightKey28[3] = uintRightTemp >> 0;
newKey56[0][0] = leftKey28[0];
newKey56[0][1] = leftKey28[1];
newKey56[0][2] = leftKey28[2];
newKey56[0][3] = leftKey28[3] | rightKey28[0];
newKey56[0][4] = rightKey28[1];
newKey56[0][5] = rightKey28[2];
newKey56[0][6] = rightKey28[3];
// have a new left circular shifted key in newKey56[0]
//*******************
//printing test code starts here
printf("\nnewKey56[0] key: ");
for (intCounter = 0; intCounter < 7; intCounter++) {
for (intCounter1 = 7; intCounter1 >= 0; intCounter1--) {
if ((newKey56[0][intCounter] & (1 << intCounter1)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
// for uintRound 1 to 15: left circular shift each 28 bit block by 1{
for (uintRound = 1; uintRound < NUM_ROUNDS; uintRound++) {
leftKey28[0] = newKey56[uintRound - 1][0];
leftKey28[1] = newKey56[uintRound - 1][1];
leftKey28[2] = newKey56[uintRound - 1][2];
leftKey28[3] = newKey56[uintRound - 1][3] & 0xf0;
rightKey28[0] = newKey56[uintRound - 1][3] & 0x0f;
rightKey28[1] = newKey56[uintRound - 1][4];
rightKey28[2] = newKey56[uintRound - 1][5];
rightKey28[3] = newKey56[uintRound - 1][6];
uintLeftTemp = 0;
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[0]) & 0xff) << 24);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[1]) & 0xff) << 16);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[2]) & 0xff) << 8);
uintLeftTemp = uintLeftTemp | ((((int) leftKey28[3]) & 0xff) << 0);
uintRightTemp = 0;
uintRightTemp = uintRightTemp | ((((int) rightKey28[0]) & 0xff) << 24);
uintRightTemp = uintRightTemp | ((((int) rightKey28[1]) & 0xff) << 16);
uintRightTemp = uintRightTemp | ((((int) rightKey28[2]) & 0xff) << 8);
uintRightTemp = uintRightTemp | ((((int) rightKey28[3]) & 0xff) << 0);
if (uintRound == 1 || uintRound == 8 || uintRound == 15) {
//left circular shift by 1
uintCircularBit = uintLeftTemp & (1 << 31);
uintCircularBit = uintCircularBit >> 31;
uintLeftTemp <<= 1;
uintLeftTemp |= (uintCircularBit << 4);
uintCircularBit = uintRightTemp & (1 << 27);
uintCircularBit >>= 27;
uintRightTemp <<= 1;
uintRightTemp = uintRightTemp & 0x0fffffff;
uintRightTemp |= (uintCircularBit);
} else {
//left circular shift by 2
uintCircularBit = 0;
uintCircularBit = uintLeftTemp & (11 << 30);
uintCircularBit = uintCircularBit >> 30;
uintLeftTemp <<= 2;
uintLeftTemp |= uintCircularBit << 4;
uintCircularBit = 0;
uintCircularBit = uintRightTemp & (11 << 26);
uintCircularBit >>= 26;
uintRightTemp <<= 2;
uintRightTemp = uintRightTemp & 0x0fffffff;
uintRightTemp |= (uintCircularBit);
}
//convert uintLeftTemp to leftKey28 again
leftKey28[0] = uintLeftTemp >> 24;
leftKey28[1] = uintLeftTemp >> 16;
leftKey28[2] = uintLeftTemp >> 8;
leftKey28[3] = uintLeftTemp >> 0;
rightKey28[0] = uintRightTemp >> 24;
rightKey28[1] = uintRightTemp >> 16;
rightKey28[2] = uintRightTemp >> 8;
rightKey28[3] = uintRightTemp >> 0;
newKey56[uintRound][0] = leftKey28[0];
newKey56[uintRound][1] = leftKey28[1];
newKey56[uintRound][2] = leftKey28[2];
newKey56[uintRound][3] = leftKey28[3] | rightKey28[0];
newKey56[uintRound][4] = rightKey28[1];
newKey56[uintRound][5] = rightKey28[2];
newKey56[uintRound][6] = rightKey28[3];
//printing test code starts here
printf("\nnewKey56[%d]: ", uintRound);
for (intCounter = 0; intCounter < 7; intCounter++) {
for (intCounter1 = 7; intCounter1 >= 0; intCounter1--) {
if ((newKey56[uintRound][intCounter] & (1 << intCounter1)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
}// for loop ends
////////////////////////////////
// KEY COMPRESSION PHASE
////////////////////////////////
for (uintRound = 0; uintRound < NUM_ROUNDS; uintRound++) {
for (intCounter = 0; intCounter < 48; intCounter++) {
uintTempInteger = 0;
uintTempInteger
= ((int) (newKey56[uintRound][(compressionPermutation[intCounter]
- 1) / 8])) & (1 << (7
- ((compressionPermutation[intCounter] - 1) % 8)));
// test code for printing temp value - starts here
if (uintTempInteger > 0) {
compressedKey[uintRound][intCounter / 8] |= (1 << (7
- (intCounter % 8)));
}
}
}
//printing test code starts here
for (intCounter1 = 0; intCounter1 < NUM_ROUNDS; intCounter1++) {
printf("\ncompressedKey[%d]: ", intCounter1);
for (intCounter = 0; intCounter < 6; intCounter++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((compressedKey[intCounter1][intCounter]
& (1 << intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
}
//printing test code ends here*/
// KEY COMPRESSION DONE
//////////////////////////
// WORKING WITH PLAINTEXT
//////////////////////////
printf("\n'%s'\n", inputMsg);
// if input length not a multiple of BLOCK_SIZE, pad it with spaces(ascii:32)
if (strlen(inputMsg) % BLOCK_SIZE != 0) {
uintPaddingSpaces = BLOCK_SIZE - (strlen(inputMsg) % BLOCK_SIZE);
for (intCounter = 0; intCounter < uintPaddingSpaces; intCounter++)
strcat(inputMsg, " ");
}
uintNumBlocks = strlen(inputMsg) / 8;
printf("\n'%s'\n'%d'\n", inputMsg, uintNumBlocks);
//intCounter1, intCounter2, uintRound;
for (intCounter = 0; intCounter < uintNumBlocks; intCounter++) {
for (intCounter1 = 0; intCounter1 < BLOCK_SIZE; intCounter1++) {
plaintextBlock[intCounter1] = inputMsg[intCounter * BLOCK_SIZE
+ intCounter1];
}
printf("'%s'", plaintextBlock);
////////////////////////////////
// INITIAL PERMUTATION FOR EACH BLOCK
////////////////////////////////
for (uintRound = 0; uintRound < NUM_ROUNDS; uintRound++) {
for (intCounter1 = 0; intCounter1 < 64; intCounter1++) {
uintTempInteger = 0;
uintTempInteger
= (((int) (plaintextBlock[(initialPermutation[intCounter1]
- 1) / 8])) & 0xff) & (1 << (7
- ((initialPermutation[intCounter1] - 1) % 8)));
// test code for printing temp value - starts here
if (uintTempInteger > 0) {
permutedPlaintextBlock[intCounter1 / 8] |= (1 << (7
- (intCounter1 % 8)));
}
}
//printing test code starts here
printf("\nBlock # %d uintRound # %d: ", intCounter, uintRound);
for (uintTempInteger = 0; uintTempInteger < BLOCK_SIZE; uintTempInteger++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((permutedPlaintextBlock[uintTempInteger] & (1
<< intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
/* IP DONE
* After IP, divide into leftPT and rightPT - 32 bits each
* do expansion permutation
* then do the 16 rounds
*/
uintLeftTemp = 0;
uintLeftTemp = uintLeftTemp
| ((((unsigned int) permutedPlaintextBlock[0]) & 0xff)
<< 24);
uintLeftTemp = uintLeftTemp
| ((((unsigned int) permutedPlaintextBlock[1]) & 0xff)
<< 16);
uintLeftTemp
= uintLeftTemp
| ((((unsigned int) permutedPlaintextBlock[2])
& 0xff) << 8);
uintLeftTemp
= uintLeftTemp
| ((((unsigned int) permutedPlaintextBlock[3])
& 0xff) << 0);
//printing test code starts here
printf("\nuintLeftTemp: ");
for (uintTempInteger = 32; uintTempInteger > 0; uintTempInteger--) {
if ((uintTempInteger) % 8 == 0)
printf(" ");
if ((uintLeftTemp & (1 << (uintTempInteger - 1))) > 0)
printf("1");
else
printf("0");
}
//printing test code ends here
uintRightTemp = 0;
uintRightTemp = uintRightTemp
| ((((unsigned int) permutedPlaintextBlock[4]) & 0xff)
<< 24);
uintRightTemp = uintRightTemp
| ((((unsigned int) permutedPlaintextBlock[5]) & 0xff)
<< 16);
uintRightTemp
= uintRightTemp
| ((((unsigned int) permutedPlaintextBlock[6])
& 0xff) << 8);
uintRightTemp
= uintRightTemp
| ((((unsigned int) permutedPlaintextBlock[7])
& 0xff) << 0);
//printing test code starts here
printf("\nuintRightTemp: ");
for (uintTempInteger = 32; uintTempInteger > 0; uintTempInteger--) {
if ((uintTempInteger) % 8 == 0)
printf(" ");
if ((uintRightTemp & (1 << (uintTempInteger - 1))) > 0)
printf("1");
else
printf("0");
}
//printing test code ends here
//done getting LPT & RPT
/*
* 32 bit RPT divided into 8 blks of 4 bits each
* 4 bit block converted into 6 bit block by adding prev blks'
* last bit and next blks' first bit
*/
//for block 0
uintCurrBits = (uintRightTemp >> 28) & 0x0f;
uintNextBit = (uintRightTemp >> 27) & 0x01;
uintPrevBit = (uintRightTemp >> 0) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[0] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[0]: '%d'",expandedRightPlaintext[0]);
//for block 1
uintCurrBits = (uintRightTemp >> 24) & 0x0f;
uintNextBit = (uintRightTemp >> 23) & 0x01;
uintPrevBit = (uintRightTemp >> 28) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[1] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[1]: '%d'",expandedRightPlaintext[1]);
//for block 2
uintCurrBits = (uintRightTemp >> 20) & 0x0f;
uintNextBit = (uintRightTemp >> 19) & 0x01;
uintPrevBit = (uintRightTemp >> 24) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[2] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[2]: '%d'",expandedRightPlaintext[2]);
//for block 3
uintCurrBits = (uintRightTemp >> 16) & 0x0f;
uintNextBit = (uintRightTemp >> 15) & 0x01;
uintPrevBit = (uintRightTemp >> 20) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[3] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[3]: '%d'",expandedRightPlaintext[3]);
//for block 4
uintCurrBits = (uintRightTemp >> 12) & 0x0f;
uintNextBit = (uintRightTemp >> 11) & 0x01;
uintPrevBit = (uintRightTemp >> 16) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[4] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[4]: '%d'",expandedRightPlaintext[4]);
//for block 5
uintCurrBits = (uintRightTemp >> 8) & 0x0f;
uintNextBit = (uintRightTemp >> 7) & 0x01;
uintPrevBit = (uintRightTemp >> 12) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[5] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[5]: '%d'",expandedRightPlaintext[5]);
//for block 6
uintCurrBits = (uintRightTemp >> 4) & 0x0f;
uintNextBit = (uintRightTemp >> 3) & 0x01;
uintPrevBit = (uintRightTemp >> 8) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[6] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[6]: '%d'",expandedRightPlaintext[6]);
//for block 7
uintCurrBits = (uintRightTemp >> 0) & 0x0f;
uintNextBit = (uintRightTemp >> 31) & 0x01;//********
uintPrevBit = (uintRightTemp >> 4) & 0x01;
//printf("\n%d %d %d\n", uintCurrBits, uintNextBit, uintPrevBit);
expandedRightPlaintext[7] = expandPlainText(uintCurrBits,
uintPrevBit, uintNextBit);
//printf("\nexpandedRightPlaintext[7]: '%d'",expandedRightPlaintext[7]);
//combine expandedRightPlaintext[0..7] to get a 48 bit RPT
//XOR with 48bit compressedKey and give result to SBox
//char compressedKey[16][6]; //stores compressed keys
//printing test code starts here
printf("\nexpandedRightPlaintext: ");
for (uintTempInteger = 0; uintTempInteger < BLOCK_SIZE; uintTempInteger++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((expandedRightPlaintext[uintTempInteger] & (1
<< intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
// conversion - 64 bit key to 48 bit RPT - starts here
for (uintTempInteger = 0; uintTempInteger < BLOCK_SIZE; uintTempInteger++)
expandedRightPlaintext[uintTempInteger] <<= 2;
expandedPlaintext[0] = (expandedRightPlaintext[0] << 0)
| (expandedRightPlaintext[1] >> 6);
expandedPlaintext[1] = (expandedRightPlaintext[1] << 2)
| (expandedRightPlaintext[2] >> 4);
expandedPlaintext[2] = (expandedRightPlaintext[2] << 4)
| (expandedRightPlaintext[3] >> 2);
expandedPlaintext[3] = (expandedRightPlaintext[4] << 0)
| (expandedRightPlaintext[5] >> 6);
expandedPlaintext[4] = (expandedRightPlaintext[5] << 2)
| (expandedRightPlaintext[6] >> 4);
expandedPlaintext[5] = (expandedRightPlaintext[6] << 4)
| (expandedRightPlaintext[7] >> 2);
// conversion - 64 bit key to 48 bit RPT - ends here
//we have a 48 bit plaintext in expandedPlaintext and a 48 bit key in compressedKey
//printing test code starts here
printf("\nexpandedPlaintext: ");
for (uintTempInteger = 0; uintTempInteger < 6; uintTempInteger++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((expandedPlaintext[uintTempInteger]
& (1 << intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
/* 48 bit RPT XORed with 48 bit key, then Sbox sub
* XORing here
*/
for (uintTempInteger = 0; uintTempInteger < 6; uintTempInteger++)
XORedText[uintTempInteger] = expandedPlaintext[uintTempInteger]
^ compressedKey[uintRound][uintTempInteger];
//printing test code starts here
printf("\nXORedPlaintext: ");
for (uintTempInteger = 0; uintTempInteger < 6; uintTempInteger++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((XORedText[uintTempInteger] & (1 << intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
// converting XORed text to blocks of 6 bits
//XORedPlaintext: 110111 01 10101101 00001000 01011011 10111011 01000010
sboxText[0] = (XORedText[0] >> 2) & 0x3f;
sboxText[1] = ((XORedText[0] & 0x03) << 4) | ((XORedText[1] >> 4)
& 0x0f);
sboxText[2] = ((XORedText[1] & 0x0f) << 2) | ((XORedText[2] >> 6)
& 0x03);
sboxText[3] = XORedText[2] & 0x3f;
sboxText[4] = (XORedText[3] >> 2) & 0x3f;
sboxText[5] = ((XORedText[3] & 0x03) << 4) | ((XORedText[4] >> 4)
& 0x0f);
sboxText[6] = ((XORedText[4] & 0x0f) << 2) | ((XORedText[5] >> 6)
& 0x03);
sboxText[7] = XORedText[5] & 0x3f;
//printing test code starts here
printf("\nsboxText: ");
for (uintTempInteger = 0; uintTempInteger < BLOCK_SIZE; uintTempInteger++) {
for (intCounter2 = 7; intCounter2 >= 0; intCounter2--) {
if ((sboxText[uintTempInteger] & (1 << intCounter2)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
//printing test code ends here
//CORRECT TILL HERE
for (uintTempInteger = 0; uintTempInteger < 4; uintTempInteger++) {
encryptedText[uintTempInteger]=getSBoxValue(gSBox_1,sboxText[uintTempInteger]);
encryptedText[0]<<=4;
encryptedText[uintTempInteger]=getSBoxValue(gSBox_1,sboxText[uintTempInteger+1]);
}
printf("\nencrypt: %d",encryptedText[0]);
break;
}
}
printf("\n\nSAFE EXIT\n");
return EXIT_SUCCESS;
}
/*
*
* TEST ROUTINES HERE
*
* //printing test code starts here
printf("\nleftKey28:\n");
for(intCounter=0;intCounter<4;intCounter++)
{
for(intCounter1=7;intCounter1>=0;intCounter1--)
{
if((leftKey28[intCounter] & (1 << intCounter1)) > 0)
printf("1");
else
printf("0");
}
printf(" ");
}
printf("\n");
//printing test code ends here*/
//printf("%ld %ld %ld\n", sizeof(int),sizeof(long int),sizeof(char));
//sizeof char = 8 bits
//sizeof int = 32 bits
//sizeof long = 64 bits
///
///