sm3算法

 


sm3算法c语言实现

/*
 
  2017.9.24 am 10:00 -11:50
  2017.9.24 pm 14:00-17:00 19:00-23:00
  2017.9.25 pm 14:00-17:30

*/
#include <stdio.h>
#include <string.h>
#include <math.h>
unsigned int w0[70],w1[70];//用于压缩函数cf
//0-8用来表示A-H
unsigned int memory[8]={0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e};
unsigned int memory1[8]={0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e};
unsigned int T[64]={0};

//将四个字符压缩成1个32位的整数存储
unsigned int chars_unit32(unsigned int n,char b[],int i)
{
 (n) =    (  (unsigned int) (b)[(i)    ] << 24 )       
        | ( (unsigned int) (b)[(i) + 1] << 16 )       
        | ( (unsigned int) (b)[(i) + 2] <<  8 )       
        | ( (unsigned int) (b)[(i) + 3]       );   
 return n;
}

//将1个32位的整数存储扩展位四个字符
void unit32_chars(unsigned int n,char b[],int i)
{
   b[i  ] =  (char) ((n)>>24);
   b[i+1] =  (char) ((n)>>16);
   b[i+2] =  (char) ((n)>>8 );
   b[i+3] =  (char) ((n)    );

}

//将n循环左移m位
unsigned int Rol(unsigned int n,int m)
{
 n=((n)<<m)|(n>>(32-m));
 return n;

}
//P0函数
unsigned int P0(unsigned int x)
{
    x=x^Rol(x,9)^Rol(x,17);
 return x;

}
//p1函数
unsigned int  P1(unsigned int x)
{
 x=x^Rol(x,15)^Rol(x,23);
 return x;

}

//填充

//len1表示mes数组的长度
 //len2表示消息的bit数 eg:b="abc",则mes[0]=0x616263,len2=24
void full(unsigned int mes[],unsigned int len1,unsigned int len2)
{
// printf("\nlen1=%d len2=%d\n",len1,len2);
  
 if((len2%32)!=0)
    mes[len1-1]=mes[len1-1]|(1<<(32-len2%32-1));
 else
       mes[len1]=mes[len1]|(1<<(32-len2%32-1));
 mes[15+(len2/512)*16]=mes[15+(len2/256)*16]+len2;

}
//消息扩展
void extends(unsigned int w0[],unsigned int w1[],unsigned int mes[])
{
 int i;
 for(i=0;i<16;i++)
  w0[i]=mes[i];
 for(i=16;i<68;i++)
 {
  w0[i]=P1(w0[i-16]^w0[i-9]^Rol(w0[i-3],15))^Rol(w0[i-13],7)^w0[i-6];
  
 }
 printf("扩展后的消息:\n");
 printf("W[0]-W[67]:\n");

    for(i=0;i<68;i++)
 {
  printf("%08x ",w0[i]);
     if((i+1)%8==0)
   printf("\n");
 }
 for(i=0;i<64;i++)
  w1[i]=w0[i]^w0[i+4];
    printf("\nW'[0]-W'[63]:\n");

    for(i=0;i<64;i++)
 {
  printf("%08x ",w1[i]);
     if((i+1)%8==0)
   printf("\n");
 }
}
//FF函数
unsigned int FF(unsigned int  x,unsigned int y,unsigned int z,int j)
{
 
 if(j>=0&&j<=15)
    return (x^y^z);
 else if(j>=16&&j<=63)
  return ((x&y)|(x&z)|(y&z));

}

//GG
unsigned int GG(unsigned int x,unsigned int y,unsigned int z,int j)
{
 
 if(j>=0&&j<=15)
    return (x^y^z);
 else if(j>=16&&j<=63)
  return ((x&y)|((~(x))&z));
}

void cf(unsigned int memory[],unsigned int w0[],unsigned int w1[])
{

 int j,i;
 unsigned int ss1,ss2,tt1,tt2;
 for(j=0;j<=63;j++)
 {
  ss1 = Rol(Rol(memory[0],12)+memory[4]+Rol(T[j],j),7);
 // printf("ss1=%08x ",ss1);
  ss2 = ss1^Rol(memory[0],12);
  tt1 = FF(memory[0],memory[1],memory[2],j)+memory[3]+ss2+w1[j];
  tt2 = GG(memory[4],memory[5],memory[6],j)+memory[7]+ss1+w0[j];
  memory[3] = memory[2];
  memory[2] = Rol(memory[1],9);
  memory[1] = memory[0];
  memory[0] = tt1;
  memory[7] = memory[6];
  memory[6] = Rol(memory[5],19);
  memory[5] = memory[4];
  memory[4] = P0(tt2);
   printf("\n");
    printf("%2d %08x",j,memory[0]);

 for(i=1;i<8;i++)
  printf(" %08x",memory[i]);
  printf("\n");
 }
 

}
int main()
{
    //b用来接受输入的字符串
 //n用来表示循环左移的位数
 //mes用来表示输入数据的ascii码值 eg:b="abc",则mes[0]=0x616263
 //len表示b长度
 //len1表示mes数组的长度
 //len2表示消息的bit数 eg:b="abc",则mes[0]=0x616263,len2=24
 FILE * fp1,*fp2;
 char * b;
 unsigned int n,mes[500],len,len1,len2;
 int i,j;
 if((fp1=fopen("input.txt","r"))==NULL)
 {
  printf("cannot open input.txt\n");
  return 0;
 }
    freopen("output.txt","w",stdout);
    fseek(fp1,0,SEEK_END);
 len=ftell(fp1);
 b= new char[len+1];//定义数组的长度

 rewind(fp1);//把指针移到文件的开头
 fgets(b,len+1,fp1);
 //b[len]='/0';//把文件的最后一位写为0
 printf("输入消息为:\n");
 printf("%s\n",b);
 len2=len*8;
 memset(mes,0,sizeof(mes));
 memset(w0,0,sizeof(w0));
 memset(w1,0,sizeof(w1));
    j=0;
 for(i=0;i<len;i=i+4,j++)
 {
  mes[j]= chars_unit32(mes[j],b,i);
 }
 len1=j;
 printf("其ASCII码为:\n");
    for(i=0;i<len1;i++)
  printf("%x",mes[i]);

 full(mes,len1,len2);
 printf("\n填充后的消息\n");

 for(i=0;i<16+(len2/512)*16;i++)
 {
  printf("%08x ",mes[i]);
     if((i+1)%8==0)
   printf("\n");
 }
 
 for(int k=0;k<(len2/512)+1;k++)
 {

  printf("第%d个分组\n",k+1);
     extends(w0,w1,mes+(k*16));
 
  printf("迭代压缩中间值\n");
  printf("j     A        B        C        D        E        F        G        H   \n");
  printf("   %08x %08x %08x %08x %08x %08x %08x %08x\n",memory[0],memory[1],memory[2],memory[3],memory[4],memory[5],memory[6],memory[7]);
  for(j=0;j<=15;j++)
   T[j]=0x79cc4519;
  for(j=16;j<=63;j++)
   T[j]=0x7a879d8a;
 
   cf(memory,w0,w1);
 
          for(i=0;i<8;i++)
   {
    memory[i]=memory[i]^memory1[i];
     memory1[i]= memory[i];
   }
     

    
 
 }
   printf("杂凑值:\n");
 for( i=0;i<8;i++)
  printf("%8x  ",memory[i]);
 printf("\n");
 fclose(fp1);
 return 0;
}

   


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中的SM3算法是一种密码学哈希函数,用于生成消息摘要。它是中国国家密码管理局发布的一种国家标准算法,适用于数字签名、身份认证等安全领域。 SM3算法的特点如下: 1. 输入和输出都是256位(32字节)的消息摘要。 2. 具有较高的安全性和抗碰撞能力,能够有效防止碰撞攻击。 3. 算法设计简洁,运算速度较快。 在Java中使用SM3算法,可以通过Java的安全包`java.security`中的`MessageDigest`类来实现。以下是使用Java实现SM3算法的示例代码: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SM3Example { public static void main(String[] args) { String message = "Hello, SM3!"; try { // 创建MessageDigest对象并指定算法为"SM3" MessageDigest md = MessageDigest.getInstance("SM3"); // 将消息转换为字节数组 byte[] messageBytes = message.getBytes(); // 计算消息摘要 byte[] digest = md.digest(messageBytes); // 将摘要转换为十六进制字符串 StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } System.out.println("Message: " + message); System.out.println("Digest: " + sb.toString()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } } ``` 以上代码中,首先创建了一个`MessageDigest`对象,并指定算法为"SM3"。然后将待计算摘要的消息转换为字节数组,通过调用`digest`方法计算消息摘要。最后将摘要转换为十六进制字符串进行展示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值