sm3.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package sm
  2. import (
  3. "encoding/binary"
  4. "hash"
  5. )
  6. type SM3 struct {
  7. digest [8]uint32 // digest represents the partial evaluation of V
  8. length uint64 // length of the message
  9. unhandleMsg []byte // uint8 //
  10. }
  11. func (sm3 *SM3) ff0(x, y, z uint32) uint32 { return x ^ y ^ z }
  12. func (sm3 *SM3) ff1(x, y, z uint32) uint32 { return (x & y) | (x & z) | (y & z) }
  13. func (sm3 *SM3) gg0(x, y, z uint32) uint32 { return x ^ y ^ z }
  14. func (sm3 *SM3) gg1(x, y, z uint32) uint32 { return (x & y) | (^x & z) }
  15. func (sm3 *SM3) p0(x uint32) uint32 { return x ^ sm3.leftRotate(x, 9) ^ sm3.leftRotate(x, 17) }
  16. func (sm3 *SM3) p1(x uint32) uint32 { return x ^ sm3.leftRotate(x, 15) ^ sm3.leftRotate(x, 23) }
  17. func (sm3 *SM3) leftRotate(x uint32, i uint32) uint32 { return x<<(i%32) | x>>(32-i%32) }
  18. func (sm3 *SM3) pad() []byte {
  19. msg := sm3.unhandleMsg
  20. msg = append(msg, 0x80) // Append '1'
  21. blockSize := 64 // Append until the resulting message length (in bits) is congruent to 448 (mod 512)
  22. for len(msg)%blockSize != 56 {
  23. msg = append(msg, 0x00)
  24. }
  25. // append message length
  26. msg = append(msg, uint8(sm3.length>>56&0xff))
  27. msg = append(msg, uint8(sm3.length>>48&0xff))
  28. msg = append(msg, uint8(sm3.length>>40&0xff))
  29. msg = append(msg, uint8(sm3.length>>32&0xff))
  30. msg = append(msg, uint8(sm3.length>>24&0xff))
  31. msg = append(msg, uint8(sm3.length>>16&0xff))
  32. msg = append(msg, uint8(sm3.length>>8&0xff))
  33. msg = append(msg, uint8(sm3.length>>0&0xff))
  34. if len(msg)%64 != 0 {
  35. panic("------SM3 Pad: error msgLen =")
  36. }
  37. return msg
  38. }
  39. func (sm3 *SM3) update(msg []byte) {
  40. var w [68]uint32
  41. var w1 [64]uint32
  42. a, b, c, d, e, f, g, h := sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7]
  43. for len(msg) >= 64 {
  44. for i := 0; i < 16; i++ {
  45. w[i] = binary.BigEndian.Uint32(msg[4*i : 4*(i+1)])
  46. }
  47. for i := 16; i < 68; i++ {
  48. w[i] = sm3.p1(w[i-16]^w[i-9]^sm3.leftRotate(w[i-3], 15)) ^ sm3.leftRotate(w[i-13], 7) ^ w[i-6]
  49. }
  50. for i := 0; i < 64; i++ {
  51. w1[i] = w[i] ^ w[i+4]
  52. }
  53. A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
  54. for i := 0; i < 16; i++ {
  55. SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x79cc4519, uint32(i)), 7)
  56. SS2 := SS1 ^ sm3.leftRotate(A, 12)
  57. TT1 := sm3.ff0(A, B, C) + D + SS2 + w1[i]
  58. TT2 := sm3.gg0(E, F, G) + H + SS1 + w[i]
  59. D = C
  60. C = sm3.leftRotate(B, 9)
  61. B = A
  62. A = TT1
  63. H = G
  64. G = sm3.leftRotate(F, 19)
  65. F = E
  66. E = sm3.p0(TT2)
  67. }
  68. for i := 16; i < 64; i++ {
  69. SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x7a879d8a, uint32(i)), 7)
  70. SS2 := SS1 ^ sm3.leftRotate(A, 12)
  71. TT1 := sm3.ff1(A, B, C) + D + SS2 + w1[i]
  72. TT2 := sm3.gg1(E, F, G) + H + SS1 + w[i]
  73. D = C
  74. C = sm3.leftRotate(B, 9)
  75. B = A
  76. A = TT1
  77. H = G
  78. G = sm3.leftRotate(F, 19)
  79. F = E
  80. E = sm3.p0(TT2)
  81. }
  82. a ^= A
  83. b ^= B
  84. c ^= C
  85. d ^= D
  86. e ^= E
  87. f ^= F
  88. g ^= G
  89. h ^= H
  90. msg = msg[64:]
  91. }
  92. sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7] = a, b, c, d, e, f, g, h
  93. }
  94. func (sm3 *SM3) update2(msg []byte) [8]uint32 {
  95. var w [68]uint32
  96. var w1 [64]uint32
  97. a, b, c, d, e, f, g, h := sm3.digest[0], sm3.digest[1], sm3.digest[2], sm3.digest[3], sm3.digest[4], sm3.digest[5], sm3.digest[6], sm3.digest[7]
  98. for len(msg) >= 64 {
  99. for i := 0; i < 16; i++ {
  100. w[i] = binary.BigEndian.Uint32(msg[4*i : 4*(i+1)])
  101. }
  102. for i := 16; i < 68; i++ {
  103. w[i] = sm3.p1(w[i-16]^w[i-9]^sm3.leftRotate(w[i-3], 15)) ^ sm3.leftRotate(w[i-13], 7) ^ w[i-6]
  104. }
  105. for i := 0; i < 64; i++ {
  106. w1[i] = w[i] ^ w[i+4]
  107. }
  108. A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
  109. for i := 0; i < 16; i++ {
  110. SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x79cc4519, uint32(i)), 7)
  111. SS2 := SS1 ^ sm3.leftRotate(A, 12)
  112. TT1 := sm3.ff0(A, B, C) + D + SS2 + w1[i]
  113. TT2 := sm3.gg0(E, F, G) + H + SS1 + w[i]
  114. D = C
  115. C = sm3.leftRotate(B, 9)
  116. B = A
  117. A = TT1
  118. H = G
  119. G = sm3.leftRotate(F, 19)
  120. F = E
  121. E = sm3.p0(TT2)
  122. }
  123. for i := 16; i < 64; i++ {
  124. SS1 := sm3.leftRotate(sm3.leftRotate(A, 12)+E+sm3.leftRotate(0x7a879d8a, uint32(i)), 7)
  125. SS2 := SS1 ^ sm3.leftRotate(A, 12)
  126. TT1 := sm3.ff1(A, B, C) + D + SS2 + w1[i]
  127. TT2 := sm3.gg1(E, F, G) + H + SS1 + w[i]
  128. D = C
  129. C = sm3.leftRotate(B, 9)
  130. B = A
  131. A = TT1
  132. H = G
  133. G = sm3.leftRotate(F, 19)
  134. F = E
  135. E = sm3.p0(TT2)
  136. }
  137. a ^= A
  138. b ^= B
  139. c ^= C
  140. d ^= D
  141. e ^= E
  142. f ^= F
  143. g ^= G
  144. h ^= H
  145. msg = msg[64:]
  146. }
  147. var digest [8]uint32
  148. digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7] = a, b, c, d, e, f, g, h
  149. return digest
  150. }
  151. // 创建哈希计算实例
  152. func New() hash.Hash {
  153. var sm3 SM3
  154. sm3.Reset()
  155. return &sm3
  156. }
  157. // BlockSize returns the hash's underlying block size.
  158. // The Write method must be able to accept any amount
  159. // of data, but it may operate more efficiently if all writes
  160. // are a multiple of the block size.
  161. func (sm3 *SM3) BlockSize() int { return 64 }
  162. // Size returns the number of bytes Sum will return.
  163. func (sm3 *SM3) Size() int { return 32 }
  164. // Reset clears the internal state by zeroing bytes in the state buffer.
  165. // This can be skipped for a newly-created hash state; the default zero-allocated state is correct.
  166. func (sm3 *SM3) Reset() {
  167. // Reset digest
  168. sm3.digest[0] = 0x7380166f
  169. sm3.digest[1] = 0x4914b2b9
  170. sm3.digest[2] = 0x172442d7
  171. sm3.digest[3] = 0xda8a0600
  172. sm3.digest[4] = 0xa96f30bc
  173. sm3.digest[5] = 0x163138aa
  174. sm3.digest[6] = 0xe38dee4d
  175. sm3.digest[7] = 0xb0fb0e4e
  176. sm3.length = 0 // Reset numberic states
  177. sm3.unhandleMsg = []byte{}
  178. }
  179. // Write (via the embedded io.Writer interface) adds more data to the running hash.
  180. // It never returns an error.
  181. func (sm3 *SM3) Write(p []byte) (int, error) {
  182. toWrite := len(p)
  183. sm3.length += uint64(len(p) * 8)
  184. msg := append(sm3.unhandleMsg, p...)
  185. nblocks := len(msg) / sm3.BlockSize()
  186. sm3.update(msg)
  187. // Update unhandleMsg
  188. sm3.unhandleMsg = msg[nblocks*sm3.BlockSize():]
  189. return toWrite, nil
  190. }
  191. // 返回SM3哈希算法摘要值
  192. // Sum appends the current hash to b and returns the resulting slice.
  193. // It does not change the underlying hash state.
  194. func (sm3 *SM3) Sum(in []byte) []byte {
  195. _, _ = sm3.Write(in)
  196. msg := sm3.pad()
  197. //Finalize
  198. digest := sm3.update2(msg)
  199. // save hash to in
  200. needed := sm3.Size()
  201. if cap(in)-len(in) < needed {
  202. newIn := make([]byte, len(in), len(in)+needed)
  203. copy(newIn, in)
  204. in = newIn
  205. }
  206. out := in[len(in) : len(in)+needed]
  207. for i := 0; i < 8; i++ {
  208. binary.BigEndian.PutUint32(out[i*4:], digest[i])
  209. }
  210. return out
  211. }
  212. func Sm3Sum(data []byte) []byte {
  213. var sm3 SM3
  214. sm3.Reset()
  215. _, _ = sm3.Write(data)
  216. return sm3.Sum(nil)
  217. }