github.com/emmansun/gmsm@v0.29.1/sm4/cipher.go (about) 1 // Package sm4 implements ShangMi(SM) sm4 symmetric encryption algorithm. 2 package sm4 3 4 import ( 5 "crypto/cipher" 6 "fmt" 7 8 "github.com/emmansun/gmsm/internal/alias" 9 ) 10 11 // BlockSize the sm4 block size in bytes. 12 const BlockSize = 16 13 14 const rounds = 32 15 16 // A cipher is an instance of SM4 encryption using a particular key. 17 type sm4Cipher struct { 18 enc [rounds]uint32 19 dec [rounds]uint32 20 } 21 22 // NewCipher creates and returns a new cipher.Block. 23 // The key argument should be the SM4 key, 24 func NewCipher(key []byte) (cipher.Block, error) { 25 k := len(key) 26 switch k { 27 default: 28 return nil, fmt.Errorf("sm4: invalid key size %d", k) 29 case 16: 30 break 31 } 32 return newCipher(key) 33 } 34 35 // newCipher creates and returns a new cipher.Block 36 // implemented in pure Go. 37 func newCipherGeneric(key []byte) (cipher.Block, error) { 38 c := &sm4Cipher{} 39 expandKeyGo(key, &c.enc, &c.dec) 40 return c, nil 41 } 42 43 func (c *sm4Cipher) BlockSize() int { return BlockSize } 44 45 func (c *sm4Cipher) Encrypt(dst, src []byte) { 46 if len(src) < BlockSize { 47 panic("sm4: input not full block") 48 } 49 if len(dst) < BlockSize { 50 panic("sm4: output not full block") 51 } 52 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { 53 panic("sm4: invalid buffer overlap") 54 } 55 encryptBlockGo(&c.enc, dst, src) 56 } 57 58 func (c *sm4Cipher) Decrypt(dst, src []byte) { 59 if len(src) < BlockSize { 60 panic("sm4: input not full block") 61 } 62 if len(dst) < BlockSize { 63 panic("sm4: output not full block") 64 } 65 if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) { 66 panic("sm4: invalid buffer overlap") 67 } 68 encryptBlockGo(&c.dec, dst, src) 69 }