All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bcos.web3j.crypto.sm3.SM3 Maven / Gradle / Ivy

There is a newer version: 2.6.6
Show newest version
package org.bcos.web3j.crypto.sm3;

public class SM3
{
	/*public static final byte[] iv = { 0x2C, (byte) 0x91, (byte) 0xB4, 0x01,
			(byte) 0xFC, 0x64, (byte) 0xB2, (byte) 0xCE, 0x7C, 0x4E,
			(byte) 0xAE, (byte) 0xFB, (byte) 0xB1, 0x3B, (byte) 0xB6,
			(byte) 0xD3, 0x17, 0x60, (byte) 0xB6, 0x35, (byte) 0xF3, 0x6F,
			0x13, (byte) 0xEB, (byte) 0xC8, 0x77, (byte) 0xE9, (byte) 0xA0,
			(byte) 0xC2, 0x76, (byte) 0xA8, 0x17 };*/

	public 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, 0x0e,
		0x4e };
	
	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;
		}
	}

	public static byte[] CF(byte[] V, byte[] B) 
	{
		int[] v, b;
		v = convert(V);
		b = convert(B);
		return convert(CF(v, b));
	}

	private static int[] convert(byte[] arr)
	{
		int[] out = new int[arr.length / 4];
		byte[] tmp = new byte[4];
		for (int i = 0; i < arr.length; i += 4) 
		{
			System.arraycopy(arr, i, tmp, 0, 4);
			out[i / 4] = bigEndianByteToInt(tmp);
		}
		return out;
	}

	private static byte[] convert(int[] arr) 
	{
		byte[] out = new byte[arr.length * 4];
		byte[] tmp = null;
		for (int i = 0; i < arr.length; i++) 
		{
			tmp = bigEndianIntToByte(arr[i]);
			System.arraycopy(tmp, 0, out, i * 4, 4);
		}
		return out;
	}

	public static int[] CF(int[] V, int[] B) 
	{
		int a, b, c, d, e, f, g, h;
		int ss1, ss2, tt1, tt2;
		a = V[0];
		b = V[1];
		c = V[2];
		d = V[3];
		e = V[4];
		f = V[5];
		g = V[6];
		h = V[7];
		
		/*System.out.println("IV: "); 
		System.out.print(Integer.toHexString(a)+" ");
		System.out.print(Integer.toHexString(b)+" ");
		System.out.print(Integer.toHexString(c)+" ");
		System.out.print(Integer.toHexString(d)+" ");
		System.out.print(Integer.toHexString(e)+" ");
		System.out.print(Integer.toHexString(f)+" ");
		System.out.print(Integer.toHexString(g)+" ");
		System.out.print(Integer.toHexString(h)+" "); 
		System.out.println("");
		System.out.println("");
		 
		System.out.println("填充后的消息: "); 
		for(int i=0; i= 0 && j <= 15) 
		{
			return FF1j(X, Y, Z);
		}
		else 
		{
			return FF2j(X, Y, Z);
		}
	}

	private static int GGj(int X, int Y, int Z, int j) 
	{
		if (j >= 0 && j <= 15) 
		{
			return GG1j(X, Y, Z);
		}
		else
		{
			return GG2j(X, Y, Z);
		}
	}

	// 逻辑位运算函数
	private static int FF1j(int X, int Y, int Z)
	{
		int tmp = X ^ Y ^ Z;
		return tmp;
	}

	private static int FF2j(int X, int Y, int Z)
	{
		int tmp = ((X & Y) | (X & Z) | (Y & Z));
		return tmp;
	}

	private static int GG1j(int X, int Y, int Z) 
	{
		int tmp = X ^ Y ^ Z;
		return tmp;
	}

	private static int GG2j(int X, int Y, int Z) 
	{
		int tmp = (X & Y) | (~X & Z);
		return tmp;
	}

	private static int P0(int X) 
	{
		int y = rotateLeft(X, 9);
		y = bitCycleLeft(X, 9);
		int z = rotateLeft(X, 17);
		z = bitCycleLeft(X, 17);
		int t = X ^ y ^ z;
		return t;
	}

	private static int P1(int X) 
	{
		int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23);
		return t;
	}

	/**
	 * 对最后一个分组字节数据padding
	 * 
	 * @param in
	 * @param bLen
	 *            分组个数
	 * @return
	 */
	public static byte[] padding(byte[] in, int bLen)
	{
		int k = 448 - (8 * in.length + 1) % 512;
		if (k < 0) 
		{
			k = 960 - (8 * in.length + 1) % 512;
		}
		k += 1;
		byte[] padd = new byte[k / 8];
		padd[0] = (byte) 0x80;
		long n = in.length * 8 + bLen * 512;
		byte[] out = new byte[in.length + k / 8 + 64 / 8];
		int pos = 0;
		System.arraycopy(in, 0, out, 0, in.length);
		pos += in.length;
		System.arraycopy(padd, 0, out, pos, padd.length);
		pos += padd.length;
		byte[] tmp = back(Util.longToBytes(n));
		System.arraycopy(tmp, 0, out, pos, tmp.length);
		return out;
	}

	/**
	 * 字节数组逆序
	 * 
	 * @param in
	 * @return
	 */
	private static byte[] back(byte[] in) 
	{
		byte[] out = new byte[in.length];
		for (int i = 0; i < out.length; i++) 
		{
			out[i] = in[out.length - i - 1];
		}

		return out;
	}

	public static int rotateLeft(int x, int n) 
	{
		return (x << n) | (x >> (32 - n));
	}

	private static int bitCycleLeft(int n, int bitLen) 
	{
		bitLen %= 32;
		byte[] tmp = bigEndianIntToByte(n);
		int byteLen = bitLen / 8;
		int len = bitLen % 8;
		if (byteLen > 0)
		{
			tmp = byteCycleLeft(tmp, byteLen);
		}

		if (len > 0) 
		{
			tmp = bitSmall8CycleLeft(tmp, len);
		}

		return bigEndianByteToInt(tmp);
	}

	private static byte[] bitSmall8CycleLeft(byte[] in, int len) 
	{
		byte[] tmp = new byte[in.length];
		int t1, t2, t3;
		for (int i = 0; i < tmp.length; i++)
		{
			t1 = (byte) ((in[i] & 0x000000ff) << len);
			t2 = (byte) ((in[(i + 1) % tmp.length] & 0x000000ff) >> (8 - len));
			t3 = (byte) (t1 | t2);
			tmp[i] = (byte) t3;
		}

		return tmp;
	}

	private static byte[] byteCycleLeft(byte[] in, int byteLen) 
	{
		byte[] tmp = new byte[in.length];
		System.arraycopy(in, byteLen, tmp, 0, in.length - byteLen);
		System.arraycopy(in, 0, tmp, in.length - byteLen, byteLen);
		return tmp;
	}
	
	/*private static void print(int[] arr)
	{
		for (int i = 0; i < arr.length; i++)
		{
			System.out.print(Integer.toHexString(arr[i]) + " ");
			if ((i + 1) % 16 == 0) 
			{
				System.out.println();
			}
		}
		System.out.println();
	}*/
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy