SM3.java 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. package com.security.cipher.sm;
  2. public class SM3
  3. {
  4. /*public static final byte[] iv = { 0x2C, (byte) 0x91, (byte) 0xB4, 0x01,
  5. (byte) 0xFC, 0x64, (byte) 0xB2, (byte) 0xCE, 0x7C, 0x4E,
  6. (byte) 0xAE, (byte) 0xFB, (byte) 0xB1, 0x3B, (byte) 0xB6,
  7. (byte) 0xD3, 0x17, 0x60, (byte) 0xB6, 0x35, (byte) 0xF3, 0x6F,
  8. 0x13, (byte) 0xEB, (byte) 0xC8, 0x77, (byte) 0xE9, (byte) 0xA0,
  9. (byte) 0xC2, 0x76, (byte) 0xA8, 0x17 };*/
  10. public static final byte[] iv = { 0x73, (byte) 0x80, 0x16, 0x6f, 0x49,
  11. 0x14, (byte) 0xb2, (byte) 0xb9, 0x17, 0x24, 0x42, (byte) 0xd7,
  12. (byte) 0xda, (byte) 0x8a, 0x06, 0x00, (byte) 0xa9, 0x6f, 0x30,
  13. (byte) 0xbc, (byte) 0x16, 0x31, 0x38, (byte) 0xaa, (byte) 0xe3,
  14. (byte) 0x8d, (byte) 0xee, 0x4d, (byte) 0xb0, (byte) 0xfb, 0x0e,
  15. 0x4e };
  16. public static int[] Tj = new int[64];
  17. static
  18. {
  19. for (int i = 0; i < 16; i++)
  20. {
  21. Tj[i] = 0x79cc4519;
  22. }
  23. for (int i = 16; i < 64; i++)
  24. {
  25. Tj[i] = 0x7a879d8a;
  26. }
  27. }
  28. public static byte[] CF(byte[] V, byte[] B)
  29. {
  30. int[] v, b;
  31. v = convert(V);
  32. b = convert(B);
  33. return convert(CF(v, b));
  34. }
  35. private static int[] convert(byte[] arr)
  36. {
  37. int[] out = new int[arr.length / 4];
  38. byte[] tmp = new byte[4];
  39. for (int i = 0; i < arr.length; i += 4)
  40. {
  41. System.arraycopy(arr, i, tmp, 0, 4);
  42. out[i / 4] = bigEndianByteToInt(tmp);
  43. }
  44. return out;
  45. }
  46. private static byte[] convert(int[] arr)
  47. {
  48. byte[] out = new byte[arr.length * 4];
  49. byte[] tmp = null;
  50. for (int i = 0; i < arr.length; i++)
  51. {
  52. tmp = bigEndianIntToByte(arr[i]);
  53. System.arraycopy(tmp, 0, out, i * 4, 4);
  54. }
  55. return out;
  56. }
  57. public static int[] CF(int[] V, int[] B)
  58. {
  59. int a, b, c, d, e, f, g, h;
  60. int ss1, ss2, tt1, tt2;
  61. a = V[0];
  62. b = V[1];
  63. c = V[2];
  64. d = V[3];
  65. e = V[4];
  66. f = V[5];
  67. g = V[6];
  68. h = V[7];
  69. /*System.out.println("IV: ");
  70. System.out.print(Integer.toHexString(a)+" ");
  71. System.out.print(Integer.toHexString(b)+" ");
  72. System.out.print(Integer.toHexString(c)+" ");
  73. System.out.print(Integer.toHexString(d)+" ");
  74. System.out.print(Integer.toHexString(e)+" ");
  75. System.out.print(Integer.toHexString(f)+" ");
  76. System.out.print(Integer.toHexString(g)+" ");
  77. System.out.print(Integer.toHexString(h)+" ");
  78. System.out.println("");
  79. System.out.println("");
  80. System.out.println("填充后的消息: ");
  81. for(int i=0; i<B.length; i++)
  82. {
  83. System.out.print(Integer.toHexString(B[i])+" ");
  84. }
  85. System.out.println("");
  86. System.out.println("");*/
  87. int[][] arr = expand(B);
  88. int[] w = arr[0];
  89. int[] w1 = arr[1];
  90. /*System.out.println("扩展后的消息: ");
  91. System.out.println("W0W1...W67");
  92. print(w);
  93. System.out.println("");
  94. System.out.println("W'0W'1...W'67");
  95. print(w1);
  96. System.out.println("迭代压缩中间值: ");*/
  97. for (int j = 0; j < 64; j++)
  98. {
  99. ss1 = (bitCycleLeft(a, 12) + e + bitCycleLeft(Tj[j], j));
  100. ss1 = bitCycleLeft(ss1, 7);
  101. ss2 = ss1 ^ bitCycleLeft(a, 12);
  102. tt1 = FFj(a, b, c, j) + d + ss2 + w1[j];
  103. tt2 = GGj(e, f, g, j) + h + ss1 + w[j];
  104. d = c;
  105. c = bitCycleLeft(b, 9);
  106. b = a;
  107. a = tt1;
  108. h = g;
  109. g = bitCycleLeft(f, 19);
  110. f = e;
  111. e = P0(tt2);
  112. /*System.out.print(j+" ");
  113. System.out.print(Integer.toHexString(a)+" ");
  114. System.out.print(Integer.toHexString(b)+" ");
  115. System.out.print(Integer.toHexString(c)+" ");
  116. System.out.print(Integer.toHexString(d)+" ");
  117. System.out.print(Integer.toHexString(e)+" ");
  118. System.out.print(Integer.toHexString(f)+" ");
  119. System.out.print(Integer.toHexString(g)+" ");
  120. System.out.print(Integer.toHexString(h)+" ");
  121. System.out.println("");*/
  122. }
  123. // System.out.println("");
  124. int[] out = new int[8];
  125. out[0] = a ^ V[0];
  126. out[1] = b ^ V[1];
  127. out[2] = c ^ V[2];
  128. out[3] = d ^ V[3];
  129. out[4] = e ^ V[4];
  130. out[5] = f ^ V[5];
  131. out[6] = g ^ V[6];
  132. out[7] = h ^ V[7];
  133. return out;
  134. }
  135. private static int[][] expand(int[] B)
  136. {
  137. int W[] = new int[68];
  138. int W1[] = new int[64];
  139. for (int i = 0; i < B.length; i++)
  140. {
  141. W[i] = B[i];
  142. }
  143. for (int i = 16; i < 68; i++)
  144. {
  145. W[i] = P1(W[i - 16] ^ W[i - 9] ^ bitCycleLeft(W[i - 3], 15))
  146. ^ bitCycleLeft(W[i - 13], 7) ^ W[i - 6];
  147. }
  148. for (int i = 0; i < 64; i++)
  149. {
  150. W1[i] = W[i] ^ W[i + 4];
  151. }
  152. int arr[][] = new int[][] { W, W1 };
  153. return arr;
  154. }
  155. private static byte[] bigEndianIntToByte(int num)
  156. {
  157. return back(Util.intToBytes(num));
  158. }
  159. private static int bigEndianByteToInt(byte[] bytes)
  160. {
  161. return Util.byteToInt(back(bytes));
  162. }
  163. private static int FFj(int X, int Y, int Z, int j)
  164. {
  165. if (j >= 0 && j <= 15)
  166. {
  167. return FF1j(X, Y, Z);
  168. }
  169. else
  170. {
  171. return FF2j(X, Y, Z);
  172. }
  173. }
  174. private static int GGj(int X, int Y, int Z, int j)
  175. {
  176. if (j >= 0 && j <= 15)
  177. {
  178. return GG1j(X, Y, Z);
  179. }
  180. else
  181. {
  182. return GG2j(X, Y, Z);
  183. }
  184. }
  185. // 逻辑位运算函数
  186. private static int FF1j(int X, int Y, int Z)
  187. {
  188. int tmp = X ^ Y ^ Z;
  189. return tmp;
  190. }
  191. private static int FF2j(int X, int Y, int Z)
  192. {
  193. int tmp = ((X & Y) | (X & Z) | (Y & Z));
  194. return tmp;
  195. }
  196. private static int GG1j(int X, int Y, int Z)
  197. {
  198. int tmp = X ^ Y ^ Z;
  199. return tmp;
  200. }
  201. private static int GG2j(int X, int Y, int Z)
  202. {
  203. int tmp = (X & Y) | (~X & Z);
  204. return tmp;
  205. }
  206. private static int P0(int X)
  207. {
  208. int y = rotateLeft(X, 9);
  209. y = bitCycleLeft(X, 9);
  210. int z = rotateLeft(X, 17);
  211. z = bitCycleLeft(X, 17);
  212. int t = X ^ y ^ z;
  213. return t;
  214. }
  215. private static int P1(int X)
  216. {
  217. int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23);
  218. return t;
  219. }
  220. /**
  221. * 对最后一个分组字节数据padding
  222. *
  223. * @param in
  224. * @param bLen
  225. * 分组个数
  226. * @return
  227. */
  228. public static byte[] padding(byte[] in, int bLen)
  229. {
  230. int k = 448 - (8 * in.length + 1) % 512;
  231. if (k < 0)
  232. {
  233. k = 960 - (8 * in.length + 1) % 512;
  234. }
  235. k += 1;
  236. byte[] padd = new byte[k / 8];
  237. padd[0] = (byte) 0x80;
  238. long n = in.length * 8 + bLen * 512;
  239. byte[] out = new byte[in.length + k / 8 + 64 / 8];
  240. int pos = 0;
  241. System.arraycopy(in, 0, out, 0, in.length);
  242. pos += in.length;
  243. System.arraycopy(padd, 0, out, pos, padd.length);
  244. pos += padd.length;
  245. byte[] tmp = back(Util.longToBytes(n));
  246. System.arraycopy(tmp, 0, out, pos, tmp.length);
  247. return out;
  248. }
  249. /**
  250. * 字节数组逆序
  251. *
  252. * @param in
  253. * @return
  254. */
  255. private static byte[] back(byte[] in)
  256. {
  257. byte[] out = new byte[in.length];
  258. for (int i = 0; i < out.length; i++)
  259. {
  260. out[i] = in[out.length - i - 1];
  261. }
  262. return out;
  263. }
  264. public static int rotateLeft(int x, int n)
  265. {
  266. return (x << n) | (x >> (32 - n));
  267. }
  268. private static int bitCycleLeft(int n, int bitLen)
  269. {
  270. bitLen %= 32;
  271. byte[] tmp = bigEndianIntToByte(n);
  272. int byteLen = bitLen / 8;
  273. int len = bitLen % 8;
  274. if (byteLen > 0)
  275. {
  276. tmp = byteCycleLeft(tmp, byteLen);
  277. }
  278. if (len > 0)
  279. {
  280. tmp = bitSmall8CycleLeft(tmp, len);
  281. }
  282. return bigEndianByteToInt(tmp);
  283. }
  284. private static byte[] bitSmall8CycleLeft(byte[] in, int len)
  285. {
  286. byte[] tmp = new byte[in.length];
  287. int t1, t2, t3;
  288. for (int i = 0; i < tmp.length; i++)
  289. {
  290. t1 = (byte) ((in[i] & 0x000000ff) << len);
  291. t2 = (byte) ((in[(i + 1) % tmp.length] & 0x000000ff) >> (8 - len));
  292. t3 = (byte) (t1 | t2);
  293. tmp[i] = (byte) t3;
  294. }
  295. return tmp;
  296. }
  297. private static byte[] byteCycleLeft(byte[] in, int byteLen)
  298. {
  299. byte[] tmp = new byte[in.length];
  300. System.arraycopy(in, byteLen, tmp, 0, in.length - byteLen);
  301. System.arraycopy(in, 0, tmp, in.length - byteLen, byteLen);
  302. return tmp;
  303. }
  304. /*private static void print(int[] arr)
  305. {
  306. for (int i = 0; i < arr.length; i++)
  307. {
  308. System.out.print(Integer.toHexString(arr[i]) + " ");
  309. if ((i + 1) % 16 == 0)
  310. {
  311. System.out.println();
  312. }
  313. }
  314. System.out.println();
  315. }*/
  316. }