sm4_gcm.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. Copyright Hyperledger-TWGC All Rights Reserved.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. writed by Zhiwei Yan, 2020 Oct
  13. */
  14. package sm4
  15. import (
  16. "errors"
  17. "strconv"
  18. )
  19. //Paper: The Galois/Counter Mode of Operation (GCM) David A. Mcgrew,John Viega .2004.
  20. func Sm4GCM(key []byte, IV ,in, A []byte, mode bool) ([]byte, []byte, error) {
  21. if len(key) != BlockSize {
  22. return nil,nil, errors.New("SM4: invalid key size " + strconv.Itoa(len(key)))
  23. }
  24. if mode {
  25. C,T:=GCMEncrypt(key,IV,in,A)
  26. return C,T,nil
  27. }else{
  28. P,_T:=GCMDecrypt(key,IV,in,A)
  29. return P,_T,nil
  30. }
  31. }
  32. func GetH(key []byte) (H []byte){
  33. c,err := NewCipher(key)
  34. if err != nil {
  35. panic(err)
  36. }
  37. zores:=make([]byte, BlockSize)
  38. H =make([]byte, BlockSize)
  39. c.Encrypt(H,zores)
  40. return H
  41. }
  42. //ut = a + b
  43. func addition(a ,b []byte) (out []byte){
  44. Len:=len(a)
  45. if Len != len(b) {
  46. return nil
  47. }
  48. out = make([]byte, Len)
  49. for i := 0; i < Len; i++ {
  50. out[i] = a[i] ^ b[i]
  51. }
  52. return out
  53. }
  54. func Rightshift(V []byte){
  55. n:=len(V)
  56. for i:=n-1;i>=0;i-- {
  57. V[i]=V[i]>>1
  58. if i!=0{
  59. V[i]=((V[i-1]&0x01)<<7)|V[i]
  60. }
  61. }
  62. }
  63. func findYi( Y []byte,index int) int{
  64. var temp byte
  65. i := uint(index)
  66. temp=Y[i/8]
  67. temp=temp>>(7-i%8)
  68. if temp & 0x01 == 1{
  69. return 1
  70. }else{
  71. return 0
  72. }
  73. }
  74. func multiplication(X,Y []byte) (Z []byte){
  75. R:=make([]byte,BlockSize)
  76. R[0]=0xe1
  77. Z=make([]byte,BlockSize)
  78. V:=make([]byte,BlockSize)
  79. copy(V,X)
  80. for i:=0;i<=127;i++{
  81. if findYi(Y,i)==1{
  82. Z=addition(Z,V)
  83. }
  84. if V[BlockSize-1]&0x01==0{
  85. Rightshift(V)
  86. }else{
  87. Rightshift(V)
  88. V=addition(V,R)
  89. }
  90. }
  91. return Z
  92. }
  93. func GHASH(H []byte,A []byte,C []byte) (X[]byte){
  94. calculm_v:=func(m ,v int) (int,int) {
  95. if(m==0 && v!=0){
  96. m=1
  97. v=v*8
  98. }else if(m!=0 && v==0) {
  99. v=BlockSize*8
  100. }else if(m!=0 && v!=0){
  101. m=m+1
  102. v=v*8
  103. }else { //m==0 && v==0
  104. m=1
  105. v=0
  106. }
  107. return m,v
  108. }
  109. m:=len(A)/BlockSize
  110. v:=len(A)%BlockSize
  111. m,v=calculm_v(m,v)
  112. n:=len(C)/BlockSize
  113. u:=(len(C)%BlockSize)
  114. n,u=calculm_v(n,u)
  115. //i=0
  116. X=make([]byte,BlockSize*(m+n+2)) //X0 = 0
  117. for i:=0;i<BlockSize;i++{
  118. X[i]=0x00
  119. }
  120. //i=1...m-1
  121. for i:=1;i<=m-1;i++{
  122. copy(X[i*BlockSize:i*BlockSize+BlockSize],multiplication(addition(X[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],A[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize]),H)) //A 1-->m-1 对于数组来说是 0-->m-2
  123. }
  124. //i=m
  125. zeros:=make([]byte,(128-v)/8)
  126. Am:=make([]byte,v/8)
  127. copy(Am[:],A[(m-1)*BlockSize:])
  128. Am=append(Am,zeros...)
  129. copy(X[m*BlockSize:m*BlockSize+BlockSize],multiplication( addition(X[(m-1)*BlockSize:(m-1)*BlockSize+BlockSize],Am),H))
  130. //i=m+1...m+n-1
  131. for i:=m+1;i<=(m+n-1);i++{
  132. copy(X[i*BlockSize:i*BlockSize+BlockSize],multiplication( addition(X[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],C[(i-m-1)*BlockSize:(i-m-1)*BlockSize+BlockSize]),H))
  133. }
  134. //i=m+n
  135. zeros =make([]byte,(128-u)/8)
  136. Cn:=make([]byte,u/8)
  137. copy(Cn[:],C[(n-1)*BlockSize:])
  138. Cn=append(Cn,zeros...)
  139. copy(X[(m+n)*BlockSize:(m+n)*BlockSize+BlockSize],multiplication( addition(X[(m+n-1)*BlockSize:(m+n-1)*BlockSize+BlockSize],Cn),H))
  140. //i=m+n+1
  141. var lenAB []byte
  142. calculateLenToBytes :=func(len int) []byte{
  143. data:=make([]byte,8)
  144. data[0]=byte((len>>56)&0xff)
  145. data[1]=byte((len>>48)&0xff)
  146. data[2]=byte((len>>40)&0xff)
  147. data[3]=byte((len>>32)&0xff)
  148. data[4]=byte((len>>24)&0xff)
  149. data[5]=byte((len>>16)&0xff)
  150. data[6]=byte((len>>8)&0xff)
  151. data[7]=byte((len>>0)&0xff)
  152. return data
  153. }
  154. lenAB=append(lenAB,calculateLenToBytes(len(A))...)
  155. lenAB=append(lenAB,calculateLenToBytes(len(C))...)
  156. copy(X[(m+n+1)*BlockSize:(m+n+1)*BlockSize+BlockSize],multiplication(addition(X[(m+n)*BlockSize:(m+n)*BlockSize+BlockSize],lenAB),H))
  157. return X[(m+n+1)*BlockSize:(m+n+1)*BlockSize+BlockSize]
  158. }
  159. func GetY0(H,IV []byte) []byte{
  160. if len(IV)*8 == 96 {
  161. zero31one1:=[]byte{0x00,0x00,0x00,0x01}
  162. IV=append(IV,zero31one1...)
  163. return IV
  164. }else{
  165. return GHASH(H,[]byte{},IV)
  166. }
  167. }
  168. func incr(n int ,Y_i []byte) (Y_ii []byte) {
  169. Y_ii=make([]byte,BlockSize*n)
  170. copy(Y_ii,Y_i)
  171. addYone:=func(yi,yii []byte){
  172. copy(yii[:],yi[:])
  173. Len:=len(yi)
  174. var rc byte=0x00
  175. for i:=Len-1;i>=0;i--{
  176. if(i==Len-1){
  177. if(yii[i]<0xff){
  178. yii[i]=yii[i]+0x01
  179. rc=0x00
  180. }else{
  181. yii[i]=0x00
  182. rc=0x01
  183. }
  184. }else{
  185. if yii[i]+rc<0xff {
  186. yii[i]=yii[i]+rc
  187. rc=0x00
  188. }else{
  189. yii[i]=0x00
  190. rc=0x01
  191. }
  192. }
  193. }
  194. }
  195. for i:=1;i<n;i++{ //2^32
  196. addYone(Y_ii[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],Y_ii[i*BlockSize:i*BlockSize+BlockSize])
  197. }
  198. return Y_ii
  199. }
  200. func MSB(len int, S []byte) (out []byte){
  201. return S[:len/8]
  202. }
  203. func GCMEncrypt(K,IV,P,A []byte) (C,T []byte){
  204. calculm_v:=func(m ,v int) (int,int) {
  205. if(m==0 && v!=0){
  206. m=1
  207. v=v*8
  208. }else if(m!=0 && v==0) {
  209. v=BlockSize*8
  210. }else if(m!=0 && v!=0){
  211. m=m+1
  212. v=v*8
  213. }else { //m==0 && v==0
  214. m=1
  215. v=0
  216. }
  217. return m,v
  218. }
  219. n:=len(P)/BlockSize
  220. u:=len(P)%BlockSize
  221. n,u=calculm_v(n,u)
  222. H:=GetH(K)
  223. Y0:=GetY0(H,IV)
  224. Y:=make([]byte,BlockSize*(n+1))
  225. Y=incr(n+1,Y0)
  226. c,err := NewCipher(K)
  227. if err != nil {
  228. panic(err)
  229. }
  230. Enc:=make([]byte,BlockSize)
  231. C =make([]byte,len(P))
  232. //i=1...n-1
  233. for i:=1;i<=n-1;i++{
  234. c.Encrypt(Enc,Y[i*BlockSize:i*BlockSize+BlockSize])
  235. copy(C[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],addition(P[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],Enc))
  236. }
  237. //i=n
  238. c.Encrypt(Enc,Y[n*BlockSize:n*BlockSize+BlockSize])
  239. out:=MSB(u,Enc)
  240. copy(C[(n-1)*BlockSize:],addition(P[(n-1)*BlockSize:],out))
  241. c.Encrypt(Enc,Y0)
  242. t:=128
  243. T =MSB(t,addition(Enc,GHASH(H,A,C)))
  244. return C,T
  245. }
  246. func GCMDecrypt(K,IV,C,A []byte)(P,_T []byte){
  247. calculm_v:=func(m ,v int) (int,int) {
  248. if(m==0 && v!=0){
  249. m=1
  250. v=v*8
  251. }else if(m!=0 && v==0) {
  252. v=BlockSize*8
  253. }else if(m!=0 && v!=0){
  254. m=m+1
  255. v=v*8
  256. }else { //m==0 && v==0
  257. m=1
  258. v=0
  259. }
  260. return m,v
  261. }
  262. H:=GetH(K)
  263. Y0:=GetY0(H,IV)
  264. Enc:=make([]byte,BlockSize)
  265. c,err := NewCipher(K)
  266. if err != nil{
  267. panic(err)
  268. }
  269. c.Encrypt(Enc,Y0)
  270. t:=128
  271. _T=MSB(t,addition(Enc,GHASH(H,A,C)))
  272. n:=len(C)/BlockSize
  273. u:=len(C)%BlockSize
  274. n,u=calculm_v(n,u)
  275. Y:=make([]byte,BlockSize*(n+1))
  276. Y=incr(n+1,Y0)
  277. P = make([]byte, BlockSize*n)
  278. for i:=1;i<=n;i++{
  279. c.Encrypt(Enc,Y[i*BlockSize:i*BlockSize+BlockSize])
  280. copy(P[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],addition(C[(i-1)*BlockSize:(i-1)*BlockSize+BlockSize],Enc))
  281. }
  282. c.Encrypt(Enc,Y[n*BlockSize:n*BlockSize+BlockSize])
  283. out:=MSB(u,Enc)
  284. copy(P[(n-1)*BlockSize:],addition(C[(n-1)*BlockSize:],out))
  285. return P,_T
  286. }