65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
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[:])
|
|
}
|