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-bitPIO 的外设,故输入输出拆成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下载频道

5 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高一孩子不愿意上学怎么办 专家解答 孩子不愿意上学怎么办 冬天脚冷怎么办膝盖疼 拉拉裤大了怎么办小妙招 孕37周翻身困难怎么办 晚上睡不好白天犯困怎么办 抑郁症又不想起床了怎么办 儿童憋尿功能太差怎么办 一个月的宝宝睡眠不好怎么办 被商场要求撤场怎么办 上班没法接孩子放学怎么办 幼儿下午放学与上班错开怎么办 宝宝早上醒的早怎么办 晚卜睡不着尿多怎么办 要求正常休息公司不准怎么办 我早起被室友说怎么办? 小孩晚上睡的晚怎么办 初中一年级学不扎实怎么办 一年级学生上课爱说话怎么办 孩子不按时完成作业怎么办 高三理科基础不好怎么办 字写快了就难看怎么办 高一文科280分怎么办 高三了学不进去怎么办 副职兼任法人不够条件怎么办 正职和上级不和副职怎么办 中层正职和上级不和副职怎么办 陆军军官年龄大了怎么办 ps选区选多了怎么办 香港货物被海关扣了怎么办 羽绒服棉填充物不均匀了怎么办 蛀牙到牙神经了怎么办 t恤袖子长了怎么办 t恤袖子短了怎么办 ofo突然要交押金余款怎么办 裙子的腰小了怎么办 白衬衣棉质变软怎么办? 车被自行车刮了怎么办 刮花别人的车门怎么办 破腹产九个月意外怀孕怎么办 破腹产一年半意外怀孕怎么办