2021-3-15 第五天
SM3密码杂凑算法
一、问题:
1、static const都代表什么意义,何时使用
2、ifdef _DEBUG endif 的意义与使用场景
3、如何通过函数传递一个数组?(一种方法为结构体,指针的方法上次除了首个元素外,其他元素均发生错误,原因未知)
4、unsigned int类型,如果用%u表示,就是无符号数;如果以%d显示,为何有时会变为负数?
5、如何才能更加合适地将一个函数封装为多个函数?依据是解耦和吗?
6、C++面向对象代码的编写方式(复习)
7、如何读入一串数据,以字符串的形式还是什么形式?
8、如何从文件读入一串数据?
9、如何将字符串和其他形式格式进行转换?
10、如何存储一组01比特串,如果开头有很多0,如何记录它的长度?
11、流是什么?
12、vetcor是什么?
13、如何将函数文件 头文件 主函数文件 联系起来,写成一个工程?
14、如何定义一些全局变量(特别是数组)让它的内容可以在每个函数中使用与改变。
二、C++ 流
c++的流是一种数据的载体,通过它可以实现数据交换和传输。 就像水流是一串水组成的,c++的数据流就是由一串数据组成的东西。
C++读取string对象
标准输入读取:cin>>string
忽略开头空白字符 读取至再次遇到空白字符
读取整行文本:getline(istream,string)
不忽略空白字符,读取至遇到换行符(换行符不存储在string中)
#cin和getline的区别:cin遇到空字符就停止读取,getline会读取所有元素(直到换行符)
标准输入接受字符串,进行相关处理
string s;
getline(cin,s);
stringstream ss(s); //定义string流
for(string s1;ss>>s1;cout<<s1<<endl);
输入:you are a boy 输出:①you ②are ③a ④boy
从文件读入字符串,并进行处理
#include
#include
#include
#include
ifstream fin(“test.in”); //
if(!fin)
return -1;
string s;
while(getline(fin,s)){
stringstream ss(s);
int a,b;
ss>>a;
ss>>b;
cout<<a+b<<endl;
}
三、SM3-密码杂凑算法
一)基本内容
1、
初始值IV
算法常量Tj(随j变化取不同的值)
2、
布尔函数:FFj、GGj
置换函数:P0(X)、P1(X)
二)算法描述
对长为lbit的消息m,经SM3杂凑函数后,生成256bit的杂凑
1、填充:
在长lbit的消息m后,先添加一个“1”到末尾,再添加k个“0”
k:满足l+1+k≡448(mod 512)的最小非负整数
再添加一个64位比特串:为长度l的二进制表示
填充后的消息m’的比特长度为512的倍数。
2、迭代压缩
迭代过程
填充后的m’按512bit分组:m‘=B^((0)) B((1))…B((n-1))
其中:n=(l+k+65)/512
对m’进行迭代:
FOR i=0 TO n-1
V((i+1))=CF(V((i)),B^((i)))
ENDFOR
a)其中CF是压缩函数
b)V((0))为256bit初始值IV,B((i))为填充后的消息分组
c)迭代压缩结果为V^((n))
2)消息扩展
3)压缩函数
3、杂凑值
代码实现
1、结果截图:
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define N 2
typedef struct{
unsigned int arr[100];
}Array;
unsigned int T(int j){
unsigned int result_T;
if(j>=0&&j<=15){
result_T=0x79cc4519;
}else if(j>=16&&j<=63){
result_T=0x7a879d8a;
}
else{
printf("T(j)error,please check the num of j!");
return -1;
}
return result_T;
}
unsigned int FF(int j,unsigned int X,unsigned int Y,unsigned int Z){
unsigned int result_T;
if(j>=0&&j<=15){
result_T=X^Y^Z;
}else if(j>=16&&j<=63){
result_T=(X&Y)|(X&Z)|(Y&Z);
}
else{
printf("FF(j)error,please check the num of j!");
return -1;
}
return result_T;
}
unsigned int GG(int j,unsigned int X,unsigned int Y,unsigned int Z){
unsigned int result_T;
if(j>=0&&j<=15){
result_T=X^Y^Z;
}else if(j>=16&&j<=63){
result_T=(X&Y)|(~X&Z);
}
else{
printf("GG(j)error,please check the num of j!");
return -1;
}
return result_T;
}
unsigned int mult(unsigned int num,unsigned int t){
int i;
unsigned int result=1;
for(i=0;i<t;i++){
result=result*num;
}
return result;
}
unsigned int Ring_shift_left(unsigned int input_r,unsigned num){
unsigned int result[32]={};
unsigned int temp[32]={};
unsigned int result_int=0;
int i;
unsigned int div=input_r;
for(i=0;i<32;i++){
temp[i]=div%2;
div=div/2;
}
/*
for(i=31;i>=0;i--){
printf("temp[%d]:%u\t",i,temp[i]);
}
*/
for(i=0;i<32;i++){
result[i]=temp[(i-num+32)%32];
}
for(i=0;i<32;i++){
result_int=result_int+result[i]*mult(2,i);
}
return result_int;
}
unsigned int P_0(unsigned int X){
unsigned int result_X;
result_X=X^Ring_shift_left(X,9)^Ring_shift_left(X,17);
return result_X;
}
unsigned int P_1(unsigned int X){
unsigned int result_X;
result_X=X^Ring_shift_left(X,15)^Ring_shift_left(X,23);
return result_X;
}
Array Compression(int i,Array V,Array W,Array W_1){
unsigned int SS1,SS2,TT1,TT2;
unsigned int A,B,C,D,E,F,G,H;
int j;
A=V.arr[0];
B=V.arr[1];
C=V.arr[2];
D=V.arr[3];
E=V.arr[4];
F=V.arr[5];
G=V.arr[6];
H=V.arr[7];
Array V_i;
printf("\n\n第%d次杂凑:\n",i+1);
for(j=0;j<64;j++){
SS1=Ring_shift_left((Ring_shift_left(A,12)+E+(Ring_shift_left(T(j),j%32))),7);
SS2=SS1^Ring_shift_left(A,12);
TT1=FF(j,A,B,C)+D+SS2+W_1.arr[j];
TT2=GG(j,E,F,G)+H+SS1+W.arr[j];
D=C;
C=Ring_shift_left(B,9);
B=A;
A=TT1;
H=G;
G=Ring_shift_left(F,19);
F=E;
E=P_0(TT2);
printf("第%d轮:",j);
printf("A:%x\t",A);
printf("B:%x\t",B);
printf("C:%x\t",C);
printf("D:%x\t",D);
printf("E:%x\t",E);
printf("F:%x\t",F);
printf("G:%x\t",G);
printf("H:%x\t",H);
printf("\n");
}
V_i.arr[0]=A^V.arr[0];
V_i.arr[1]=B^V.arr[1];
V_i.arr[2]=C^V.arr[2];
V_i.arr[3]=D^V.arr[3];
V_i.arr[4]=E^V.arr[4];
V_i.arr[5]=F^V.arr[5];
V_i.arr[6]=G^V.arr[6];
V_i.arr[7]=H^V.arr[7];
return V_i;
}
unsigned int Input_Algorithm(){
unsigned int info;
unsigned int fill_info;
printf("Please input a 3 length message that you want Hash:");
scanf("%x",&info);
fill_info=info*mult(2,8)+0x80;
return fill_info;
}
Array W_Extend(){
Array W;
int j;
unsigned int temp_W;
W.arr[0]=Input_Algorithm();
for(j=1;j<15;j++){
W.arr[j]=0;
}
W.arr[15]=0x18;
for(j=16;j<68;j++){
temp_W=W.arr[j-16]^W.arr[j-9]^(Ring_shift_left(W.arr[j-3],15));
W.arr[j]=P_1(temp_W)^(Ring_shift_left(W.arr[j-13],7))^W.arr[j-6];
//printf("W[%d]:%x\t",j,W.arr[j]);
}
return W;
}
Array W1_Extend(Array W){
Array W_1;
int j;
for(j=0;j<64;j++){
W_1.arr[j]=W.arr[j]^W.arr[j+4];
//printf("W'[%d]:%x\t",j,W_1.arr[j]);
}
return W_1;
}
Array V0_Init(){
Array V_0;
V_0.arr[0]=0x7380166f;
V_0.arr[1]=0x4914b2b9;
V_0.arr[2]=0x172442d7;
V_0.arr[3]=0xda8a0600;
V_0.arr[4]=0xa96f30bc;
V_0.arr[5]=0x163138aa;
V_0.arr[6]=0xe38dee4d;
V_0.arr[7]=0xb0fb0e4e;
return V_0;
}
void V_output(int i,Array V){
int j;
printf("V[%d]",i);
for(j=0;j<8;j++){
printf("%x ",V.arr[j]);
}
}
///主函数
int main()
{
///声明
Array W,W_1;
Array V[64];
int i,j;
///初始化
W=W_Extend();
W_1=W1_Extend(W);
V[0]=V0_Init();
///进行N次哈希
for(i=0;i<N;i++){
V_output(i,V[i]);
V[i+1]=Compression(i,V[i],W,W_1);
}
return 0;
}