SM3国密算法标准中两个实例的实现

来源于CSDN博客:https://blog.csdn.net/ErErFei/article/details/50998162
代码新增内容:在原博客的基础上,整合了各个类的方法,同时增添了SM3国密标准中的第二个案例的验证,并尝试将原代码中的缓冲区长度修改为64*2,本代码作者是在命令行里面运行通过的。如有运行问题,请各位能够反馈,互相学习;

public class ren_SM3
{
/**IV为256比特初始值,32个字节,修饰为静态最终变量,不可改变,比如0x80值(128)范围超过byte表示范围(-128~127),所以需要强制转换*/
private static final byte[] IV = { 0x73, (byte)0x80, 0x16, 0x6f, 0x49, 0x14, (byte) 0xb2, (byte) 0xb9, 0x17, 0x24, 0x42, (byte) 0xd7, (byte) 0xda, (byte) 0x8a, 0x06, 0x00, (byte) 0xa9, 0x6f, 0x30, (byte) 0xbc, (byte) 0x16, 0x31, 0x38, (byte) 0xaa, (byte) 0xe3, (byte) 0x8d, (byte) 0xee, 0x4d, (byte) 0xb0, (byte)0xfb, (byte)0x0e, 0x4e };

/**由于IV不可改变,而在64次迭代过程中需要一个不断改变的V,所以重新定义一个。*/
private byte[] V= IV.clone();

/** SM3分组长度 */
private static final int BLOCK_LENGTH = 64;

/** 缓冲区长度 */
private static final int BUFFER_LENGTH = BLOCK_LENGTH * 2;

/*缓冲区偏移量*/
private int xBufOff;

/*缓冲区,缓冲区长度是64,这个缓冲区指的什么?指的明文进入内存后,算法中要求需要将消息进行512比特分组,
然后对每组进行迭代,由于对消息原文是不能有改变的,所以需要将分组后的消息进行复制一份。*/
private byte[] xBuf = new byte[BUFFER_LENGTH];

private int cntBlock = 0;//用于记录明文分组的个数,计算消息长度时需要用到。

public static int[] Tj = new int[64];
 
static
{
    for (int i = 0; i < 16; i++)
    {
        Tj[i] = 0x79cc4519;
    }
 
    for (int i = 16; i < 64; i++)
    {
        Tj[i] = 0x7a879d8a;
    }
}
/*
*@param in明文输入缓冲区
*@param inOff明文输入缓冲区偏移量
*@param len明文输入长度
*/
public void update(byte[] in,int inOff)
{
	
	int inputLen = in.length;//明文的长度
	int dPos = inOff;//明文输入缓冲区偏移量,一开始是0
	if(BUFFER_LENGTHBUFFER_LENGTH)
		{
			System.arraycopy(in,dPos,xBuf,0,BUFFER_LENGTH);
			inputLen = inputLen - BUFFER_LENGTH;
			dPos = dPos+BUFFER_LENGTH;
			doUpdate();
		}
	}
	if(inputLen>0)
	{
		System.arraycopy(in,dPos,xBuf,0,inputLen);
		xBufOff = inputLen;
	}
}
public void doUpdate()//将缓冲区的内容复制到一份新的字节数组中。然后对字节数组作用。
{
	byte [] B = new byte[BLOCK_LENGTH];
	for(int i=0;i0)
	{
		tmp = byteCycleLeft(tmp,byteLen);
	}
	if(len>0)
	{
		tmp = bitSmall8CycleLeft(tmp,len);
	}
	return bigEndianByteToInt(tmp);
}
public byte[] bigEndianIntToByte(int n)
{
	byte[] tmp = new byte[4];
	tmp[3] = (byte)(n>>0);
	tmp[2] = (byte)(n>>8);
	tmp[1] = (byte)(n>>16);
	tmp[0] = (byte)(n>>24);
	return tmp;
}	
public byte[] byteCycleLeft(byte[] in,int n)
{
	byte[] tmp = new byte[in.length];
    System.arraycopy(in, n, tmp, 0, in.length - n);
    System.arraycopy(in, 0, tmp, in.length - n, n);
    return tmp;
}
public byte[] bitSmall8CycleLeft(byte[] in,int n)
{
	byte[] tmp = new byte[in.length];
	int t1, t2, t3;
	for(int j=0;j>(8-n));
		t3 = (byte)(t1|t2);
		tmp[j]=(byte)t3;
	}
	return tmp;
}
public int FFj(int a,int b ,int c,int j)
{
	if(j>=0&&j<=15)
	{
		return a^b^c;
	}
	else
	{
		return (a&b)|(a&c)|(b&c);
	}
}
public int GGj(int a,int b ,int c,int j)
{
	if(j>=0&&j<=15)
	{
		return a^b^c;
	}
	else
	{
		return (a&b)|(~a&c);
	}
}
public int P0(int a)
{
	int tmp = a^bitCycleLeft(a,9)^bitCycleLeft(a,17);
	return tmp;
}
public int P1(int a)
{
	int tmp = a^bitCycleLeft(a,15)^bitCycleLeft(a,23);
	return tmp;
}
public byte[] convert(int[] v)
{
	byte[] out = new byte[v.length*4];
	int[] in = new int[v.length];
	for(int i=0;i>0);
		out[4*i+2] = (byte)(in[i]>>8);
		out[4*i+1] = (byte)(in[i]>>16);
		out[4*i+0] = (byte)(in[i]>>24);
	}
	return out;
}
public byte[] doFinal()
{
	byte[] B= new byte[BLOCK_LENGTH];
	byte[] buffer = new byte[xBufOff];
	System.arraycopy(xBuf,0,buffer,0,buffer.length);
	byte[] tmp = padding(buffer,cntBlock);
	for(int i=0;i>(i*8)));
	}
	return bytes;
}
public String getHexString(byte[] bt)
{
	String str = "";
	for(int i = 0;i

}

你可能感兴趣的:(SM3国密算法标准中两个实例的实现)