DES加密:8051实现(C语言) & FPGA实现(VHDL+NIOS II)
来源:互联网 发布:java冒泡排序算法代码 编辑:程序博客网 时间:2024/05/21 11:25
本文将利用C语言和VHDL语言分别实现DES加密,并在8051和FPGA上测试。
终于有机会阅读《深入浅出密码学一书》,趁此机会深入研究了DES加密的思想与实现。本文将分为两部分,第一部分为简单的C语言实现,第二部分为FPGA实现并在NIOS II
核上测试该模块。
DES加密的思想
DES加密的由来网络上资料非常了,这里给出wikipedia
链接: 维基百科
DES加密主要利用了两个工具
利用替换来实现混淆,如DES加密中的
S_box
,即将明文和密文之间存在的关系尽可能模糊。利用位置换来实现扩散,如DES加密中的
IP
。实现扩散之后,可以隐藏明文的统计属性,即一个明文符号的改变会涉及到多个密文符号的加密操作。
DES利用的流程为 Feistel网络
该网络主要特点为加密过程和解密过程几乎完全相同。
DES加密的C语言实现
利用C语言实现DES加密分为几个步骤:
第一步先将上文中所描述的
替换
与位置换
先实现。第二步实现
f函数
以及子密钥生成
最后实现完整的
DES加密
操作
下面分步骤实现这些部分
替换实现
替换利用C语言来实现并不复杂,可以直接用数组实现,例如 S-box
实现可以如下
for (i = 0; i < 8; i++){ e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F; e_string[i] = s[i] [e_string[i]];}
位置换实现
位置换相对就复杂,抽象出一个函数,传入置换表和置换位数。根据置换表中描述的位数查看对应位是否为1。若为1,则在输出表中将对应位置为1。
/** transpose * This function is going to use table to transpose trans_in_data into trans_out_data, * while n is the number of bit which trans_out_data have. * @Author Liu Nian, 2017 */void transpose(unsigned char *trans_in_data, unsigned char *trans_out_data, unsigned char *table, unsigned char n){ int i, bit_change; //clear trans_out_data for(i = 0; i < 8;i++) trans_out_data[i] = 0; //To transpose the bit_change bit for(i = 0; i < n;i++){ bit_change = *table++; //find the bit and check whether it is 1 if (trans_in_data[bit_change>>3] & (0x80>>(bit_change & 7))) trans_out_data[i>>3] |= (0x80>>(i & 7)); }}
f函数实现
利用上述两个方法可以实现f函数,f函数实现如下:
/** f * This function is going to mix round_key with 32-bit string. * @Author Liu Nian, 2017 */void f(unsigned char *round_key, unsigned char *in_string, unsigned char *xor_string){ unsigned char e_string[8]; int i; transpose(in_string, e_string, E_table, 64); //Use S box for confussion for (i = 0; i < 8; i++){ e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F; e_string[i] = s[i] [e_string[i]]; } transpose(e_string, xor_string, P_table, 32);}
16轮子密钥生成
子密钥生成时,还用到了另一个工具,就是1,2,9,16轮加密时,左右32-bit密钥向左轮转1位,剩余情况则轮转2位。轮转用rotate_left
函数来实现。
/** rotate_left * This function is going to make both left (32-bit) and right part of key rotate 1 bit. * @Author Liu Nian, 2017 */void rotate_left(unsigned char *key){ unsigned char str_x[8]; unsigned char i; for (i=0; i < 8; ++i) str_x[i] = key[i]; for (i=0; i < 7; ++i){ key[i] = (key[i] << 1); if ((i < 6) && ((str_x[i+1] & 128) == 128)) key[i] |= 1; } if (str_x[0] & 0x80 ) key[3] |= 0x10; else key[3] &= ~0x10; if (str_x[3] & 0x08 ) key[6] |= 0x01; else key[6] &= ~0x01;}
计算子密钥函数如下:
/** compute_subkeys * This function is going to generate sub_keys. * @Author Liu Nian, 2017 */void compute_subkeys(unsigned char *key){ unsigned char i, j, in_key[8], out_key[8]; // Store key in main_key for (i=0; i < 8; i++) main_key[i] = key[i]; // Use PC_1_table to transpose 64-bit key into 56-bit in_key transpose(key, in_key, PC_1_table, 56); //Generate sub_keys for every round for (i=0; i < 16; i++){ //For round 1,2,9,16 , key has to be rotate left 1 bit //For other rounds, key has to rotate left 2 bit for (j=0; j < round_turn[i]; j++) rotate_left(in_key); // Use PC_2_table to transpose in_key to out_key transpose(in_key, out_key, PC_2_table, 64); for (j=0; j < 8; j++) sub_keys[i][j] = out_key[j]; }}
DES加密函数
将上述模块连接起来,完整整体DES加密。
/** DES function * This function is used for DES encryption * Input parameter * unsigned char *plain_strng : pointer to 64 bits input string * unsigned char *key : pointer to 64 bits key string * unsigned char *ciph_strng : pointer to a 64 bits output string * @Author Liu Nian, 2017 */void des(unsigned char *plain_strng, unsigned char *key, unsigned char *ciph_strng){ unsigned char in_string[8], round_string[8], xor_string[8]; unsigned char i, j, *round_key, temp; // compute subkeys which will be used in every round compute_subkeys(key); // Use transpose plain_strng into in_string transpose(plain_strng, in_string, IP_table, 64); // Encrypt for 16 round for (i = 0; i < 16; i++){ // round_string is string which we will deal with in this round. for (j=0; j < 8; j++) round_string[j] = in_string[j]; // round_key is the key which will be used in this round round_key = &sub_keys[i][0]; // The first 32-bit of the next round string is the same as the last 32-bit of // this round. for (j=0; j < 4; j++) in_string[j] = round_string[j+4]; // Use f box to generate xor_string f(round_key, in_string, xor_string); // The last 32-bit of the next round string is the result of XOR between // the fist 32-bit of this round and xor_string for (j=0; j < 4; j++) in_string[j+4] = round_string[j] ^ xor_string[j]; } // change the sequence of first 32-bit and last 32-bit for (j=0; j < 4; j++) { temp = in_string[j]; in_string[j] = in_string[j+4]; in_string[j+4] = temp; } // Use IP_1_table to transpose in_string into ciph_strng transpose(in_string, ciph_strng, IP_1_table, 64);}
完整代码见附
DES加密的FPGA实现
DES加密的FPGA实现参考CoreTex Systems
公司的版本。
主要思想是利用状态机来在各个状态之间进行转移。详细代码可以参见CoreTex Systems
详细分析待后补充。
接入NIOS II核心并测试
由于NIOS II
核心只支持 32-bit
的 PIO
的外设,故输入输出拆成2个32位
端口实现。
Qsys
编辑界面如下:
在顶层图上添加DES加密模块
如下:
测试代码如下:
#include <stdio.h>#include "system.h"#include "altera_avalon_pio_regs.h"int main(){ int i = 0x0A; unsigned int key_low = 0x12341234; unsigned int key_high = 0x12341234; unsigned int data_high = 0x01020304 ; unsigned int data_low = 0x05060708; unsigned int out_low; unsigned int out_high; int des_state = 0; printf("Des_test\n"); IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,i); IOWR_ALTERA_AVALON_PIO_DATA(KEY_OUT_LOW_BASE,key_low); IOWR_ALTERA_AVALON_PIO_DATA(KEY_OUT_HIGH_BASE,key_high); IOWR_ALTERA_AVALON_PIO_DATA(DATA_OUT_HIGH_BASE,data_high); IOWR_ALTERA_AVALON_PIO_DATA(DATA_OUT_LOW_BASE,data_low); printf("Start des\n"); //密钥明文传输完成,LD_DATA置1通知DES加密元件 IOWR_ALTERA_AVALON_PIO_DATA(LD_DATA_BASE,1); //等待加密完成 des_state = IORD_ALTERA_AVALON_PIO_DATA(DES_STATE_BASE); printf("des_state:%d\n",des_state); while(des_state & 0x1 == 0){ printf("des_state:%d\n",des_state); usleep(10000); des_state = IORD_ALTERA_AVALON_PIO_DATA(DES_STATE_BASE); } //输出加密结果 out_low = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_LOW_BASE); out_high = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_HIGH_BASE); printf("%x",out_high); printf("%x",out_low); return 0;}
DES 加密C语言完整代码
#include <stdio.h>/****************************************************************************************//* Translation Table *//****************************************************************************************/xdata const unsigned char IP_table[64] ={ 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, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6};xdata const unsigned char IP_1_table[64] ={ 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, 32, 0, 40, 8, 48, 16, 56, 24};xdata const unsigned char swap[64] ={ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};xdata const unsigned char PC_1_table[56] ={ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3};xdata const unsigned char PC_2_table[64] ={ 0, 0, 13, 4, 16, 10, 23, 0, 0, 0, 2, 9, 27, 14, 5, 20, 0, 0, 22, 7, 18, 11, 3, 25, 0, 0, 15, 1, 6, 26, 19, 12, 0, 0, 40, 54, 51, 30, 36, 46, 0, 0, 29, 47, 39, 50, 44, 32, 0, 0, 43, 52, 48, 38, 55, 33, 0, 0, 45, 31, 41, 49, 35, 28};xdata const unsigned char E_table[64] ={ 0, 0, 31, 4, 0, 1, 2, 3, 0, 0, 3, 8, 4, 5, 6, 7, 0, 0, 7, 12, 8, 9, 10, 11, 0, 0, 11, 16, 12, 13, 14, 15, 0, 0, 15, 20, 16, 17, 18, 19, 0, 0, 19, 24, 20, 21, 22, 23, 0, 0, 23, 28, 24, 25, 26, 27, 0, 0, 27, 0, 28, 29, 30, 31};xdata const unsigned char P_table[32] ={ 31, 14, 39, 44, 60, 23, 55, 36, 4, 30, 46, 53, 12, 37, 62, 21, 5, 15, 47, 29, 63, 54, 6, 20, 38, 28, 61, 13, 45, 22, 7, 52};/****************************************************************************************//* S Box *//****************************************************************************************/xdata const unsigned char s[8][64] ={ { 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 }, { 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 }, { 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 }, { 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 }, { 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 }, { 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 }, { 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 }, { 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 }};xdata const unsigned char round_turn[16] ={ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};unsigned char DES_Encrypt_key[8];unsigned char DES_Decrypt_key[8];unsigned char sub_keys[16][8];unsigned char main_key[8];void des(unsigned char*, unsigned char*, unsigned char*);static void transpose (unsigned char*, unsigned char*, const unsigned char*, unsigned char);static void rotate_left (unsigned char*);static void compute_subkeys (unsigned char*);static void f (unsigned char*, unsigned char*, unsigned char*);/** DES function * This function is used for DES encryption * Input parameter * unsigned char *plain_strng : pointer to 64 bits input string * unsigned char *key : pointer to 64 bits key string * unsigned char *ciph_strng : pointer to a 64 bits output string * @Author Liu Nian, 2017 */void des(unsigned char *plain_strng, unsigned char *key, unsigned char *ciph_strng){ unsigned char in_string[8], round_string[8], xor_string[8]; unsigned char i, j, *round_key, temp; // compute subkeys which will be used in every round compute_subkeys(key); // Use transpose plain_strng into in_string transpose(plain_strng, in_string, IP_table, 64); // Encrypt for 16 round for (i = 0; i < 16; i++){ // round_string is string which we will deal with in this round. for (j=0; j < 8; j++) round_string[j] = in_string[j]; // round_key is the key which will be used in this round round_key = &sub_keys[i][0]; // The first 32-bit of the next round string is the same as the last 32-bit of // this round. for (j=0; j < 4; j++) in_string[j] = round_string[j+4]; // Use f box to generate xor_string f(round_key, in_string, xor_string); // The last 32-bit of the next round string is the result of XOR between // the fist 32-bit of this round and xor_string for (j=0; j < 4; j++) in_string[j+4] = round_string[j] ^ xor_string[j]; } // change the sequence of first 32-bit and last 32-bit for (j=0; j < 4; j++) { temp = in_string[j]; in_string[j] = in_string[j+4]; in_string[j+4] = temp; } // Use IP_1_table to transpose in_string into ciph_strng transpose(in_string, ciph_strng, IP_1_table, 64);}/** transpose * This function is going to use table to transpose trans_in_data into trans_out_data, * while n is the number of bit which trans_out_data have. * @Author Liu Nian, 2017 */void transpose(unsigned char *trans_in_data, unsigned char *trans_out_data, unsigned char *table, unsigned char n){ int i, bit_change; //clear trans_out_data for(i = 0; i < 8;i++) trans_out_data[i] = 0; //To transpose the bit_change bit for(i = 0; i < n;i++){ bit_change = *table++; //find the bit and check whether it is 1 if (trans_in_data[bit_change>>3] & (0x80>>(bit_change & 7))) trans_out_data[i>>3] |= (0x80>>(i & 7)); }}/** rotate_left * This function is going to make both left (32-bit) and right part of key rotate 1 bit. * @Author Liu Nian, 2017 */void rotate_left(unsigned char *key){ unsigned char str_x[8]; unsigned char i; for (i=0; i < 8; ++i) str_x[i] = key[i]; for (i=0; i < 7; ++i){ key[i] = (key[i] << 1); if ((i < 6) && ((str_x[i+1] & 128) == 128)) key[i] |= 1; } if (str_x[0] & 0x80 ) key[3] |= 0x10; else key[3] &= ~0x10; if (str_x[3] & 0x08 ) key[6] |= 0x01; else key[6] &= ~0x01;}/** compute_subkeys * This function is going to generate sub_keys. * @Author Liu Nian, 2017 */void compute_subkeys(unsigned char *key){ unsigned char i, j, in_key[8], out_key[8]; // Store key in main_key for (i=0; i < 8; i++) main_key[i] = key[i]; // Use PC_1_table to transpose 64-bit key into 56-bit in_key transpose(key, in_key, PC_1_table, 56); //Generate sub_keys for every round for (i=0; i < 16; i++){ //For round 1,2,9,16 , key has to be rotate left 1 bit //For other rounds, key has to rotate left 2 bit for (j=0; j < round_turn[i]; j++) rotate_left(in_key); // Use PC_2_table to transpose in_key to out_key transpose(in_key, out_key, PC_2_table, 64); for (j=0; j < 8; j++) sub_keys[i][j] = out_key[j]; }}/** f * This function is going to mix round_key with 32-bit string. * @Author Liu Nian, 2017 */void f(unsigned char *round_key, unsigned char *in_string, unsigned char *xor_string){ unsigned char e_string[8]; int i; transpose(in_string, e_string, E_table, 64); //Use S box for confussion for (i = 0; i < 8; i++){ e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F; e_string[i] = s[i] [e_string[i]]; } transpose(e_string, xor_string, P_table, 32);}
FPGA NIOSII 工程
CSDN下载频道
- DES加密:8051实现(C语言) & FPGA实现(VHDL+NIOS II)
- c语言实现des加密
- DES加密实现(c语言)
- DES加密的C语言实现
- DES(C语言实现)
- c语言实现记事本文件的 DES加密 解密
- C语言实现DES算法
- c语言des加密算法实现
- 实现FPGA Verilog HDL与NIOS II的通信数据交换——利用AVALON总线
- 用C#实现Des加密和解密
- 用C实现DES的加密
- 用C#实现Des加密和解密
- C#实现Des加密和解密
- 实现一个简单C#DES加密类
- 用C#实现Des加密和解密
- 用C#实现Des加密和解密
- des加密(c#实现)
- des加密(c#实现)
- Digital Image Processing
- VMware虚拟机系统没有声音?
- Mac上配置maven+eclipse+spark开发环境
- Linux内核学习-进程调度二
- 2017.03.18【NOIP 普及组】模拟赛C组 T4:剪草
- DES加密:8051实现(C语言) & FPGA实现(VHDL+NIOS II)
- 19. Remove Nth Node From End of List
- jzoj P1509【普及模拟】单元格
- qt制作象棋
- 491_无弹出效果dialog步骤
- 单列数据库索引的实现原理
- 数据结构与算法分析:3-4章
- Android Studio -添加你见过的最牛Log*神器*
- 字符编码总结