SM3Digest.java 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package com.security.cipher.sm;
  2. import org.bouncycastle.util.encoders.Hex;
  3. public class SM3Digest
  4. {
  5. /** SM3值的长度 */
  6. private static final int BYTE_LENGTH = 32;
  7. /** SM3分组长度 */
  8. private static final int BLOCK_LENGTH = 64;
  9. /** 缓冲区长度 */
  10. private static final int BUFFER_LENGTH = BLOCK_LENGTH * 1;
  11. /** 缓冲区 */
  12. private byte[] xBuf = new byte[BUFFER_LENGTH];
  13. /** 缓冲区偏移量 */
  14. private int xBufOff;
  15. /** 初始向量 */
  16. private byte[] V = SM3.iv.clone();
  17. private int cntBlock = 0;
  18. public SM3Digest() {
  19. }
  20. public SM3Digest(SM3Digest t)
  21. {
  22. System.arraycopy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);
  23. this.xBufOff = t.xBufOff;
  24. System.arraycopy(t.V, 0, this.V, 0, t.V.length);
  25. }
  26. /**
  27. * SM3结果输出
  28. *
  29. * @param out 保存SM3结构的缓冲区
  30. * @param outOff 缓冲区偏移量
  31. * @return
  32. */
  33. public int doFinal(byte[] out, int outOff)
  34. {
  35. byte[] tmp = doFinal();
  36. System.arraycopy(tmp, 0, out, 0, tmp.length);
  37. return BYTE_LENGTH;
  38. }
  39. public void reset()
  40. {
  41. xBufOff = 0;
  42. cntBlock = 0;
  43. V = SM3.iv.clone();
  44. }
  45. /**
  46. * 明文输入
  47. *
  48. * @param in
  49. * 明文输入缓冲区
  50. * @param inOff
  51. * 缓冲区偏移量
  52. * @param len
  53. * 明文长度
  54. */
  55. public void update(byte[] in, int inOff, int len)
  56. {
  57. int partLen = BUFFER_LENGTH - xBufOff;
  58. int inputLen = len;
  59. int dPos = inOff;
  60. if (partLen < inputLen)
  61. {
  62. System.arraycopy(in, dPos, xBuf, xBufOff, partLen);
  63. inputLen -= partLen;
  64. dPos += partLen;
  65. doUpdate();
  66. while (inputLen > BUFFER_LENGTH)
  67. {
  68. System.arraycopy(in, dPos, xBuf, 0, BUFFER_LENGTH);
  69. inputLen -= BUFFER_LENGTH;
  70. dPos += BUFFER_LENGTH;
  71. doUpdate();
  72. }
  73. }
  74. System.arraycopy(in, dPos, xBuf, xBufOff, inputLen);
  75. xBufOff += inputLen;
  76. }
  77. private void doUpdate()
  78. {
  79. byte[] B = new byte[BLOCK_LENGTH];
  80. for (int i = 0; i < BUFFER_LENGTH; i += BLOCK_LENGTH)
  81. {
  82. System.arraycopy(xBuf, i, B, 0, B.length);
  83. doHash(B);
  84. }
  85. xBufOff = 0;
  86. }
  87. private void doHash(byte[] B)
  88. {
  89. byte[] tmp = SM3.CF(V, B);
  90. System.arraycopy(tmp, 0, V, 0, V.length);
  91. cntBlock++;
  92. }
  93. private byte[] doFinal()
  94. {
  95. byte[] B = new byte[BLOCK_LENGTH];
  96. byte[] buffer = new byte[xBufOff];
  97. System.arraycopy(xBuf, 0, buffer, 0, buffer.length);
  98. byte[] tmp = SM3.padding(buffer, cntBlock);
  99. for (int i = 0; i < tmp.length; i += BLOCK_LENGTH)
  100. {
  101. System.arraycopy(tmp, i, B, 0, B.length);
  102. doHash(B);
  103. }
  104. return V;
  105. }
  106. public void update(byte in)
  107. {
  108. byte[] buffer = new byte[] { in };
  109. update(buffer, 0, 1);
  110. }
  111. public int getDigestSize()
  112. {
  113. return BYTE_LENGTH;
  114. }
  115. public static void main(String[] args)
  116. {
  117. byte[] md = new byte[32];
  118. byte[] msg1 = "abc".getBytes();
  119. SM3Digest sm3 = new SM3Digest();
  120. sm3.update(msg1, 0, msg1.length);
  121. sm3.doFinal(md, 0);
  122. String s = new String(Hex.encode(md));
  123. System.out.println(s);
  124. }
  125. }