gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm4/block.go (about) 1 package sm4 2 3 // [GM/T] SM4 GB/T 32907-2016 4 5 import ( 6 "encoding/binary" 7 "math/bits" 8 ) 9 10 /* 11 sm4/block.go sm4块加密与块解密 12 */ 13 14 type convert func(uint32) uint32 15 16 // sm4块加密 17 // Encrypt one block from src into dst, using the expanded key xk. 18 func encryptBlockGo(xk []uint32, dst, src []byte) { 19 _ = src[15] // early bounds check 20 _ = dst[15] // early bounds check 21 var b0, b1, b2, b3 uint32 22 // 切分明文块,获取4个字 23 b0 = binary.BigEndian.Uint32(src[0:4]) 24 b1 = binary.BigEndian.Uint32(src[4:8]) 25 b2 = binary.BigEndian.Uint32(src[8:12]) 26 b3 = binary.BigEndian.Uint32(src[12:16]) 27 // 1~4轮 28 b0 ^= t(b1 ^ b2 ^ b3 ^ xk[0]) 29 b1 ^= t(b2 ^ b3 ^ b0 ^ xk[1]) 30 b2 ^= t(b3 ^ b0 ^ b1 ^ xk[2]) 31 b3 ^= t(b0 ^ b1 ^ b2 ^ xk[3]) 32 // 5~8轮 33 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[4]) 34 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[5]) 35 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[6]) 36 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[7]) 37 // 9~12轮 38 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[8]) 39 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[9]) 40 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[10]) 41 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[11]) 42 // 13~16轮 43 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[12]) 44 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[13]) 45 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[14]) 46 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[15]) 47 // 17~20轮 48 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[16]) 49 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[17]) 50 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[18]) 51 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[19]) 52 // 21~24轮 53 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[20]) 54 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[21]) 55 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[22]) 56 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[23]) 57 // 24~28轮 58 b0 ^= precomputeT(b1 ^ b2 ^ b3 ^ xk[24]) 59 b1 ^= precomputeT(b2 ^ b3 ^ b0 ^ xk[25]) 60 b2 ^= precomputeT(b3 ^ b0 ^ b1 ^ xk[26]) 61 b3 ^= precomputeT(b0 ^ b1 ^ b2 ^ xk[27]) 62 // 29~32轮 63 b0 ^= t(b1 ^ b2 ^ b3 ^ xk[28]) 64 b1 ^= t(b2 ^ b3 ^ b0 ^ xk[29]) 65 b2 ^= t(b3 ^ b0 ^ b1 ^ xk[30]) 66 b3 ^= t(b0 ^ b1 ^ b2 ^ xk[31]) 67 // 反序拼接 68 binary.BigEndian.PutUint32(dst[:], b3) 69 binary.BigEndian.PutUint32(dst[4:], b2) 70 binary.BigEndian.PutUint32(dst[8:], b1) 71 binary.BigEndian.PutUint32(dst[12:], b0) 72 } 73 74 // sm4密钥扩展 75 // Key expansion algorithm. 76 func expandKeyGo(key []byte, enc, dec []uint32) { 77 // Encryption key setup. 78 var i int 79 var mk []uint32 80 var k [rounds + 4]uint32 81 nk := len(key) / 4 82 mk = make([]uint32, nk) 83 for i = 0; i < nk; i++ { 84 mk[i] = binary.BigEndian.Uint32(key[4*i:]) 85 k[i] = mk[i] ^ fk[i] 86 } 87 88 for i = 0; i < rounds; i++ { 89 // 合成置换再异或 90 k[i+4] = k[i] ^ t2(k[i+1]^k[i+2]^k[i+3]^ck[i]) 91 enc[i] = k[i+4] 92 } 93 94 // Derive decryption key from encryption key. 95 if dec == nil { 96 return 97 } 98 for i = 0; i < rounds; i++ { 99 dec[i] = enc[rounds-1-i] 100 } 101 } 102 103 // sm4块解密 104 // 外部调用时需保证xk是逆序的轮密钥 105 // Decrypt one block from src into dst, using the expanded key xk. 106 func decryptBlockGo(xk []uint32, dst, src []byte) { 107 encryptBlockGo(xk, dst, src) 108 } 109 110 // 轮函数用线性变换函数 111 // L(B) 112 func l(b uint32) uint32 { 113 return b ^ bits.RotateLeft32(b, 2) ^ bits.RotateLeft32(b, 10) ^ bits.RotateLeft32(b, 18) ^ bits.RotateLeft32(b, 24) 114 } 115 116 // 密钥扩展用线性变换函数 117 // L'(B) 118 func l2(b uint32) uint32 { 119 return b ^ bits.RotateLeft32(b, 13) ^ bits.RotateLeft32(b, 23) 120 } 121 122 // 合成置换函数 123 func _t(in uint32, fn convert) uint32 { 124 var bytes [4]byte 125 binary.BigEndian.PutUint32(bytes[:], in) 126 // 使用s盒映射实现非线性变换 127 for i := 0; i < 4; i++ { 128 bytes[i] = sbox[bytes[i]] 129 } 130 // 调用线性变换函数 131 return fn(binary.BigEndian.Uint32(bytes[:])) 132 } 133 134 // 轮函数用合成置换函数 135 // T 136 func t(in uint32) uint32 { 137 return _t(in, l) 138 } 139 140 // 密钥扩展用合成置换函数 141 // T' 142 func t2(in uint32) uint32 { 143 return _t(in, l2) 144 } 145 146 // 优化的轮函数用合成置换函数 147 // 5~28轮使用 148 func precomputeT(in uint32) uint32 { 149 return sboxT0[byte(in>>24)] ^ 150 sboxT1[byte(in>>16)] ^ 151 sboxT2[byte(in>>8)] ^ 152 sboxT3[byte(in)] 153 }