package com.shensu.sm;
/*
* SM3 & SM4 (Java)脱坑版
*
* **** 不要直接使用此文件,使用 SMUtils 里的封装即可。****
*
* 苏州沈苏自动化技术开发有限公司(金苗部),于 2019-01-02。邮箱:delphi2006@163.com
*/
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];
int[][] arr = expand(B);
int[] w = arr[0];
int[] w1 = arr[1];
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);
}
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;
}
/**
* 整形转换成网络传输的字节流(字节数组)型数据
*
* @param num 一个整型数据
* @return 4个字节的自己数组
*/
public static byte[] intToBytes(int num) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (0xff & (num >> 0));
bytes[1] = (byte) (0xff & (num >> 8));
bytes[2] = (byte) (0xff & (num >> 16));
bytes[3] = (byte) (0xff & (num >> 24));
return bytes;
}
private static byte[] bigEndianIntToByte(int num) {
return back(intToBytes(num));
}
/**
* 四个字节的字节数据转换成一个整形数据
*
* @param bytes 4个字节的字节数组
* @return 一个整型数据
*/
public static int byteToInt(byte[] bytes) {
int num = 0;
int temp;
temp = (0x000000ff & (bytes[0])) << 0;
num = num | temp;
temp = (0x000000ff & (bytes[1])) << 8;
num = num | temp;
temp = (0x000000ff & (bytes[2])) << 16;
num = num | temp;
temp = (0x000000ff & (bytes[3])) << 24;
num = num | temp;
return num;
}
private static int bigEndianByteToInt(byte[] bytes) {
return 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) {
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;
}
/**
* 长整形转换成网络传输的字节流(字节数组)型数据
*
* @param num 一个长整型数据
* @return 4个字节的自己数组
*/
public static byte[] longToBytes(long num) {
byte[] bytes = new byte[8];
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) (0xff & (num >> (i * 8)));
}
return bytes;
}
/**
* 对最后一个分组字节数据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(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;
}
public class SM3Digest {
/** SM3值的长度 */
private static final int BYTE_LENGTH = 32;
/** SM3分组长度 */
private static final int BLOCK_LENGTH = 64;
/** 缓冲区长度 */
private static final int BUFFER_LENGTH = BLOCK_LENGTH * 1;
/** 缓冲区 */
private byte[] xBuf = new byte[BUFFER_LENGTH];
/** 缓冲区偏移量 */
private int xBufOff;
/** 初始向量 */
private byte[] V = SM3.iv.clone();
private int cntBlock = 0;
public SM3Digest() {
}
public SM3Digest(SM3Digest t) {
System.arraycopy(t.xBuf, 0, this.xBu
Java SM3&SM4; 脱坑版
需积分: 11 196 浏览量
2019-01-02
13:26:53
上传
评论 2
收藏 8KB RAR 举报
delphi2006
- 粉丝: 4
- 资源: 3
最新资源
- TFS(淘宝分布式存储引擎代码
- 海尔H42E10 6i981BTA DH1PY600000 MBOOT usb.bin 程序.zip
- 网盘的功能实现之数据库搭建笔记
- 软件工程与软件测试阶段作业三.doc
- 软件工程中的人工智能辅助设计研究.pptx
- 海尔智能电视刷机数据 H42E07 机编DH1QR000H07 务必确认机编一致 强制刷机 整机USB升级主程序
- 4444444444444444444
- 基于PHP实现响应式创业园区管委会网站.zip
- 安卓手机用作电脑网络摄像头的工具文件
- 海尔智能电视刷机数据 H32E10 机编DH1QX000805 务必确认机编一致 强制刷机 整机USB升级主程序
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈