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();
}
}
/************************************************************************
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();
/************************************************************************
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 用于商业开发,触犯相关单位知识产权或经济利
益的,程序源代码提供单位不承担任何直接或间接责任。