SM3.java
public class SM3 {
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<B.length; i++)
{
System.out.print(Integer.toHexString(B[i])+" ");
}
System.out.println("");
System.out.println("");*/
int[][] arr = expand(B);
int[] w = arr[0];
int[] w1 = arr[1];
/*System.out.println("扩展后的消息: ");
System.out.println("W0W1...W67");
print(w);
System.out.println("");
System.out.println("W'0W'1...W'67");
print(w1);
System.out.println("迭代压缩中间值: ");*/
for (int j = 0; j < 64; j++)
{
ss1 = (bitCycleLeft(a, 12) + e + bitCycleLeft(Tj[j], j));
ss1 = bitCycleLeft(ss1, 7);
ss2 = ss1 ^ bitCycleLeft(a, 12);
tt1 = FFj(a, b, c, j) + d + ss2 + w1[j];
tt2 = GGj(e, f, g, j) + h + ss1 + w[j];
d = c;
c = bitCycleLeft(b, 9);
b = a;
a = tt1;
h = g;
g = bitCycleLeft(f, 19);
f = e;
e = P0(tt2);
/*System.out.print(j+" ");
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("");
int[] out = new int[8];
out[0] = a ^ V[0];
out[1] = b ^ V[1];
out[2] = c ^ V[2];
out[3] = d ^ V[3];
out[4] = e ^ V[4];
out[5] = f ^ V[5];
out[6] = g ^ V[6];
out[7] = h ^ V[7];
return out;
}
private static int[][] expand(int[] B)
{
int W[] = new int[68];
int W1[] = new int[64];
for (int i = 0; i < B.length; i++)
{
W[i] = B[i];
}
for (int i = 16; i < 68; i++)
{
W[i] = P1(W[i - 16] ^ W[i - 9] ^ bitCycleLeft(W[i - 3], 15))
^ bitCycleLeft(W[i - 13], 7) ^ W[i - 6];
}
for (int i = 0; i < 64; i++)
{
W1[i] = W[i] ^ W[i + 4];
}
int arr[][] = new int[][] { W, W1 };
return arr;
}
private static byte[] bigEndianIntToByte(int num)
{
return back(Util.intToBytes(num));
}
private static int bigEndianByteToInt(byte[] bytes)
{
return Util.byteToInt(back(bytes));
}
private static int FFj(int X, int Y, int Z, int j)
{
if (j >= 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)
{