package sm1 import ( "crypto/cipher" "xdx.jelly/xgcl/gerrors" ) // BlockSize is the SM1 block size in bytes. const ( BlockSize = 16 numOfRound = 8 ) // sm1Cipher is an instance of cipher.Block interface type sm1Cipher struct { encKey [4 * (numOfRound + 1)]uint32 decKey [4 * (numOfRound + 1)]uint32 } // NewCipher creates and returns a new cipher.Block. func NewCipher(key []byte) (cipher.Block, error) { if len(key) != BlockSize { return nil, gerrors.WithAnnotatingf(ErrInvalidInputLength, "key should be %d bytes", BlockSize) } cp := new(sm1Cipher) // gen keys keyexpand_enc(cp.encKey[:], key) keyexpand_dec(cp.decKey[:], key) return cp, nil } // Clear implements the gmath.Clearable interface func (c *sm1Cipher) Clear() { for i := 0; i < len(c.decKey); i++ { c.decKey[i] = 0 c.encKey[i] = 0 } } func (c *sm1Cipher) BlockSize() int { return BlockSize } // 调用前应保证输入一个block func (c *sm1Cipher) Encrypt(dst, src []byte) { if len(src) < BlockSize { panic("xdx.jelly/xgcl/sm/sm1/Encrypt: input not full block") } if len(dst) < BlockSize { panic("xdx.jelly/xgcl/sm/sm1/Encrypt: output not full block") } encryptBlock(dst, src, c.encKey[:]) } func (c *sm1Cipher) Decrypt(dst, src []byte) { if len(src) < BlockSize { panic("xdx.jelly/xgcl/sm/sm1/Decrypt: input not full block") } if len(dst) < BlockSize { panic("xdx.jelly/xgcl/sm/sm1/Decrypt: output not full block") } decryptBlock(dst, src, c.decKey[:]) }