SM3的实现(java和c)

目录

  • java实现SM3源码
  • SM3官方实现(C语言)
    • SM3_h文件
    • SM3_c文件
    • 免责声明

java实现SM3源码

import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;//写到最后用FileReader读中文会出乱码,发现编码格式为"GBK",将其改为"UTF-8"后中文注释和button按钮的中文显示都成了乱码.
class Demo{				//代码中乱码的地方原为中文注释,因改编码格式变成乱码
	JFrame frame;
	JLabel labelZhaiYao,labelMingWen,labelDaoRu;
	JButton buttonCreate,buttonReset,buttonDaoRu,buttonDaoChu,buttonMingWen;
	JTextArea textAreaMingWen,textAreaZhaiYao,textAreaDaoRu;
	JScrollPane jspMingWen,jspZhaiYao,jspDaoRu;
	JPanel buttonPanel;
	JPanel panel1,panel2,panel3,panel10,panel20,panel30,panellk,panelrk;
	Demo(){
		frame=new JFrame("SM3");
		buttonCreate=new JButton("生成摘要");
		buttonReset=new JButton("重置");
		buttonDaoRu=new JButton("导入摘要");
		buttonDaoChu=new JButton("导出摘要");
		buttonMingWen=new JButton("导入明文");
		labelZhaiYao=new JLabel("摘要:");
		labelMingWen=new JLabel("明文:");
		labelDaoRu=new JLabel("导入的摘要:");
		textAreaMingWen=new JTextArea(10,10);
		textAreaZhaiYao=new JTextArea(10,10);
		textAreaDaoRu=new JTextArea(10,10);
		buttonPanel=new JPanel();
		panel1=new JPanel();
		panel2=new JPanel();
		panel3=new JPanel();
		panel10=new JPanel();
		panel20=new JPanel();
		panel30=new JPanel();
		panellk=new JPanel();
		panelrk=new JPanel();
		//
		frame.setLayout(new BorderLayout());
		//buttonPanel:
		buttonPanel.setLayout(new FlowLayout());
		buttonPanel.add(buttonReset);
		buttonPanel.add(buttonMingWen);
		buttonPanel.add(buttonCreate);
		buttonPanel.add(buttonDaoRu);
		buttonPanel.add(buttonDaoChu);
		frame.add(BorderLayout.NORTH,buttonPanel);
		//textArea:
		textAreaMingWen.setLineWrap(true);
		textAreaZhaiYao.setLineWrap(true);
		textAreaDaoRu.setLineWrap(true);
		textAreaDaoRu.setEditable(false);
		textAreaZhaiYao.setEditable(false);
		jspMingWen=new JScrollPane(textAreaMingWen);
		jspZhaiYao=new JScrollPane(textAreaZhaiYao);
		jspDaoRu=new JScrollPane(textAreaDaoRu);
		panel10.setLayout(new BorderLayout());
		panel10.add(BorderLayout.NORTH,labelDaoRu);
		panel10.add(BorderLayout.CENTER,jspDaoRu);
		panel1.setLayout(new BorderLayout());
		panel1.add(BorderLayout.NORTH,panel10);
		//panel3
		panel3.setLayout(new BorderLayout());
		panel30.setLayout(new BorderLayout());
		panel30.add(BorderLayout.NORTH,labelMingWen);
		panel30.add(BorderLayout.CENTER,jspMingWen);
		panel3.add(BorderLayout.NORTH,panel30);
		//panel2:
		panel20.setLayout(new BorderLayout());
		panel20.add(BorderLayout.NORTH,labelZhaiYao);
		panel20.add(BorderLayout.CENTER,jspZhaiYao);
		panel2.setLayout(new BorderLayout());
		panel2.add(BorderLayout.NORTH,panel20);
		panel2.add(BorderLayout.CENTER,panel3);
		panel1.add(BorderLayout.CENTER,panel2);
		frame.add(BorderLayout.CENTER,panel1);
		frame.add(BorderLayout.SOUTH,panellk);
		frame.add(BorderLayout.EAST,panelrk);
		frame.setSize(1200,900);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//
		buttonCreate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {		
					String happy=new String(textAreaMingWen.getText());
					textAreaZhaiYao.setText("\""+happy+"\"生成的摘要为:\n"+SM3.byteArrayToHexString(SM3.hash(happy.getBytes())));
				}catch(IOException ioe) {
					ioe.printStackTrace();
				}
			}
		});
		buttonReset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				textAreaMingWen.setText("");
				textAreaZhaiYao.setText("");
				textAreaDaoRu.setText("");
			}
		});
		buttonMingWen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					textAreaMingWen.setText("");
					JFileChooser chooser=new JFileChooser("D:\\杂货\\SM3");
					chooser.showOpenDialog(null);
					File file=chooser.getSelectedFile();
					FileReader fr=new FileReader(file);
					char ch;
					for(int i=0;fr.ready();i++) {
						ch=(char) (fr.read());
						textAreaMingWen.append(String.valueOf(ch));
					}
					textAreaZhaiYao.setText("");
					fr.close();
					
				}catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		buttonDaoRu.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				try {
					JFileChooser chooser=new JFileChooser("D:\\杂货\\SM3");
					chooser.showOpenDialog(null);
					File file=chooser.getSelectedFile();
					FileReader fr=new FileReader(file);
					char ch;
					for(int i=0;fr.ready();i++) {
						ch=(char)fr.read();
						textAreaDaoRu.append(String.valueOf(ch));
					}
					textAreaDaoRu.append("\n");
					fr.close();
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		buttonDaoChu.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					JFileChooser chooser=new JFileChooser("D:\\杂货\\SM3");
					chooser.showOpenDialog(null);
					File file=chooser.getSelectedFile();
					FileWriter fw=new FileWriter(file);
					String s=textAreaZhaiYao.getText();
					fw.write(s);
					System.out.println(s);
//					fw.write("happy");
					fw.close();
				}catch(Exception ex) {
					ex.printStackTrace();
				}
			}
		});
		
	}	
}
class SM3{
	//常量与函数
private static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E','F' };
private static final String ivHexStr = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e";
private static final BigInteger IV = new BigInteger(ivHexStr.replaceAll(" ", ""), 16);
private static final Integer Tj15 = Integer.valueOf("79cc4519", 16);
private static final Integer Tj63 = Integer.valueOf("7a879d8a", 16);
private static final byte[] FirstPadding = { (byte) 0x80 };//1000 0000
private static final byte[] ZeroPadding = { (byte) 0x00 };//0000 0000

private static int T(int j) {
	if (j >= 0 && j <= 15) {
		return Tj15.intValue();
	} else if (j >= 16 && j <= 63) {
		return Tj63.intValue();
	} else {
		throw new RuntimeException("data invalid");
	}
}

private static Integer FF(Integer x, Integer y, Integer z, int j) {
	if (j >= 0 && j <= 15) {
		return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
	} else if (j >= 16 && j <= 63) {
		return Integer.valueOf(
				(x.intValue() & y.intValue()) | (x.intValue() & z.intValue()) | (y.intValue() & z.intValue()));
	} else {
		throw new RuntimeException("data invalid");
	}
}

private static Integer GG(Integer x, Integer y, Integer z, int j) {
	if (j >= 0 && j <= 15) {
		return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
	} else if (j >= 16 && j <= 63) {
		return Integer.valueOf((x.intValue() & y.intValue()) | (~x.intValue() & z.intValue()));
	} else {
		throw new RuntimeException("data invalid");
	}
}

private static Integer P0(Integer x) {
	return Integer.valueOf(x.intValue() ^ Integer.rotateLeft(x.intValue(), 9) ^ Integer.rotateLeft(x.intValue(), 17));
}

private static Integer P1(Integer x) {
	return Integer.valueOf(x.intValue() ^ Integer.rotateLeft(x.intValue(), 15) ^ Integer.rotateLeft(x.intValue(), 23));
}
//填充并附加消息长度
private static byte[] padding(byte[] source) throws IOException {
	long l = source.length * 8;//消息字节*8bit
	long k = 448 - (l) % 512;
	if (k <= 0) 
		k = k + 512;
	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	baos.write(source);
	baos.write(FirstPadding);//写入1000 0000
	long i = k - 8;
	while (i > 0) {
		baos.write(ZeroPadding);
		i -= 8;
	}
	baos.write(long2bytes(l));//将消息长度变成byte[]再写入
	return baos.toByteArray();//返回byte数组
}

private static byte[] long2bytes(long l) {
	byte[] bytes = new byte[8];
	for (int i = 0; i < 8; i++) {
		bytes[i] = (byte) (l >>> ((7 - i) * 8));
	}
	return bytes;
}
//hash
public static byte[] hash(byte[] source) throws IOException {
	byte[] m1 = padding(source);
	int n = m1.length / (512 / 8);//512bit每组,组数
	byte[] b;
	byte[] vi = IV.toByteArray();//TV��һ��bigInteger,ת��ΪByteArray
	byte[] vi1 = null;
	for (int i = 0; i < n; i++) {
		b = Arrays.copyOfRange(m1, i * 64, (i + 1) * 64);//左闭右开,拷贝m1 8B
		vi1 = CF(vi, b);
		vi = vi1;//不这么写就会出错,也不知道错在哪里
	}
	return vi1;
}
private static byte[] CF(byte[] vi, byte[] bi) throws IOException {//vi256b,bi512b
	int a, b, c, d, e, f, g, h;
	a = toInteger(vi, 0);//取32bit,4个字节呗
	b = toInteger(vi, 1);
	c = toInteger(vi, 2);
	d = toInteger(vi, 3);
	e = toInteger(vi, 4);
	f = toInteger(vi, 5);
	g = toInteger(vi, 6);
	h = toInteger(vi, 7);
//����Ϣ����b������Ϣ��չ�õ�W[0-67]W1[0-63]
	int[] w = new int[68];
	int[] w1 = new int[64];
	for (int i = 0; i < 16; i++) {
		w[i] = toInteger(bi, i);
	}
	for (int j = 16; j < 68; j++) {
		w[j] = P1(w[j - 16] ^ w[j - 9] ^ Integer.rotateLeft(w[j - 3], 15)) ^ Integer.rotateLeft(w[j - 13], 7)^ w[j - 6];
	}
	for (int j = 0; j < 64; j++) {
		w1[j] = w[j] ^ w[j + 4];
	}
//ѹ������
	int ss1, ss2, tt1, tt2;
	for (int j = 0; j < 64; j++) {
		ss1 = Integer.rotateLeft(Integer.rotateLeft(a, 12) + e + Integer.rotateLeft(T(j), j), 7);
		ss2 = ss1 ^ Integer.rotateLeft(a, 12);
		tt1 = FF(a, b, c, j) + d + ss2 + w1[j];
		tt2 = GG(e, f, g, j) + h + ss1 + w[j];
		d = c;
		c = Integer.rotateLeft(b, 9);
		b = a;
		a = tt1;
		h = g;
		g = Integer.rotateLeft(f, 19);
		f = e;
		e = P0(tt2);
	}//ԭ��Ϊ������ѵ�,û�뵽�������˳����.ֽ��̸������ȡ��.
	byte[] v = toByteArray(a, b, c, d, e, f, g, h);//abcdefgh�ϲ�����
	for (int i = 0; i < v.length; i++) {
		v[i] = (byte) (v[i] ^ vi[i]);
	}
	return v;
}
//从source中取4bit,即32位
private static int toInteger(byte[] source, int index) {
	StringBuilder valueStr = new StringBuilder("");
	for (int i = 0; i < 4; i++) {//eg:AB
		valueStr.append(hexDigits[(byte) ((source[index * 4 + i] & 0xF0) >> 4)]);//高四位转hex
		valueStr.append(hexDigits[(byte) (source[index * 4 + i] & 0x0F)]);///第四位转Hex
	}
	return Long.valueOf(valueStr.toString(), 16).intValue();

}

private static byte[] toByteArray(int a, int b, int c, int d, int e, int f, int g, int h) throws IOException {
	ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
	baos.write(toByteArray(a));
	baos.write(toByteArray(b));
	baos.write(toByteArray(c));
	baos.write(toByteArray(d));
	baos.write(toByteArray(e));
	baos.write(toByteArray(f));
	baos.write(toByteArray(g));
	baos.write(toByteArray(h));
	return baos.toByteArray();
}

public static byte[] toByteArray(int i) {
	byte[] byteArray = new byte[4];
	byteArray[0] = (byte) (i >>> 24);
	byteArray[1] = (byte) ((i & 0xFFFFFF) >>> 16);//�߰��ֽ���0
	byteArray[2] = (byte) ((i & 0xFFFF) >>> 8);
	byteArray[3] = (byte) (i & 0xFF);
	return byteArray;
}

private static String byteToHexString(byte b) {
	int n = b;
	if (n < 0)
		n = 256 + n;
	int d1 = n / 16;
	int d2 = n % 16;
	return "" + hexDigits[d1] + hexDigits[d2];
}

public static String byteArrayToHexString(byte[] b) {
	StringBuffer resultSb = new StringBuffer();
	for (int i = 0; i < b.length; i++) {
		resultSb.append(byteToHexString(b[i]));
	}
	return resultSb.toString();
	}
}
public class happy {
	public static void main(String[]args) throws IOException {
		new Demo();
	}
}

SM3官方实现(C语言)

SM3_h文件

/************************************************************************
 FileName:
 SM3.h
 Version:
 SM3_V1.1
 Date:
 Sep 18,2016
 Description:
 This headfile provide macro defination, parameter definition
and function declaration needed in SM3 algorithm implement
 Function List:
 1.SM3_256 //calls SM3_init, SM3_process and SM3_done to calculate hash value
 2.SM3_init //init the SM3 state
 3.SM3_process //compress the the first len/64 blocks of the message
 4.SM3_done //compress the rest message and output the hash value
 5.SM3_compress //called by SM3_process and SM3_done, compress a single block of message
 6.BiToW //called by SM3_compress,to calculate W from Bi
 7.WToW1 //called by SM3_compress, calculate W' from W
 8.CF //called by SM3_compress, to calculate CF function.
 9.BigEndian //called by SM3_compress and SM3_done.GM/T 0004-2012 requires to use
big-endian.
 //if CPU uses little-endian, BigEndian function is a necessary call to
change the
 //little-endian format into big-endian format.
 10.SM3_SelfTest //test whether the SM3 calculation is correct by comparing the hash result
with the standard data
 History:
 1. Date: Sep 18,2016
 Author: Mao Yingying, Huo Lili
 Modification: 1)add notes to all the functions
 2)add SM3_SelfTest function
************************************************************************/
#include 
#define SM3_len 256
#define SM3_T1 0x79CC4519
#define SM3_T2 0x7A879D8A
#define SM3_IVA 0x7380166f
#define SM3_IVB 0x4914b2b9
#define SM3_IVC 0x172442d7
#define SM3_IVD 0xda8a0600
#define SM3_IVE 0xa96f30bc
#define SM3_IVF 0x163138aa
#define SM3_IVG 0xe38dee4d
#define SM3_IVH 0xb0fb0e4e
/* Various logical functions */
#define SM3_p1(x) (x^SM3_rotl32(x,15)^SM3_rotl32(x,23))
#define SM3_p0(x) (x^SM3_rotl32(x,9)^SM3_rotl32(x,17))
#define SM3_ff0(a,b,c) (a^b^c)
#define SM3_ff1(a,b,c) ((a&b)|(a&c)|(b&c))
#define SM3_gg0(e,f,g) (e^f^g)
#define SM3_gg1(e,f,g) ((e&f)|((~e)&g))
#define SM3_rotl32(x,n) ((((unsigned int) x) << n) | (((unsigned int) x) >> (32 - n)))
#define SM3_rotr32(x,n) ((((unsigned int) x) >> n) | (((unsigned int) x) << (32 - n)))
typedef struct {
 unsigned int state[8];
 unsigned int length;
 unsigned int curlen;
 unsigned char buf[64];
} SM3_STATE;
void BiToWj(unsigned int Bi[], unsigned int Wj[]);
void WjToWj1(unsigned int Wj[], unsigned int Wj1[]);
void CF(unsigned int Wj[], unsigned int Wj1[], unsigned int V[]);
void BigEndian(unsigned char src[], unsigned int bytelen, unsigned char des[]);
void SM3_init(SM3_STATE *md);
void SM3_compress(SM3_STATE * md);
void SM3_process(SM3_STATE * md, unsigned char buf[], int len);
void SM3_done(SM3_STATE *md, unsigned char *hash);
void SM3_256(unsigned char buf[], int len, unsigned char hash[]);
int SM3_SelfTest();

SM3_c文件

/************************************************************************
 File name: SM3.c
 Version: SM3_V1.1
 Date: Sep 18,2016
 Description: to calculate a hash message from a given message
 Function List:
 1.SM3_256 //calls SM3_init, SM3_process and SM3_done to calculate hash value
 2.SM3_init //init the SM3 state
 3.SM3_process //compress the the first len/64 blocks of the message
 4.SM3_done //compress the rest message and output the hash value
 5.SM3_compress //called by SM3_process and SM3_done, compress a single block of message
 6.BiToW //called by SM3_compress,to calculate W from Bi
 7.WToW1 //called by SM3_compress, calculate W1 from W
 8.CF //called by SM3_compress, to calculate CF function.
 9.BigEndian //called by SM3_compress and SM3_done.GM/T 0004-2012 requires to use
big-endian.
 //if CPU uses little-endian, BigEndian function is a necessary call to
change the
 //little-endian format into big-endian format.
 10.SM3_SelfTest //test whether the SM3 calculation is correct by comparing the hash result
with the standard result
 History:
 1. Date: Sep 18,2016
 Author: Mao Yingying, Huo Lili
 Modification: 1)add notes to all the functions
 2)add SM3_SelfTest function
**************************************************************************/
#include "SM3.h"
/****************************************************************
 Function: BiToW
 Description: calculate W from Bi
 Calls:
 Called By: SM3_compress
 Input: Bi[16] //a block of a message
Output: W[64]
 Return: null
 Others:
****************************************************************/
void BiToW(unsigned int Bi[], unsigned int W[])
{
 int i;
 unsigned int tmp;
 for(i=0;i<=15;i++)
 {
 W[i]=Bi[i];
 }
 for(i=16;i<=67;i++)
 {
 tmp=W[i-16]
 ^ W[i-9]
 ^ SM3_rotl32(W[i-3],15);
 W[i]=SM3_p1(tmp)
 ^ (SM3_rotl32(W[i-13],7))
 ^ W[i-6];
 }
}
/*****************************************************************
 Function: WToW1
 Description: calculate W1 from W
 Calls:
 Called By: SM3_compress
 Input: W[64]
 Output: W1[64]
 Return: null
 Others:
*****************************************************************/
void WToW1(unsigned int W[], unsigned int W1[])
{
 int i;
 for(i=0;i<=63;i++)
 {
 W1[i]=W[i]^W[i+4];
 }
}
/******************************************************************
 Function: CF
 Description: calculate the CF compress function and update V
 Calls:
 Called By: SM3_compress
 Input: W[64]
 W1[64]
 V[8]
 Output: V[8]
 Return: null
 Others:
********************************************************************/
void CF(unsigned int W[], unsigned int W1[], unsigned int V[])
{
unsigned int SS1;
unsigned int SS2;
unsigned int TT1;
unsigned int TT2;
unsigned int A,B,C,D,E,F,G,H;
unsigned int T=SM3_T1;
unsigned int FF;
unsigned int GG;
int j;
//reg init,set ABCDEFGH=V0
A=V[0];
B=V[1];
C=V[2];
D=V[3];
E=V[4];
F=V[5];
G=V[6];
H=V[7];
for(j=0;j<=63;j++)
 {
 //SS1
 if(j==0)
 {
 T=SM3_T1;
 }
 else if(j==16)
 {
 T=SM3_rotl32(SM3_T2,16);
 }
 else
 {
 T=SM3_rotl32(T,1);
 }
 SS1=SM3_rotl32((SM3_rotl32(A,12)+E+T),7);
 //SS2
 SS2=SS1^SM3_rotl32(A,12);
 //TT1
 if(j<=15)
 {
 FF=SM3_ff0(A,B,C);
 }
 else
 {
 FF=SM3_ff1(A,B,C);
 }
 TT1=FF+D+SS2+*W1;
 W1++;
 //TT2
 if(j<=15)
 {
 GG=SM3_gg0(E,F,G);
 }
 else
 {
 GG=SM3_gg1(E,F,G);
 }
 TT2=GG+H+SS1+*W;
 W++;
 //D
 D=C;
 //C
 C=SM3_rotl32(B,9);
 //B
 B=A;
 //A
 A=TT1;
 //H
 H=G;
 //G
 G=SM3_rotl32(F,19);
 //F
 F=E;
 //E
 E=SM3_p0(TT2);
 }
 //update V
 V[0]=A^V[0];
 V[1]=B^V[1];
 V[2]=C^V[2];
 V[3]=D^V[3];
 V[4]=E^V[4];
 V[5]=F^V[5];
 V[6]=G^V[6];
 V[7]=H^V[7];
}
/******************************************************************************
 Function: BigEndian
 Description: U32 endian converse.GM/T 0004-2012 requires to use big-endian.
 if CPU uses little-endian, BigEndian function is a necessary
 call to change the little-endian format into big-endian format.
 Calls:
 Called By: SM3_compress, SM3_done
 Input: src[bytelen]
 bytelen
 Output: des[bytelen]
 Return: null
 Others: src and des could implies the same address
*******************************************************************************/
void BigEndian(unsigned char src[], unsigned int bytelen, unsigned char des[])
{
 unsigned char tmp = 0;
 unsigned int i = 0;
 for(i=0; i<bytelen/4; i++)
 {
 tmp = des[4*i];
 des[4*i] = src[4*i+3];
 src[4*i+3] = tmp;
 tmp = des[4*i+1];
 des[4*i+1] = src[4*i+2];
 des[4*i+2] = tmp;
 }
}
/******************************************************************************
 Function: SM3_init
 Description: initiate SM3 state
 Calls:
 Called By: SM3_256
 Input: SM3_STATE *md
 Output: SM3_STATE *md
 Return: null
 Others:
*******************************************************************************/
void SM3_init(SM3_STATE *md)
{
 md->curlen = md->length = 0;
 md->state[0] = SM3_IVA;
 md->state[1] = SM3_IVB;
 md->state[2] = SM3_IVC;
 md->state[3] = SM3_IVD;
 md->state[4] = SM3_IVE;
 md->state[5] = SM3_IVF;
 md->state[6] = SM3_IVG;
 md->state[7] = SM3_IVH;
}
/******************************************************************************
 Function: SM3_compress
 Description: compress a single block of message
 Calls: BigEndian
 BiToW
 WToW1
 CF
 Called By: SM3_256
 Input: SM3_STATE *md
 Output: SM3_STATE *md
 Return: null
 Others:
*******************************************************************************/
void SM3_compress(SM3_STATE * md)
{
 unsigned int W[68];
 unsigned int W1[64];
 //if CPU uses little-endian, BigEndian function is a necessary call
 BigEndian(md->buf, 64, md->buf);
 BiToW((unsigned int *)md->buf,W);
 WToW1(W,W1);
 CF(W, W1, md->state);
}
/******************************************************************************
 Function: SM3_process
 Description: compress the first (len/64) blocks of message
 Calls: SM3_compress
 Called By: SM3_256
 Input: SM3_STATE *md
 unsigned char buf[len] //the input message
 int len //bytelen of message
 Output: SM3_STATE *md
 Return: null
 Others:
*******************************************************************************/
void SM3_process(SM3_STATE * md, unsigned char *buf, int len)
{
 while (len--)
 {
 /* copy byte */
 md->buf[md->curlen] = *buf++;
 md->curlen++;
 /* is 64 bytes full? */
 if (md->curlen == 64)
 {
 SM3_compress(md);
 md->length += 512;
 md->curlen = 0;
 }
 }
}
/******************************************************************************
 Function: SM3_done
 Description: compress the rest message that the SM3_process has left behind
 Calls: SM3_compress
 Called By: SM3_256
 Input: SM3_STATE *md
 Output: unsigned char *hash
 Return: null
 Others:
*******************************************************************************/
void SM3_done(SM3_STATE *md, unsigned char hash[])
{
 int i;
 unsigned char tmp = 0;
 /* increase the bit length of the message */
 md->length += md->curlen <<3;
 /* append the '1' bit */
 md->buf[md->curlen] = 0x80;
 md->curlen++;
 /* if the length is currently above 56 bytes, appends zeros till
 it reaches 64 bytes, compress the current block, creat a new
 block by appending zeros and length,and then compress it
 */
 if (md->curlen >56)
 {
 for (; md->curlen < 64;)
 {
 md->buf[md->curlen] = 0;
 md->curlen++;
 }
 SM3_compress(md);
 md->curlen = 0;
 }
 /* if the length is less than 56 bytes, pad upto 56 bytes of zeroes */
 for (; md->curlen < 56;)
 {
 md->buf[md->curlen] = 0;
 md->curlen++;
 }
 /* since all messages are under 2^32 bits we mark the top bits zero */
 for (i = 56; i < 60; i++)
 {
 md->buf[i] = 0;
 }
 /* append length */
 md->buf[63] = md->length & 0xff;
 md->buf[62] = (md->length >> 8) & 0xff;
 md->buf[61] = (md->length >> 16) & 0xff;
 md->buf[60] = (md->length >> 24) & 0xff;
 SM3_compress(md);
 /* copy output */
 memcpy(hash,md->state,SM3_len/8);
 BigEndian(hash,SM3_len/8,hash);//if CPU uses little-endian, BigEndian function is a
necessary call
}
/******************************************************************************
 Function: SM3_256
 Description: calculate a hash value from a given message
 Calls: SM3_init
 SM3_process
 SM3_done
 Called By:
 Input: unsigned char buf[len] //the input message
 int len //bytelen of the message
 Output: unsigned char hash[32]
 Return: null
 Others:
*******************************************************************************/
void SM3_256(unsigned char buf[], int len, unsigned char hash[])
{
 SM3_STATE md;
 SM3_init(&md);
 SM3_process(&md, buf, len);
 SM3_done(&md, hash);
}
/******************************************************************************
 Function: SM3_SelfTest
 Description: test whether the SM3 calculation is correct by comparing
 the hash result with the standard result
 Calls: SM3_256
 Called By:
 Input: null
 Output: null
 Return: 0 //the SM3 operation is correct
 1 //the sm3 operation is wrong
 Others:
*******************************************************************************/
int SM3_SelfTest()
{
 unsigned int i=0,a=1,b=1;
 unsigned char Msg1[3]={0x61,0x62,0x63};
 int MsgLen1=3;
 unsigned char MsgHash1[32]={0};
 unsigned char
StdHash1[32]={0x66,0xC7,0xF0,0xF4,0x62,0xEE,0xED,0xD9,0xD1,0xF2,0xD4,0x6B,0xDC,0x10,0xE4,0xE
2,

0x41,0x67,0xC4,0x87,0x5C,0xF2,0xF7,0xA2,0x29,0x7D,0xA0,0x2B,0x8F,0x4B,0xA8,0xE0};
 unsigned char
Msg2[64]={0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,

0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,

0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,

0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64,0x61,0x62,0x63,0x64};
 int MsgLen2=64;
 unsigned char MsgHash2[32]={0};
 unsigned char
StdHash2[32]={0xde,0xbe,0x9f,0xf9,0x22,0x75,0xb8,0xa1,0x38,0x60,0x48,0x89,0xc1,0x8e,0x5a,0x4
d,

0x6f,0xdb,0x70,0xe5,0x38,0x7e,0x57,0x65,0x29,0x3d,0xcb,0xa3,0x9c,0x0c,0x57,0x32};
 SM3_256(Msg1,MsgLen1,MsgHash1);
 SM3_256(Msg2,MsgLen2,MsgHash2);
 a=memcmp(MsgHash1,StdHash1,SM3_len/8);
 b=memcmp(MsgHash2,StdHash2,SM3_len/8);
 if ((a==0) && (b==0))
 {
 return 0;
 }
 else
 {
 return 1;
 }
}

免责声明

本网站发布的程序源代码仅供有关单位作密码应用开发验证、系
统升级改造核验等工作的验证参考,任何组织和个人不得使用相关程
序源代码进行商业开发或从事任何非法活动。
本网站发布的程序源代码不承诺代码运行效率及实现安全性,任
何组织和个人因使用相关程序源代码造成信息传递或传送失误、代码
瑕疵或错误、开发的产品或系统性能及安全性可靠性缺失等任何问题
或任何损失的,程序源代码提供单位不承担任何直接或间接责任。
本网站发布的部分算法实现代码使用了 MIRACL,MIRACL 是
来源于网络的开源库资源,仅限用于非商业应用。任何组织或个人因
私自使用 MIRACL 用于商业开发,触犯相关单位知识产权或经济利
益的,程序源代码提供单位不承担任何直接或间接责任。

你可能感兴趣的:(密码学)