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  }