educoder DES加解密算法的实现
//
// des.cpp
// step3
//
// Created by ljpc on 2018/10/17.
// Copyright © 2018年 ljpc. All rights reserved.
//
#include "des.h"
bool flag = true;
void print_bool(char* s, const bool *out, int len){
printf("%s: ", s);
for (int i=0; i<len; i++) {
printf("%d", out[i]);
}
printf("\n");
}
void SETKEY(const char Key_C[8], bool Key_B[64])
// Key_C: 2018helo
// ascii: 0x32 0x30 0x31 0x38 0x68 0x65 0x6c 0x6f
// 8bits: 00110010 00110000 00110001 00111000 01101000 01100101 01101100 01101111
// Key_B: 0011001000110000001100010011100001101000011001010110110001101111
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
for(int i=0; i<8; i++)
for(int j=0; j<8; ++j)
//Key_B[63-i*8-j] = ((Key_C[i]>>j) & 1);
Key_B[i*8+7-j] = ((Key_C[i]>>j) & 1);
/********* End *********/
}
void ByteToBit(bool *Outs, const char *In, int bits)
// In: password
// ascii: 0x70 0x61 0x73 0x73 0x77 0x6f 0x72 0x64
// 8bits: 01110000 01100001 01110011 01110011 01110111 01101111 01110010 01100100
// Outs: 0111000001100001011100110111001101110111011011110111001001100100
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
for(int i=0; i<bits; i++)
for(int j=0; j<bits; ++j)
//Outs[63-i*bits-j] = ((In[i]>>j) & 1);
Outs[i*bits+bits-1-j] = ((In[i]>>j) & 1);
/********* End *********/
}
void BitToByte(char *Outs, const bool *In, int bits)
// In: 0111000001100001011100110111001101110111011011110111001001100100
// 8bits: 01110000 01100001 01110011 01110011 01110111 01101111 01110010 01100100
// ascii: 0x70 0x61 0x73 0x73 0x77 0x6f 0x72 0x64
// Outs: password
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
for(int i=0; i<bits; i++){
int val = 0;
for (int j=0; j<bits; j++) {
//val = (val<<1) | In[63-i*bits-(bits-1-j)];
val = (val<<1) | In[i*bits+j];
}
Outs[i] = val;
}
Outs[bits] = '\0';
/********* End *********/
}
void CYCLELEFT(bool *In, int len, int loop) // 循环左移函数
// before: 0000000011110000111111110000
// loop: 1
// after: 0000000111100001111111100000
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
bool tmp[28];
memcpy(tmp, In, sizeof(tmp));
for (int i=0; i<len; i++) {
In[i] = tmp[(i+loop)%len];
}
/********* End *********/
}
void Set_SubKey(bool subKey[16][48], bool Key[64]) // 设置子密钥
// Key: 0011001000110000001100010011100001101000011001010110110001101111
// SubKey: 011000000011110001100100010111000101100101000100
// SubKey: 010000001011010001110100010111001000100011100100
// SubKey: 110001001100010001110110110000001110110011011001
// SubKey: 111001101100001100100010001010111011011000011001
// SubKey: 101010101001001100100011101110110101010100100010
// SubKey: 101010010001001001011011000011000100101100100110
// SubKey: 001001010101001011011000110101000110100011010100
// SubKey: 000101100101100111010000111000011000001011011001
// SubKey: 000101100100100101010001111000111010011010011000
// SubKey: 000011110110100100010101001110010001011100001111
// SubKey: 000011110010010110001101000111100101000010100110
// SubKey: 010110110000010010101001010001000110100111100101
// SubKey: 110110011000100010101000101000101010100011011001
// SubKey: 100100001010101010001110111000111001011100010011
// SubKey: 001100000011111000000110000111110000011100101010
// SubKey: 011100000011111000000100000101000101011101100110
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
bool realKey[56];
bool left[28];
bool right[28];
bool compressKey[48]; // 去掉奇偶标记位,将64位密钥变成56位
for (int i=0; i<56; i++){
realKey[i] = Key[TRANS_64to56[i]-1];
}
// 生成子密钥,保存在 subKeys[16] 中
for(int round=0; round<16; round++)
{
// 前28位与后28位
for(int i=0; i<28; i++)
left[i] = realKey[i];
for(int i=28; i<56; i++)
right[i-28] = realKey[i];
// 左移
CYCLELEFT(left, 28, SHIFT_TAB[round]);
CYCLELEFT(right, 28, SHIFT_TAB[round]);
for(int i=0; i<28; i++)
realKey[i] = left[i];
for(int i=28; i<56; i++)
realKey[i] = right[i-28];
// 压缩置换,由56位得到48位子密钥
for(int i=0; i<48; i++)
compressKey[i] = realKey[TRANS_56to48[i]-1];
for (int i=0; i<48; i++) {
subKey[round][i] = compressKey[i];
}
}
/********* End *********/
}
void XOR(bool *InA, const bool *InB, int len) // 异或函数
// Before InA: 000000000001011111111110100100000000001111111000
// Before InB: 011000000011110001100100010111000101100101000100
// Before InA: 011000000010101110011010110011000101101010111100
// Before InB: 011000000011110001100100010111000101100101000100
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
for (int i=0; i<len; i++) {
InA[i] = InA[i] ^ InB[i];
}
/********* End *********/
}
void S_BOXF(bool Out[32], const bool In[48])// S-盒代替函数
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
int x = 0;
for(int i=0; i<48; i=i+6)
{
int row = In[i+0]*2 + In[i+5];
int col = In[i+1]*8 + In[i+2]*4 + In[i+3]*2 + In[i+4];
int num = S_BOX[i/6][row][col];
for (int k=3; k>=0; k--) {
Out[x+k] = num%2;
num /= 2;
}
x += 4;
}
/********* End *********/
}
void F_FUNCTION(bool In[32], const bool Ki[48]) // f 函数完成扩展置换、S-盒代替和P盒置换
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
// 第一步:扩展置换,32 -> 48
bool expandR[48];
for(int i=0; i<48; i++)
//expandR[47-i] = In[32-EXPAND_32to48[i]]; // 0x8c 0x22 0xe2 0x86 0x48 0x5a 0x4b 0xae
expandR[i] = In[EXPAND_32to48[i]-1]; // 0x8c 0x22 0xe2 0x86 0x48 0x5a 0x4b 0xae
// 第二步:异或
XOR(expandR, Ki, 48);
// 第三步:查找S_BOX置换表
bool output[32];
S_BOXF(output, expandR);
// 第四步:P-置换,32 -> 32
for(int i=0; i<32; i++){
In[i] = output[TRANS_32to32[i]-1];
}
/********* End *********/
}
void DES(char Out[8], char In[8], const bool subKey[16][48], bool Type) // 标准DES Type: True加密/False解密
{
// 请在这里补充代码,完成本关任务
/********* Begin *********/
bool plain[64];
bool left[32];
bool right[32];
bool newLeft[32];
bool cipher[64];
bool currentBits[64];
ByteToBit(plain, In, 8);
// 第一步:初始置换IP
for(int i=0; i<64; i++)
currentBits[i] = plain[TRANS_INIT[i]-1];
// 第二步:获取 Li 和 Ri
for(int i=0; i<32; i++)
left[i] = currentBits[i];
for(int i=32; i<64; i++)
right[i-32] = currentBits[i];
// 第三步:共16轮迭代
if (Type == true) { // 加密
for(int round=0; round<16; round++)
{
memcpy(newLeft, right, sizeof(newLeft));
F_FUNCTION(right,subKey[round]);
XOR(right, left, 32);
memcpy(left, newLeft, sizeof(left));
}
}
if (Type == false) { // 解密
for(int round=15; round>=0; round--)
{
memcpy(newLeft, right, sizeof(newLeft));
F_FUNCTION(right,subKey[round]);
XOR(right, left, 32);
memcpy(left, newLeft, sizeof(left));
}
}
// 第四步:合并L16和R16,注意合并为 R16L16
for(int i=0; i<32; i++)
//cipher[63-i] = left[31-i];
cipher[i] = right[i];
for(int i=32; i<64; i++)
//cipher[63-i] = right[31-(i-32)];
cipher[i] = left[(i-32)];
// 第五步:结尾置换IP-1
for(int i=0; i<64; i++)
currentBits[i] = cipher[i];
for(int i=0; i<64; i++)
cipher[i] = currentBits[TRANS_END[i]-1];
BitToByte(Out, cipher, 8);
/********* End *********/
}