gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm4/cipher.go (about)

     1  // Package sm4 handle shangmi sm4 symmetric encryption algorithm
     2  package sm4
     3  
     4  import (
     5  	"crypto/cipher"
     6  	"fmt"
     7  
     8  	"gitee.com/ks-custle/core-gm/internal/subtle"
     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 []uint32
    19  	dec []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{make([]uint32, rounds), make([]uint32, rounds)}
    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 subtle.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 subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
    66  		panic("sm4: invalid buffer overlap")
    67  	}
    68  	decryptBlockGo(c.dec, dst, src)
    69  }