本次博文以前面的两次文章的函数定义、说明为基础进行扩展。
并且参考了一些其他的优秀博客文章,比如KDF局部密钥派生函数的使用、十六进制字符串与二进制字符串以及普通字符串转换函数(自己也编写了一部分函数)、SM3杂凑签名算法(太懒了,完全拿来用了,取其精华,感谢博客主人)。
完成本次实验前,进一步了解了C语言,这种直接面对内存进行操作的语言真的既让人爱又让人恨……
然后,介绍一下我实现本算法的大概思路:从文件读入等待加密的明文,然后以二进制字符串形式(字符数组,定义了很多中间变量,做好准备吧)构造密文,中间还涉及十六进制形式的字符串,因为我需要把字符串转成16进制再转成二进制,并且中间有很多操作也和十六进制形式有关。
最后,强调一下定义的这些函数都是对字符数组进行,然后把结果填充到另一个指定地址去,这种思想伴随了整个程序中……
sm3头文件代码(参考与网址 https://blog.csdn.net/a344288106/ article/details/80094878 ):
1 #include <stdio.h> 2 #include <memory.h> 3 #ifndef _SM3_H_ 4 #define _SM3_H_ 5 6 /* 7 * SM3算法产生的哈希值大小(单位:字节) 8 */ 9 #define SM3_HASH_SIZE 32 10 11 /* 12 * SM3上下文 13 */ 14 typedef struct SM3Context 15 { 16 unsigned int intermediateHash[SM3_HASH_SIZE / 4]; 17 unsigned char messageBlock[64]; 18 } SM3Context; 19 20 /* 21 * SM3计算函数 22 */ 23 unsigned char *SM3Calc(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]); 24 25 #endif // _SM3_H_ 26 /* 27 * 判断运行环境是否为小端 28 */ 29 static const int endianTest = 1; 30 #define IsLittleEndian() (*(char *)&endianTest == 1) 31 32 /* 33 * 向左循环移位 34 */ 35 #define LeftRotate(word, bits) ( (word) << (bits) | (word) >> (32 - (bits)) ) 36 37 /* 38 * 反转四字节整型字节序 39 */ 40 unsigned int *ReverseWord(unsigned int *word) 41 { 42 unsigned char *byte, temp; 43 44 byte = (unsigned char *)word; 45 temp = byte[0]; 46 byte[0] = byte[3]; 47 byte[3] = temp; 48 49 temp = byte[1]; 50 byte[1] = byte[2]; 51 byte[2] = temp; 52 return word; 53 } 54 55 /* 56 * T 57 */ 58 unsigned int T(int i) 59 { 60 if (i >= 0 && i <= 15) 61 return 0x79CC4519; 62 else if (i >= 16 && i <= 63) 63 return 0x7A879D8A; 64 else 65 return 0; 66 } 67 68 /* 69 * FF 70 */ 71 unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i) 72 { 73 if (i >= 0 && i <= 15) 74 return X ^ Y ^ Z; 75 else if (i >= 16 && i <= 63) 76 return (X & Y) | (X & Z) | (Y & Z); 77 else 78 return 0; 79 } 80 81 /* 82 * GG 83 */ 84 unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i) 85 { 86 if (i >= 0 && i <= 15) 87 return X ^ Y ^ Z; 88 else if (i >= 16 && i <= 63) 89 return (X & Y) | (~X & Z); 90 else 91 return 0; 92 } 93 94 /* 95 * P0 96 */ 97 unsigned int P0(unsigned int X) 98 { 99 return X ^ LeftRotate(X, 9) ^ LeftRotate(X, 17); 100 } 101 102 /* 103 * P1 104 */ 105 unsigned int P1(unsigned int X) 106 { 107 return X ^ LeftRotate(X, 15) ^ LeftRotate(X, 23); 108 } 109 110 /* 111 * 初始化函数 112 */ 113 void SM3Init(SM3Context *context) 114 { 115 context->intermediateHash[0] = 0x7380166F; 116 context->intermediateHash[1] = 0x4914B2B9; 117 context->intermediateHash[2] = 0x172442D7; 118 context->intermediateHash[3] = 0xDA8A0600; 119 context->intermediateHash[4] = 0xA96F30BC; 120 context->intermediateHash[5] = 0x163138AA; 121 context->intermediateHash[6] = 0xE38DEE4D; 122 context->intermediateHash[7] = 0xB0FB0E4E; 123 } 124 125 /* 126 * 处理消息块 127 */