mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 12:16:20 +08:00
cipher/sm4: refactoring, remove sm4_test folder
This commit is contained in:
parent
2c3b759652
commit
8eeeddbbea
415
cipher/benchmark_test.go
Normal file
415
cipher/benchmark_test.go
Normal file
@ -0,0 +1,415 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"testing"
|
||||
|
||||
smcipher "github.com/emmansun/gmsm/cipher"
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
func benchmarkCBCEncrypt1K(b *testing.B, block cipher.Block) {
|
||||
buf := make([]byte, 1024)
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var iv [16]byte
|
||||
cbc := cipher.NewCBCEncrypter(block, iv[:])
|
||||
for i := 0; i < b.N; i++ {
|
||||
cbc.CryptBlocks(buf, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAESCBCEncrypt1K(b *testing.B) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
benchmarkCBCEncrypt1K(b, c)
|
||||
}
|
||||
|
||||
func BenchmarkSM4CBCEncrypt1K(b *testing.B) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
benchmarkCBCEncrypt1K(b, c)
|
||||
}
|
||||
|
||||
func benchmarkSM4CBCDecrypt1K(b *testing.B, block cipher.Block) {
|
||||
buf := make([]byte, 1024)
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var iv [16]byte
|
||||
cbc := cipher.NewCBCDecrypter(block, iv[:])
|
||||
for i := 0; i < b.N; i++ {
|
||||
cbc.CryptBlocks(buf, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAESCBCDecrypt1K(b *testing.B) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
benchmarkSM4CBCDecrypt1K(b, c)
|
||||
}
|
||||
|
||||
func BenchmarkSM4CBCDecrypt1K(b *testing.B) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
benchmarkSM4CBCDecrypt1K(b, c)
|
||||
}
|
||||
|
||||
func benchmarkStream(b *testing.B, block cipher.Block, mode func(cipher.Block, []byte) cipher.Stream, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
//var key [16]byte
|
||||
var iv [16]byte
|
||||
//c, _ := sm4.NewCipher(key[:])
|
||||
stream := mode(block, iv[:])
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
stream.XORKeyStream(buf, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkSM4Stream(b *testing.B, mode func(cipher.Block, []byte) cipher.Stream, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
benchmarkStream(b, c, mode, buf)
|
||||
}
|
||||
|
||||
func benchmarkAESStream(b *testing.B, mode func(cipher.Block, []byte) cipher.Stream, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
benchmarkStream(b, c, mode, buf)
|
||||
}
|
||||
|
||||
// If we test exactly 1K blocks, we would generate exact multiples of
|
||||
// the cipher's block size, and the cipher stream fragments would
|
||||
// always be wordsize aligned, whereas non-aligned is a more typical
|
||||
// use-case.
|
||||
const almost1K = 1024 - 5
|
||||
const almost8K = 8*1024 - 5
|
||||
|
||||
func BenchmarkAESCFBEncrypt1K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewCFBEncrypter, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CFBEncrypt1K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewCFBEncrypter, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkAESCFBDecrypt1K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewCFBDecrypter, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CFBDecrypt1K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewCFBDecrypter, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkAESCFBDecrypt8K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewCFBDecrypter, make([]byte, almost8K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CFBDecrypt8K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewCFBDecrypter, make([]byte, almost8K))
|
||||
}
|
||||
|
||||
func BenchmarkAESOFB1K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewOFB, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4OFB1K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewOFB, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkAESCTR1K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewCTR, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CTR1K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewCTR, make([]byte, almost1K))
|
||||
}
|
||||
|
||||
func BenchmarkAESCTR8K(b *testing.B) {
|
||||
benchmarkAESStream(b, cipher.NewCTR, make([]byte, almost8K))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CTR8K(b *testing.B) {
|
||||
benchmarkSM4Stream(b, cipher.NewCTR, make([]byte, almost8K))
|
||||
}
|
||||
|
||||
func benchmarkGCMSign(b *testing.B, aead cipher.AEAD, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var nonce [12]byte
|
||||
var out []byte
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
out = aead.Seal(out[:0], nonce[:], nil, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkAESGCMSign(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
aesgcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMSign(b, aesgcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4GCMSign(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMSign(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkGCMSeal(b *testing.B, aead cipher.AEAD, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var nonce [12]byte
|
||||
var ad [13]byte
|
||||
var out []byte
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
out = aead.Seal(out[:0], nonce[:], buf, ad[:])
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkAESGCMSeal(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMSeal(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4GCMSeal(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMSeal(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkGCMOpen(b *testing.B, aead cipher.AEAD, buf []byte) {
|
||||
b.SetBytes(int64(len(buf)))
|
||||
|
||||
var nonce [12]byte
|
||||
var ad [13]byte
|
||||
var out []byte
|
||||
out = aead.Seal(out[:0], nonce[:], buf, ad[:])
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := aead.Open(buf[:0], nonce[:], out, ad[:])
|
||||
if err != nil {
|
||||
b.Errorf("Open: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkAESGCMOpen(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMOpen(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4GCMOpen(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
benchmarkGCMOpen(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMSeal1K(b *testing.B) {
|
||||
benchmarkAESGCMSeal(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMSeal1K(b *testing.B) {
|
||||
benchmarkSM4GCMSeal(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMOpen1K(b *testing.B) {
|
||||
benchmarkAESGCMOpen(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMOpen1K(b *testing.B) {
|
||||
benchmarkSM4GCMOpen(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMSign1K(b *testing.B) {
|
||||
benchmarkAESGCMSign(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMSign1K(b *testing.B) {
|
||||
benchmarkSM4GCMSign(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMSign8K(b *testing.B) {
|
||||
benchmarkAESGCMSign(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMSign8K(b *testing.B) {
|
||||
benchmarkSM4GCMSign(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMSeal8K(b *testing.B) {
|
||||
benchmarkAESGCMSeal(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMSeal8K(b *testing.B) {
|
||||
benchmarkSM4GCMSeal(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESGCMOpen8K(b *testing.B) {
|
||||
benchmarkAESGCMOpen(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4GCMOpen8K(b *testing.B) {
|
||||
benchmarkSM4GCMOpen(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func benchmarkAESCCMSign(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
aesccm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMSign(b, aesccm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4CCMSign(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4ccm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMSign(b, sm4ccm, buf)
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMSign1K(b *testing.B) {
|
||||
benchmarkAESCCMSign(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMSign1K(b *testing.B) {
|
||||
benchmarkSM4CCMSign(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMSeal1K(b *testing.B) {
|
||||
benchmarkAESCCMSeal(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMSeal1K(b *testing.B) {
|
||||
benchmarkSM4CCMSeal(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMOpen1K(b *testing.B) {
|
||||
benchmarkAESCCMOpen(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMOpen1K(b *testing.B) {
|
||||
benchmarkSM4CCMOpen(b, make([]byte, 1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMSign8K(b *testing.B) {
|
||||
benchmarkAESCCMSign(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMSign8K(b *testing.B) {
|
||||
benchmarkSM4CCMSign(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMSeal8K(b *testing.B) {
|
||||
benchmarkAESCCMSeal(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMSeal8K(b *testing.B) {
|
||||
benchmarkSM4CCMSeal(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkAESCCMOpen8K(b *testing.B) {
|
||||
benchmarkAESCCMOpen(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func BenchmarkSM4CCMOpen8K(b *testing.B) {
|
||||
benchmarkSM4CCMOpen(b, make([]byte, 8*1024))
|
||||
}
|
||||
|
||||
func benchmarkAESCCMSeal(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
sm4gcm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMSeal(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4CCMSeal(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4gcm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMSeal(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkAESCCMOpen(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := aes.NewCipher(key[:])
|
||||
sm4gcm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMOpen(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkSM4CCMOpen(b *testing.B, buf []byte) {
|
||||
var key [16]byte
|
||||
c, _ := sm4.NewCipher(key[:])
|
||||
sm4gcm, _ := smcipher.NewCCM(c)
|
||||
benchmarkGCMOpen(b, sm4gcm, buf)
|
||||
}
|
||||
|
||||
func benchmarkXTS(b *testing.B, cipherFunc func([]byte) (cipher.Block, error), length, keylen int64) {
|
||||
c, err := smcipher.NewXTS(cipherFunc, make([]byte, keylen))
|
||||
if err != nil {
|
||||
b.Fatalf("NewCipher failed: %s", err)
|
||||
}
|
||||
plaintext := make([]byte, length)
|
||||
encrypted := make([]byte, length)
|
||||
//decrypted := make([]byte, length)
|
||||
b.SetBytes(int64(len(plaintext)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.Encrypt(encrypted, plaintext, 0)
|
||||
//c.Decrypt(decrypted, encrypted[:len(plaintext)], 0)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAES128XTSEncrypt512(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 512, 32)
|
||||
}
|
||||
|
||||
func BenchmarkAES128XTSEncrypt1K(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 1024, 32)
|
||||
}
|
||||
|
||||
func BenchmarkAES128XTSEncrypt4K(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 4096, 32)
|
||||
}
|
||||
|
||||
func BenchmarkAES256XTSEncrypt512(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 512, 64)
|
||||
}
|
||||
|
||||
func BenchmarkAES256XTSEncrypt1K(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 1024, 64)
|
||||
}
|
||||
|
||||
func BenchmarkAES256XTSEncrypt4K(b *testing.B) {
|
||||
benchmarkXTS(b, aes.NewCipher, 4096, 64)
|
||||
}
|
||||
|
||||
func BenchmarkSM4XTSEncrypt512(b *testing.B) {
|
||||
benchmarkXTS(b, sm4.NewCipher, 512, 32)
|
||||
}
|
||||
|
||||
func BenchmarkSM4XTSEncrypt1K(b *testing.B) {
|
||||
benchmarkXTS(b, sm4.NewCipher, 1024, 32)
|
||||
}
|
||||
|
||||
func BenchmarkSM4XTSEncrypt4K(b *testing.B) {
|
||||
benchmarkXTS(b, sm4.NewCipher, 4096, 32)
|
||||
}
|
187
cipher/cbc_sm4_test.go
Normal file
187
cipher/cbc_sm4_test.go
Normal file
@ -0,0 +1,187 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/padding"
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var cbcSM4Tests = []struct {
|
||||
name string
|
||||
key []byte
|
||||
iv []byte
|
||||
in []byte
|
||||
out []byte
|
||||
}{
|
||||
{
|
||||
"from internet",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World"),
|
||||
[]byte{0x0a, 0x67, 0x06, 0x2f, 0x0c, 0xd2, 0xdc, 0xe2, 0x6a, 0x7b, 0x97, 0x8e, 0xbf, 0x21, 0x34, 0xf9},
|
||||
},
|
||||
{
|
||||
"Three blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello Worldd"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0x06, 0x8d, 0x0f, 0xef, 0x4e, 0x2b, 0xfa, 0xb4, 0xbc, 0xab, 0xa6, 0x64, 0x41, 0xfd, 0xe0, 0xfe,
|
||||
0x92, 0xc1, 0x64, 0xec, 0xa1, 0x70, 0x24, 0x75, 0x72, 0xde, 0x12, 0x02, 0x95, 0x2e, 0xc7, 0x27,
|
||||
},
|
||||
},
|
||||
{
|
||||
"Four blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello World Hello World Hell"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0xe0, 0x02, 0xd6, 0xe4, 0xf5, 0x66, 0x87, 0xc4, 0xcc, 0x54, 0x1d, 0x1f, 0x1c, 0xc4, 0x2f, 0xe6,
|
||||
0xe5, 0x1d, 0xea, 0x52, 0xb8, 0x0c, 0xc8, 0xbe, 0xae, 0xcc, 0x44, 0xa8, 0x51, 0x81, 0x08, 0x60,
|
||||
0x34, 0x6e, 0x9d, 0xad, 0xe1, 0x8a, 0xf4, 0xa1, 0x83, 0x69, 0x57, 0xb9, 0x37, 0x26, 0x7e, 0x03,
|
||||
},
|
||||
},
|
||||
{
|
||||
"Five blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello World Hello World Hello World Hello Wo"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0xe0, 0x02, 0xd6, 0xe4, 0xf5, 0x66, 0x87, 0xc4, 0xcc, 0x54, 0x1d, 0x1f, 0x1c, 0xc4, 0x2f, 0xe6,
|
||||
0xe5, 0x1d, 0xea, 0x52, 0xb8, 0x0c, 0xc8, 0xbe, 0xae, 0xcc, 0x44, 0xa8, 0x51, 0x81, 0x08, 0x60,
|
||||
0xb6, 0x09, 0x7b, 0xb8, 0x7e, 0xdb, 0x53, 0x4b, 0xea, 0x2a, 0xc6, 0xa1, 0xe5, 0xa0, 0x2a, 0xe9,
|
||||
0x62, 0xb5, 0xe7, 0x50, 0x44, 0xea, 0x24, 0xcc, 0x9b, 0x5e, 0x07, 0x48, 0x04, 0x89, 0xa2, 0x74,
|
||||
},
|
||||
},
|
||||
{
|
||||
"7 blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hell"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0xe0, 0x02, 0xd6, 0xe4, 0xf5, 0x66, 0x87, 0xc4, 0xcc, 0x54, 0x1d, 0x1f, 0x1c, 0xc4, 0x2f, 0xe6,
|
||||
0xe5, 0x1d, 0xea, 0x52, 0xb8, 0x0c, 0xc8, 0xbe, 0xae, 0xcc, 0x44, 0xa8, 0x51, 0x81, 0x08, 0x60,
|
||||
0xb6, 0x09, 0x7b, 0xb8, 0x7e, 0xdb, 0x53, 0x4b, 0xea, 0x2a, 0xc6, 0xa1, 0xe5, 0xa0, 0x2a, 0xe9,
|
||||
0x22, 0x65, 0x5b, 0xa3, 0xb9, 0xcc, 0x63, 0x92, 0x16, 0x0e, 0x2f, 0xf4, 0x3b, 0x93, 0x06, 0x82,
|
||||
0xb3, 0x8c, 0x26, 0x2e, 0x06, 0x51, 0x34, 0x2c, 0xe4, 0x3d, 0xd0, 0xc7, 0x2b, 0x8f, 0x31, 0x15,
|
||||
0xb7, 0x8f, 0xd0, 0x47, 0x45, 0x40, 0xec, 0x02, 0x1b, 0xef, 0xc1, 0xd2, 0xe5, 0xa2, 0x35, 0xd2,
|
||||
},
|
||||
},
|
||||
{
|
||||
"9 blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0xe0, 0x02, 0xd6, 0xe4, 0xf5, 0x66, 0x87, 0xc4, 0xcc, 0x54, 0x1d, 0x1f, 0x1c, 0xc4, 0x2f, 0xe6,
|
||||
0xe5, 0x1d, 0xea, 0x52, 0xb8, 0x0c, 0xc8, 0xbe, 0xae, 0xcc, 0x44, 0xa8, 0x51, 0x81, 0x08, 0x60,
|
||||
0xb6, 0x09, 0x7b, 0xb8, 0x7e, 0xdb, 0x53, 0x4b, 0xea, 0x2a, 0xc6, 0xa1, 0xe5, 0xa0, 0x2a, 0xe9,
|
||||
0x22, 0x65, 0x5b, 0xa3, 0xb9, 0xcc, 0x63, 0x92, 0x16, 0x0e, 0x2f, 0xf4, 0x3b, 0x93, 0x06, 0x82,
|
||||
0xb3, 0x8c, 0x26, 0x2e, 0x06, 0x51, 0x34, 0x2c, 0xe4, 0x3d, 0xd0, 0xc7, 0x2b, 0x8f, 0x31, 0x15,
|
||||
0x30, 0xa8, 0x96, 0x1c, 0xbc, 0x8e, 0xf7, 0x4f, 0x6b, 0x69, 0x9d, 0xc9, 0x40, 0x89, 0xd7, 0xe8,
|
||||
0xf7, 0x90, 0x47, 0x74, 0xaf, 0x40, 0xfd, 0x72, 0xc6, 0x17, 0xeb, 0xc0, 0x8b, 0x01, 0x71, 0x5c,
|
||||
},
|
||||
},
|
||||
{
|
||||
"17 blocks",
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("0123456789ABCDEF"),
|
||||
[]byte("Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World"),
|
||||
[]byte{
|
||||
0xd3, 0x1e, 0x36, 0x83, 0xe4, 0xfc, 0x9b, 0x51, 0x6a, 0x2c, 0x0f, 0x98, 0x36, 0x76, 0xa9, 0xeb,
|
||||
0x1f, 0xdc, 0xc3, 0x2a, 0xf3, 0x84, 0x08, 0x97, 0x81, 0x57, 0xa2, 0x06, 0x5d, 0xe3, 0x4c, 0x6a,
|
||||
0xe0, 0x02, 0xd6, 0xe4, 0xf5, 0x66, 0x87, 0xc4, 0xcc, 0x54, 0x1d, 0x1f, 0x1c, 0xc4, 0x2f, 0xe6,
|
||||
0xe5, 0x1d, 0xea, 0x52, 0xb8, 0x0c, 0xc8, 0xbe, 0xae, 0xcc, 0x44, 0xa8, 0x51, 0x81, 0x08, 0x60,
|
||||
0xb6, 0x09, 0x7b, 0xb8, 0x7e, 0xdb, 0x53, 0x4b, 0xea, 0x2a, 0xc6, 0xa1, 0xe5, 0xa0, 0x2a, 0xe9,
|
||||
0x22, 0x65, 0x5b, 0xa3, 0xb9, 0xcc, 0x63, 0x92, 0x16, 0x0e, 0x2f, 0xf4, 0x3b, 0x93, 0x06, 0x82,
|
||||
0xb3, 0x8c, 0x26, 0x2e, 0x06, 0x51, 0x34, 0x2c, 0xe4, 0x3d, 0xd0, 0xc7, 0x2b, 0x8f, 0x31, 0x15,
|
||||
0x30, 0xa8, 0x96, 0x1c, 0xbc, 0x8e, 0xf7, 0x4f, 0x6b, 0x69, 0x9d, 0xc9, 0x40, 0x89, 0xd7, 0xe8,
|
||||
0x2a, 0xe8, 0xc3, 0x3d, 0xcb, 0x8a, 0x1c, 0xb3, 0x70, 0x7d, 0xe9, 0xe6, 0x88, 0x36, 0x65, 0x21,
|
||||
0x7b, 0x34, 0xac, 0x73, 0x8d, 0x4f, 0x11, 0xde, 0xd4, 0x21, 0x45, 0x9f, 0x1f, 0x3e, 0xe8, 0xcf,
|
||||
0x50, 0x92, 0x8c, 0xa4, 0x79, 0x58, 0x3a, 0x26, 0x01, 0x7b, 0x99, 0x5c, 0xff, 0x8d, 0x66, 0x5b,
|
||||
0x07, 0x86, 0x0e, 0x22, 0xb4, 0xb4, 0x83, 0x74, 0x33, 0x79, 0xd0, 0x54, 0x9f, 0x03, 0x6b, 0x60,
|
||||
0xa1, 0x52, 0x3c, 0x61, 0x1d, 0x91, 0xbf, 0x50, 0x00, 0xfb, 0x62, 0x58, 0xfa, 0xd3, 0xbd, 0x17,
|
||||
0x7d, 0x6f, 0xda, 0x76, 0x9a, 0xdb, 0x01, 0x96, 0x97, 0xc9, 0x5f, 0x64, 0x20, 0x3c, 0x70, 0x7a,
|
||||
0x40, 0x1f, 0x35, 0xc8, 0x22, 0xf2, 0x76, 0x6d, 0x8e, 0x4a, 0x78, 0xd7, 0x8d, 0x52, 0x51, 0x60,
|
||||
0x39, 0x14, 0xd8, 0xcd, 0xc7, 0x4b, 0x3f, 0xb3, 0x16, 0xdf, 0x52, 0xba, 0xcb, 0x98, 0x56, 0xaa,
|
||||
0x97, 0x8b, 0xab, 0xa7, 0xbf, 0xe8, 0x0f, 0x16, 0x27, 0xbb, 0x56, 0xce, 0x10, 0xe5, 0x90, 0x05,
|
||||
},
|
||||
},
|
||||
{
|
||||
"A.1",
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{
|
||||
0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46,
|
||||
0x67, 0x7d, 0x30, 0x7e, 0x84, 0x4d, 0x7a, 0xa2, 0x45, 0x79, 0xd5, 0x56, 0x49, 0x0d, 0xc7, 0xaa},
|
||||
},
|
||||
}
|
||||
|
||||
func TestCBCEncrypterSM4(t *testing.T) {
|
||||
pkcs7 := padding.NewPKCS7Padding(sm4.BlockSize)
|
||||
for _, test := range cbcSM4Tests {
|
||||
c, err := sm4.NewCipher(test.key)
|
||||
if err != nil {
|
||||
t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err)
|
||||
continue
|
||||
}
|
||||
|
||||
encrypter := cipher.NewCBCEncrypter(c, test.iv)
|
||||
|
||||
plainText := pkcs7.Pad(test.in)
|
||||
data := make([]byte, len(plainText))
|
||||
copy(data, plainText)
|
||||
|
||||
encrypter.CryptBlocks(data, data)
|
||||
if !bytes.Equal(test.out, data) {
|
||||
t.Errorf("%s: CBCEncrypter\nhave %s\nwant %x", test.name, hex.EncodeToString(data), test.out)
|
||||
for i := 0; i < len(data); i++ {
|
||||
fmt.Printf("0x%02x, ", data[i])
|
||||
if (i+1)%16 == 0 {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCBCDecrypterSM4(t *testing.T) {
|
||||
pkcs7 := padding.NewPKCS7Padding(sm4.BlockSize)
|
||||
for _, test := range cbcSM4Tests {
|
||||
c, err := sm4.NewCipher(test.key)
|
||||
if err != nil {
|
||||
t.Errorf("%s: NewCipher(%d bytes) = %s", test.name, len(test.key), err)
|
||||
continue
|
||||
}
|
||||
|
||||
decrypter := cipher.NewCBCDecrypter(c, test.iv)
|
||||
|
||||
data := make([]byte, len(test.out))
|
||||
copy(data, test.out)
|
||||
|
||||
decrypter.CryptBlocks(data, data)
|
||||
data, err = pkcs7.Unpad(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(test.in, data) {
|
||||
t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test.name, data, test.in)
|
||||
}
|
||||
}
|
||||
}
|
54
cipher/ccm_sm4_test.go
Normal file
54
cipher/ccm_sm4_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
smcipher "github.com/emmansun/gmsm/cipher"
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var sm4CCMTests = []struct {
|
||||
key, nonce, plaintext, ad, result string
|
||||
}{
|
||||
{ // https://tools.ietf.org/html/rfc8998 A.2. SM4-CCM Test Vectors
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"00001234567800000000abcd",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b16842d4fa186f56ab33256971fa110f4",
|
||||
},
|
||||
}
|
||||
|
||||
func TestCCM(t *testing.T) {
|
||||
for i, tt := range sm4CCMTests {
|
||||
nonce, _ := hex.DecodeString(tt.nonce)
|
||||
plaintext, _ := hex.DecodeString(tt.plaintext)
|
||||
ad, _ := hex.DecodeString(tt.ad)
|
||||
key, _ := hex.DecodeString(tt.key)
|
||||
tagSize := (len(tt.result) - len(tt.plaintext)) / 2
|
||||
c, err := sm4.NewCipher(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sm4ccm, err := smcipher.NewCCMWithNonceAndTagSize(c, len(nonce), tagSize)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ct := sm4ccm.Seal(nil, nonce, plaintext, ad)
|
||||
if ctHex := hex.EncodeToString(ct); ctHex != tt.result {
|
||||
t.Errorf("#%d: got %s, want %s", i, ctHex, tt.result)
|
||||
continue
|
||||
}
|
||||
|
||||
//func (c *ccm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error)
|
||||
pt, err := sm4ccm.Open(nil, nonce, ct, ad)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ptHex := hex.EncodeToString(pt); ptHex != tt.plaintext {
|
||||
t.Errorf("#%d: got %s, want %s", i, ptHex, tt.plaintext)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package cipher
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/cipher"
|
||||
)
|
||||
|
||||
// https://tools.ietf.org/html/rfc3610, 8. Test Vectors
|
||||
@ -189,7 +191,7 @@ var aesCCMTests = []struct {
|
||||
},
|
||||
}
|
||||
|
||||
func TestCCM(t *testing.T) {
|
||||
func TestCCMWithAES(t *testing.T) {
|
||||
for i, tt := range aesCCMTests {
|
||||
nonce, _ := hex.DecodeString(tt.nonce)
|
||||
plaintext, _ := hex.DecodeString(tt.plaintext)
|
||||
@ -199,7 +201,7 @@ func TestCCM(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
aesccm, err := NewCCMWithNonceAndTagSize(c, len(nonce), tt.tagSize)
|
||||
aesccm, err := cipher.NewCCMWithNonceAndTagSize(c, len(nonce), tt.tagSize)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -227,20 +229,20 @@ func TestCCMInvalidTagSize(t *testing.T) {
|
||||
c, _ := aes.NewCipher(key)
|
||||
|
||||
for _, tagSize := range []int{0, 1, c.BlockSize() + 1} {
|
||||
aesccm, err := NewCCMWithTagSize(c, tagSize)
|
||||
aesccm, err := cipher.NewCCMWithTagSize(c, tagSize)
|
||||
if aesccm != nil || err == nil {
|
||||
t.Fatalf("NewCCMWithNonceAndTagSize was successful with an invalid %d-byte tag size", tagSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagFailureOverwrite(t *testing.T) {
|
||||
func TestCCMTagFailureOverwrite(t *testing.T) {
|
||||
key, _ := hex.DecodeString("ab72c77b97cb5fe9a382d9fe81ffdbed")
|
||||
nonce, _ := hex.DecodeString("54cc7dc2c37ec006bcc6d1db")
|
||||
ciphertext, _ := hex.DecodeString("0e1bde206a07a9c2c1b65300f8c649972b4401346697138c7a4891ee59867d0c")
|
||||
|
||||
c, _ := aes.NewCipher(key)
|
||||
aesccm, _ := NewCCM(c)
|
||||
aesccm, _ := cipher.NewCCM(c)
|
||||
|
||||
dst := make([]byte, len(ciphertext)-16)
|
||||
for i := range dst {
|
||||
|
107
cipher/cfb_sm4_test.go
Normal file
107
cipher/cfb_sm4_test.go
Normal file
@ -0,0 +1,107 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var cfbTests = []struct {
|
||||
key, iv, plaintext, ciphertext string
|
||||
}{
|
||||
{
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"6bc1bee22e409f96e93d7e117393172a",
|
||||
"bc710d762d070b26361da82b54565e46",
|
||||
},
|
||||
{
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"3B3FD92EB72DAD20333449F8E83CFB4A",
|
||||
"ae2d8a571e03ac9c9eb76fac45af8e51",
|
||||
"945fc8a8241b340d496be6b772d04ee3",
|
||||
},
|
||||
{
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"C8A64537A0B3A93FCDE3CDAD9F1CE58B",
|
||||
"30c81c46a35ce411e5fbc1191a0a52ef",
|
||||
"ebe17f4c9b41ebe026d99ccdbb1e1e0d",
|
||||
},
|
||||
{
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"26751F67A3CBB140B1808CF187A4F4DF",
|
||||
"f69f2445df4f9b17ad2b417be66c3710",
|
||||
"422994eb51eb089f1def710f07324be5",
|
||||
},
|
||||
}
|
||||
|
||||
func TestCFBVectors(t *testing.T) {
|
||||
for i, test := range cfbTests {
|
||||
key, err := hex.DecodeString(test.key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
iv, err := hex.DecodeString(test.iv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plaintext, err := hex.DecodeString(test.plaintext)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected, err := hex.DecodeString(test.ciphertext)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
block, err := sm4.NewCipher(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ciphertext := make([]byte, len(plaintext))
|
||||
cfb := cipher.NewCFBEncrypter(block, iv)
|
||||
cfb.XORKeyStream(ciphertext, plaintext)
|
||||
|
||||
if !bytes.Equal(ciphertext, expected) {
|
||||
t.Errorf("#%d: wrong output: got %x, expected %x", i, ciphertext, expected)
|
||||
}
|
||||
|
||||
cfbdec := cipher.NewCFBDecrypter(block, iv)
|
||||
plaintextCopy := make([]byte, len(ciphertext))
|
||||
cfbdec.XORKeyStream(plaintextCopy, ciphertext)
|
||||
|
||||
if !bytes.Equal(plaintextCopy, plaintext) {
|
||||
t.Errorf("#%d: wrong plaintext: got %x, expected %x", i, plaintextCopy, plaintext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCFBInverse(t *testing.T) {
|
||||
block, err := sm4.NewCipher([]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
plaintext := []byte("this is the plaintext. this is the plaintext.")
|
||||
iv := make([]byte, block.BlockSize())
|
||||
rand.Reader.Read(iv)
|
||||
cfb := cipher.NewCFBEncrypter(block, iv)
|
||||
ciphertext := make([]byte, len(plaintext))
|
||||
copy(ciphertext, plaintext)
|
||||
cfb.XORKeyStream(ciphertext, ciphertext)
|
||||
|
||||
cfbdec := cipher.NewCFBDecrypter(block, iv)
|
||||
plaintextCopy := make([]byte, len(plaintext))
|
||||
copy(plaintextCopy, ciphertext)
|
||||
cfbdec.XORKeyStream(plaintextCopy, plaintextCopy)
|
||||
|
||||
if !bytes.Equal(plaintextCopy, plaintext) {
|
||||
t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
|
||||
}
|
||||
}
|
67
cipher/ctr_sm4_test.go
Normal file
67
cipher/ctr_sm4_test.go
Normal file
@ -0,0 +1,67 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var commonCounter = []byte{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}
|
||||
|
||||
var ctrSM4Tests = []struct {
|
||||
name string
|
||||
key []byte
|
||||
iv []byte
|
||||
in []byte
|
||||
out []byte
|
||||
}{
|
||||
{
|
||||
"2 blocks",
|
||||
[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
|
||||
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
[]byte{
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51},
|
||||
[]byte{
|
||||
0xbc, 0x71, 0x0d, 0x76, 0x2d, 0x07, 0x0b, 0x26, 0x36, 0x1d, 0xa8, 0x2b, 0x54, 0x56, 0x5e, 0x46,
|
||||
0xb0, 0x2b, 0x3d, 0xbd, 0xdd, 0x50, 0xd5, 0xb4, 0x58, 0xae, 0xcc, 0xb2, 0x5d, 0xa1, 0x05, 0xe1},
|
||||
},
|
||||
}
|
||||
|
||||
func TestCTR_SM4(t *testing.T) {
|
||||
for _, tt := range ctrSM4Tests {
|
||||
test := tt.name
|
||||
|
||||
c, err := sm4.NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
|
||||
for j := 0; j <= 5; j += 5 {
|
||||
in := tt.in[0 : len(tt.in)-j]
|
||||
ctr := cipher.NewCTR(c, tt.iv)
|
||||
encrypted := make([]byte, len(in))
|
||||
ctr.XORKeyStream(encrypted, in)
|
||||
if out := tt.out[0:len(in)]; !bytes.Equal(out, encrypted) {
|
||||
t.Errorf("%s/%d: CTR\ninpt %x\nhave %x\nwant %x", test, len(in), in, encrypted, out)
|
||||
}
|
||||
}
|
||||
|
||||
for j := 0; j <= 7; j += 7 {
|
||||
in := tt.out[0 : len(tt.out)-j]
|
||||
ctr := cipher.NewCTR(c, tt.iv)
|
||||
plain := make([]byte, len(in))
|
||||
ctr.XORKeyStream(plain, in)
|
||||
if out := tt.in[0:len(in)]; !bytes.Equal(out, plain) {
|
||||
t.Errorf("%s/%d: CTRReader\nhave %x\nwant %x", test, len(out), plain, out)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
379
cipher/gcm_sm4_test.go
Normal file
379
cipher/gcm_sm4_test.go
Normal file
@ -0,0 +1,379 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var sm4GCMTests = []struct {
|
||||
key, nonce, plaintext, ad, result string
|
||||
}{
|
||||
{
|
||||
"11754cd72aec309bf52f7687212e8957",
|
||||
"3c819d9a9bed087615030b65",
|
||||
"",
|
||||
"",
|
||||
"2179109c88c0659706f7bd4aed0ea10c",
|
||||
},
|
||||
{
|
||||
"ca47248ac0b6f8372a97ac43508308ed",
|
||||
"ffd2b598feabc9019262d2be",
|
||||
"",
|
||||
"",
|
||||
"34e4a2fda29c1d4c1ec1341b4c6cc95f",
|
||||
},
|
||||
{
|
||||
"fbe3467cc254f81be8e78d765a2e6333",
|
||||
"c6697351ff4aec29cdbaabf2",
|
||||
"",
|
||||
"67",
|
||||
"8c39237d769ca5fe5edee9e193c86d7d",
|
||||
},
|
||||
{
|
||||
"8a7f9d80d08ad0bd5a20fb689c88f9fc",
|
||||
"88b7b27d800937fda4f47301",
|
||||
"",
|
||||
"50edd0503e0d7b8c91608eb5a1",
|
||||
"cf15a847573907e399b8f15b362a1572",
|
||||
},
|
||||
{
|
||||
"051758e95ed4abb2cdc69bb454110e82",
|
||||
"c99a66320db73158a35a255d",
|
||||
"",
|
||||
"67c6697351ff4aec29cdbaabf2fbe3467cc254f81be8e78d765a2e63339f",
|
||||
"df05c2ff06ae2a40745b0ef080d433b3",
|
||||
},
|
||||
{
|
||||
"77be63708971c4e240d1cb79e8d77feb",
|
||||
"e0e00f19fed7ba0136a797f3",
|
||||
"",
|
||||
"7a43ec1d9c0a5a78a0b16533a6213cab",
|
||||
"d1cae93ced2525052c4a6d53a2850fa1",
|
||||
},
|
||||
{
|
||||
"7680c5d3ca6154758e510f4d25b98820",
|
||||
"f8f105f9c3df4965780321f8",
|
||||
"",
|
||||
"c94c410194c765e3dcc7964379758ed3",
|
||||
"419289e9e805656dcd110df1875a83e4",
|
||||
},
|
||||
{
|
||||
"7fddb57453c241d03efbed3ac44e371c",
|
||||
"ee283a3fc75575e33efd4887",
|
||||
"d5de42b461646c255c87bd2962d3b9a2",
|
||||
"",
|
||||
"15e29a2a64bfc2974286e0cb84cfc7fa6c5ed60f77e0832fbbd81f07958f3934",
|
||||
},
|
||||
{
|
||||
"ab72c77b97cb5fe9a382d9fe81ffdbed",
|
||||
"54cc7dc2c37ec006bcc6d1da",
|
||||
"007c5e5b3e59df24a7c355584fc1518d",
|
||||
"",
|
||||
"97ce841f7d174d76969fb46b19e742cf28983f4439909cbb6c27662dd4fbbc73",
|
||||
},
|
||||
{ //#9
|
||||
"fe47fcce5fc32665d2ae399e4eec72ba",
|
||||
"5adb9609dbaeb58cbd6e7275",
|
||||
"7c0e88c88899a779228465074797cd4c2e1498d259b54390b85e3eef1c02df60e743f1b840382c4bccaf3bafb4ca8429bea063",
|
||||
"88319d6e1d3ffa5f987199166c8a9b56c2aeba5a",
|
||||
"2276da0e9a4ccaa2a5934c96ba1dc6b0a52b3430ca011b4db4bf6e298b3a58425402952806350fdda7ac20bc38838d7124ee7c333e395b9a94c508b6bf0ce6b2d10d61",
|
||||
},
|
||||
{ //#10
|
||||
"ec0c2ba17aa95cd6afffe949da9cc3a8",
|
||||
"296bce5b50b7d66096d627ef",
|
||||
"b85b3753535b825cbe5f632c0b843c741351f18aa484281aebec2f45bb9eea2d79d987b764b9611f6c0f8641843d5d58f3a242",
|
||||
"f8d00f05d22bf68599bcdeb131292ad6e2df5d14",
|
||||
"3175cd3cb772af34490e4f5203b6a5743cd9b3798c387b7bda2708ff82d520c35d3022767b2d0fe4addff59fb25ead69ca3dd4d73ce1b4cb53a7c4cdc6a4c1fb06c316",
|
||||
},
|
||||
{ //#11
|
||||
"2c1f21cf0f6fb3661943155c3e3d8492",
|
||||
"23cb5ff362e22426984d1907",
|
||||
"42f758836986954db44bf37c6ef5e4ac0adaf38f27252a1b82d02ea949c8a1a2dbc0d68b5615ba7c1220ff6510e259f06655d8",
|
||||
"5d3624879d35e46849953e45a32a624d6a6c536ed9857c613b572b0333e701557a713e3f010ecdf9a6bd6c9e3e44b065208645aff4aabee611b391528514170084ccf587177f4488f33cfb5e979e42b6e1cfc0a60238982a7aec",
|
||||
"9db299bb7f9d6914c4a13589cf41ab014445e4914c1571745d50508bf0f6adeaa41aa4b081a444ee82fed6769da92f5e727d004b21791f961e212a69bfe80af14e7adf",
|
||||
},
|
||||
{ //#12
|
||||
"d9f7d2411091f947b4d6f1e2d1f0fb2e",
|
||||
"e1934f5db57cc983e6b180e7",
|
||||
"73ed042327f70fe9c572a61545eda8b2a0c6e1d6c291ef19248e973aee6c312012f490c2c6f6166f4a59431e182663fcaea05a",
|
||||
"0a8a18a7150e940c3d87b38e73baee9a5c049ee21795663e264b694a949822b639092d0e67015e86363583fcf0ca645af9f43375f05fdb4ce84f411dcbca73c2220dea03a20115d2e51398344b16bee1ed7c499b353d6c597af8",
|
||||
"65c81d83857626a3ec94c913a9f44fa065b6cd61ca5dd6e15e15bb7f16e757202ef966ab1f1e8e6dcbc82f002d29ba6070f53cd79767b1cbcb8cdb656a6a4369f297fc",
|
||||
},
|
||||
{ //#13
|
||||
"fe9bb47deb3a61e423c2231841cfd1fb",
|
||||
"4d328eb776f500a2f7fb47aa",
|
||||
"f1cc3818e421876bb6b8bbd6c9",
|
||||
"",
|
||||
"d8ce306b812aa1b09299ceef804e76b1cb3f736791a5b0d93774d40c2a",
|
||||
},
|
||||
{ //#14
|
||||
"6703df3701a7f54911ca72e24dca046a",
|
||||
"12823ab601c350ea4bc2488c",
|
||||
"793cd125b0b84a043e3ac67717",
|
||||
"",
|
||||
"f42f741a51c02f71a99519f60a55c8dbdcc9a15549158cc1acd6754847",
|
||||
},
|
||||
// These cases test non-standard nonce sizes.
|
||||
{ //#15
|
||||
"1672c3537afa82004c6b8a46f6f0d026",
|
||||
"05",
|
||||
"",
|
||||
"",
|
||||
"65bde02c20351976153d5d2b49790e30",
|
||||
},
|
||||
{ //#16
|
||||
"9a4fea86a621a91ab371e492457796c0",
|
||||
"75",
|
||||
"ca6131faf0ff210e4e693d6c31c109fc5b6f54224eb120f37de31dc59ec669b6",
|
||||
"4f6e2585c161f05a9ae1f2f894e9f0ab52b45d0f",
|
||||
"b86d6055e7e07a664801ccce38172bf7d91dc20babf2c0662d635cc9111ffefb308ee64ce01afe544b6ee1a65b803cb9",
|
||||
},
|
||||
{ //#17
|
||||
"d0f1f4defa1e8c08b4b26d576392027c",
|
||||
"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
|
||||
"",
|
||||
"",
|
||||
"1edcf8ea546af4879379e7653c53dddc",
|
||||
},
|
||||
{ //#18
|
||||
"4a0c00a3d284dea9d4bf8b8dde86685e",
|
||||
"f8cbe82588e784bcacbe092cd9089b51e01527297f635bf294b3aa787d91057ef23869789698ac960707857f163ecb242135a228ad93964f5dc4a4d7f88fd7b3b07dd0a5b37f9768fb05a523639f108c34c661498a56879e501a2321c8a4a94d7e1b89db255ac1f685e185263368e99735ebe62a7f2931b47282be8eb165e4d7",
|
||||
"6d4bf87640a6a48a50d28797b7",
|
||||
"8d8c7ffc55086d539b5a8f0d1232654c",
|
||||
"193952a26ab455b3c16db216bb2597cba90a9946dec5b7d085ceb7408e",
|
||||
},
|
||||
{ //#19
|
||||
"0e18a844ac5bf38e4cd72d9b0942e506",
|
||||
"0870d4b28a2954489a0abcd5",
|
||||
"67c6697351ff4aec29cdbaabf2fbe3467cc254f81be8e78d765a2e63339fc99a66320db73158a35a255d051758e95ed4abb2cdc69bb454110e827441213ddc8770e93ea141e1fc673e017e97eadc6b968f385c2aecb03bfb32af3c54ec18db5c021afe43fbfaaa3afb29d1e6053c7c9475d8be6189f95cbba8990f95b1ebf1b3",
|
||||
"05eff700e9a13ae5ca0bcbd0484764bd1f231ea81c7b64c514735ac55e4b79633b706424119e09dcaad4acf21b10af3b33cde3504847155cbb6f2219ba9b7df50be11a1c7f23f829f8a41b13b5ca4ee8983238e0794d3d34bc5f4e77facb6c05ac86212baa1a55a2be70b5733b045cd33694b3afe2f0e49e4f321549fd824ea9",
|
||||
"f492d37084697e941acd69c3d8b53d91760f4bced0fdff529327fb03000b865fbf87133c5816bdafdd23013f1440a30835b7e4d57bb6660e14b438b19b5b07a03f74369f2a11a163e5fcc4fd7ea139982ccf589533011d8efab4a44f6154043099b39f19754a4f434290299c2faa838b92453a1b989f354e7b50ea558daf1f6a88ea50b481a4ffcdd634f324f27cb3f6",
|
||||
},
|
||||
{ //#20
|
||||
"1f6c3a3bc0542aabba4ef8f6c7169e73",
|
||||
"f3584606472b260e0dd2ebb2",
|
||||
"67c6697351ff4aec29cdbaabf2fbe3467cc254f81be8e78d765a2e63339fc99a66320db73158a35a255d051758e95ed4abb2cdc69bb454110e827441213ddc8770e93ea141e1fc673e017e97eadc6b968f385c2aecb03bfb32af3c54ec18db5c021afe43fbfaaa3afb29d1e6053c7c9475d8be6189f95cbba8990f95b1ebf1b305eff700e9a13ae5ca0bcbd0484764bd1f231ea81c7b64c514735ac55e4b79633b706424119e09dcaad4acf21b10af3b33cde3504847155cbb6f2219ba9b7df50be11a1c7f23f829f8a41b13b5ca4ee8983238e0794d3d34bc5f4e77facb6c05ac86212baa1a55a2be70b5733b045cd33694b3afe2f0e49e4f321549fd824ea90870d4b28a2954489a0abcd50e18a844ac5bf38e4cd72d9b0942e506c433afcda3847f2dadd47647de321cec4ac430f62023856cfbb20704f4ec0bb920ba86c33e05f1ecd96733b79950a3e314d3d934f75ea0f210a8f6059401beb4bc4478fa4969e623d01ada696a7e4c7e5125b34884533a94fb319990325744ee9bbce9e525cf08f5e9e25e5360aad2b2d085fa54d835e8d466826498d9a8877565705a8a3f62802944de7ca5894e5759d351adac869580ec17e485f18c0c66f17cc07cbb22fce466da610b63af62bc83b4692f3affaf271693ac071fb86d11342d8def4f89d4b66335c1c7e4248367d8ed9612ec453902d8e50af89d7709d1a596c1f41f",
|
||||
"95aa82ca6c49ae90cd1668baac7aa6f2b4a8ca99b2c2372acb08cf61c9c3805e6e0328da4cd76a19edd2d3994c798b0022569ad418d1fee4d9cd45a391c601ffc92ad91501432fee150287617c13629e69fc7281cd7165a63eab49cf714bce3a75a74f76ea7e64ff81eb61fdfec39b67bf0de98c7e4e32bdf97c8c6ac75ba43c02f4b2ed7216ecf3014df000108b67cf99505b179f8ed4980a6103d1bca70dbe9bbfab0ed59801d6e5f2d6f67d3ec5168e212e2daf02c6b963c98a1f7097de0c56891a2b211b01070dd8fd8b16c2a1a4e3cfd292d2984b3561d555d16c33ddc2bcf7edde13efe520c7e2abdda44d81881c531aeeeb66244c3b791ea8acfb6a68",
|
||||
"c40924873aa2ef1b1b7bf4e16576446b4d24ab529c3f526cdbf7ea1cf64a73f26e4077d1464d1af165b26138ae65281dc3ca0d0998cce7b3c4fe2de5007c5c47ae586016fb11eb1b5ee1f775005b00f2c030c22fbebffc4c7fb3f4ae5b0032e7ab79b3fa48e17bb576486ba73ada0322577efd52b79f229da7e05d00a215ab3a1d717ede7c383c2eff400c4fd13c2eb6dd9e4165f67a7f5260619e459d7d9e2d276f44839ea1ec8bcc460a94b759b12b49f49ba350dab04313953d9ac0a8ac2fdd2b5cbfc70c62cdfaea658427afdc7a8a86c6a3b85c795364077fab193e87965a2cc45cbc82656e62410f027b79276317d7a1a81ebc721af6174f34e7d524c2b333e9802d2ecebec414bbdecd4587bc15079001ef140d65f689bb8f686cd670376d1e579a23fc5d098137ef2f11ec4413fcc308e689f4fcb11bde15c657651ee82694cdb676a286b2059fdf41210eceb9f03c3add1e316495a613d85e9126f4e4ba4565a2465fe578587748476360e353c2cd0e880100be8821ddae242f54efb4e7079420312443834db98e9252456b97cd1925880fffba64b0fcf2c8c05f49e0739c78df846975d99d8072b7c3c2ed5df96cdc3ad3a5dfb9d9fa8a73154765f33ca68a64bfced57391bd54250d5681aa09c28970f1fad0627205a0ea68e02bba7edb8e4f2468d70c879a585461349637639887d41f3206da7421bba36c142947a5bfa91ed341b466f8f6c8c12af0f2",
|
||||
},
|
||||
{ //#21
|
||||
"0795d80bc7f40f4d41c280271a2e4f7f",
|
||||
"ff824c906594aff365d3cb1f",
|
||||
"1ad4e74d127f935beee57cff920665babe7ce56227377afe570ba786193ded3412d4812453157f42fafc418c02a746c1232c234a639d49baa8f041c12e2ef540027764568ce49886e0d913e28059a3a485c6eee96337a30b28e4cd5612c2961539fa6bc5de034cbedc5fa15db844013e0bef276e27ca7a4faf47a5c1093bd643354108144454d221b3737e6cb87faac36ed131959babe44af2890cfcc4e23ffa24470e689ce0894f5407bb0c8665cff536008ad2ac6f1c9ef8289abd0bd9b72f21c597bda5210cf928c805af2dd4a464d52e36819d521f967bba5386930ab5b4cf4c71746d7e6e964673457348e9d71d170d9eb560bd4bdb779e610ba816bf776231ebd0af5966f5cdab6815944032ab4dd060ad8dab880549e910f1ffcf6862005432afad",
|
||||
"98a47a430d8fd74dc1829a91e3481f8ed024d8ba34c9b903321b04864db333e558ae28653dffb2",
|
||||
"598798e51e3b70677ee1cd17c25dd6a4752f42aa51b2d055df9992e46afc8e48ac0e99f645bbab4388bc22bc674ecd3bea4f59dbe77a3e33f1b66d751f2772b59eb462443d2de8f27cbf057b8e00c000e2653a597c440cdd3a87a83f7a2f26f3966ba26fc60c05de7da075e635fdd3b5fefa816398855e099ab746278fc57f65b7573f5372a676ca5a9835d0e158f16201ea16fb6685da1829cffc6cea57a9937e822dc6becd7679239c55df5b88caa91522eeb3223dd9357d374a5b3be015624ca21ff667f427d94e9c5cd6e9ec227d3fb2b8c3835dfe5cd8949da744f8d30470a5f36dc33f3f57586ff9e4f117d94b1d1a94318a7cecb61f0386b2e34d4d39e965640e2fc211f34552352ef1df24f409583f82d4b259bf0f9358c3330bea2a2cab2fd303d8cd22abce5339576d8a6736f46589d8",
|
||||
},
|
||||
// These cases test non-standard tag sizes.
|
||||
{ //#22
|
||||
"89c54b0d3bc3c397d5039058c220685f",
|
||||
"bc7f45c00868758d62d4bb4d",
|
||||
"582670b0baf5540a3775b6615605bd05",
|
||||
"48d16cda0337105a50e2ed76fd18e114",
|
||||
"6e37e818153f115f2fab4c890f3eac139a3ee8b30bf2cbcb54c39ff0651313",
|
||||
},
|
||||
{ //#23
|
||||
"bad6049678bf75c9087b3e3ae7e72c13",
|
||||
"a0a017b83a67d8f1b883e561",
|
||||
"a1be93012f05a1958440f74a5311f4a1",
|
||||
"f7c27b51d5367161dc2ff1e9e3edc6f2",
|
||||
"baa7c826af7983e1824558e7e31d04063543c8a5e80eb58af0e38b7a1581",
|
||||
},
|
||||
{ //#24
|
||||
"66a3c722ccf9709525650973ecc100a9",
|
||||
"1621d42d3a6d42a2d2bf9494",
|
||||
"61fa9dbbed2190fbc2ffabf5d2ea4ff8",
|
||||
"d7a9b6523b8827068a6354a6d166c6b9",
|
||||
"4e920aff4744aef585b81c80fe962231d13d8f7f03e56a06cb33d12491",
|
||||
},
|
||||
{ //#25
|
||||
"562ae8aadb8d23e0f271a99a7d1bd4d1",
|
||||
"f7a5e2399413b89b6ad31aff",
|
||||
"bbdc3504d803682aa08a773cde5f231a",
|
||||
"2b9680b886b3efb7c6354b38c63b5373",
|
||||
"716a4e0150125a51e72f95d900814fc37b0ddba2a85bda1f8819b774",
|
||||
},
|
||||
{ //#26
|
||||
"11754cd72aec309bf52f7687212e8957",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"250327c674aaf477aef2675748cf6971",
|
||||
},
|
||||
{ // https://tools.ietf.org/html/rfc8998 A.1. SM4-GCM Test Vectors
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"00001234567800000000abcd",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"17f399f08c67d5ee19d0dc9969c4bb7d5fd46fd3756489069157b282bb200735d82710ca5c22f0ccfa7cbf93d496ac15a56834cbcf98c397b4024a2691233b8d83de3541e4c2b58177e065a9bf7b62ec",
|
||||
},
|
||||
}
|
||||
|
||||
func TestSM4GCM(t *testing.T) {
|
||||
for i, test := range sm4GCMTests {
|
||||
key, _ := hex.DecodeString(test.key)
|
||||
c, err := sm4.NewCipher(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
nonce, _ := hex.DecodeString(test.nonce)
|
||||
plaintext, _ := hex.DecodeString(test.plaintext)
|
||||
ad, _ := hex.DecodeString(test.ad)
|
||||
tagSize := (len(test.result) - len(test.plaintext)) / 2
|
||||
|
||||
var sm4gcm cipher.AEAD
|
||||
switch {
|
||||
// Handle non-standard tag sizes
|
||||
case tagSize != 16:
|
||||
sm4gcm, err = cipher.NewGCMWithTagSize(c, tagSize)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Handle 0 nonce size (expect error and continue)
|
||||
case len(nonce) == 0:
|
||||
sm4gcm, err = cipher.NewGCMWithNonceSize(c, 0)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for zero nonce size")
|
||||
}
|
||||
continue
|
||||
|
||||
// Handle non-standard nonce sizes
|
||||
case len(nonce) != 12:
|
||||
sm4gcm, err = cipher.NewGCMWithNonceSize(c, len(nonce))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
default:
|
||||
sm4gcm, err = cipher.NewGCM(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
ct := sm4gcm.Seal(nil, nonce, plaintext, ad)
|
||||
if ctHex := hex.EncodeToString(ct); ctHex != test.result {
|
||||
t.Errorf("#%d: got %s, want %s", i, ctHex, test.result)
|
||||
continue
|
||||
}
|
||||
|
||||
plaintext2, err := sm4gcm.Open(nil, nonce, ct, ad)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: Open failed", i)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(plaintext, plaintext2) {
|
||||
t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(ad) > 0 {
|
||||
ad[0] ^= 0x80
|
||||
if _, err := sm4gcm.Open(nil, nonce, ct, ad); err == nil {
|
||||
t.Errorf("#%d: Open was successful after altering additional data", i)
|
||||
}
|
||||
ad[0] ^= 0x80
|
||||
}
|
||||
|
||||
nonce[0] ^= 0x80
|
||||
if _, err := sm4gcm.Open(nil, nonce, ct, ad); err == nil {
|
||||
t.Errorf("#%d: Open was successful after altering nonce", i)
|
||||
}
|
||||
nonce[0] ^= 0x80
|
||||
|
||||
ct[0] ^= 0x80
|
||||
if _, err := sm4gcm.Open(nil, nonce, ct, ad); err == nil {
|
||||
t.Errorf("#%d: Open was successful after altering ciphertext", i)
|
||||
}
|
||||
ct[0] ^= 0x80
|
||||
}
|
||||
}
|
||||
|
||||
func TestGCMInvalidTagSize(t *testing.T) {
|
||||
key, _ := hex.DecodeString("ab72c77b97cb5fe9a382d9fe81ffdbed")
|
||||
|
||||
c, _ := sm4.NewCipher(key)
|
||||
|
||||
for _, tagSize := range []int{0, 1, c.BlockSize() + 1} {
|
||||
aesgcm, err := cipher.NewGCMWithTagSize(c, tagSize)
|
||||
if aesgcm != nil || err == nil {
|
||||
t.Fatalf("NewGCMWithNonceAndTagSize was successful with an invalid %d-byte tag size", tagSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagFailureOverwrite(t *testing.T) {
|
||||
// The AESNI GCM code decrypts and authenticates concurrently and so
|
||||
// overwrites the output buffer before checking the authentication tag.
|
||||
// In order to be consistent across platforms, all implementations
|
||||
// should do this and this test checks that.
|
||||
|
||||
key, _ := hex.DecodeString("ab72c77b97cb5fe9a382d9fe81ffdbed")
|
||||
nonce, _ := hex.DecodeString("54cc7dc2c37ec006bcc6d1db")
|
||||
ciphertext, _ := hex.DecodeString("0e1bde206a07a9c2c1b65300f8c649972b4401346697138c7a4891ee59867d0c")
|
||||
|
||||
c, _ := sm4.NewCipher(key)
|
||||
sm4gcm, _ := cipher.NewGCM(c)
|
||||
|
||||
dst := make([]byte, len(ciphertext)-16)
|
||||
for i := range dst {
|
||||
dst[i] = 42
|
||||
}
|
||||
|
||||
result, err := sm4gcm.Open(dst[:0], nonce, ciphertext, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Bad Open still resulted in nil error.")
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
t.Fatal("Failed Open returned non-nil result.")
|
||||
}
|
||||
|
||||
for i := range dst {
|
||||
if dst[i] != 0 {
|
||||
t.Fatal("Failed Open didn't zero dst buffer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGCMCounterWrap(t *testing.T) {
|
||||
// Test that the last 32-bits of the counter wrap correctly.
|
||||
tests := []struct {
|
||||
nonce, tag string
|
||||
}{
|
||||
{"0fa72e25", "07d6369bf22b6507a736f19972b5a0e3"}, // counter: 7eb59e4d961dad0dfdd75aaffffffff0
|
||||
{"afe05cc1", "36e0538ec7fda19fc98621f3de9de166"}, // counter: 75d492a7e6e6bfc979ad3a8ffffffff4
|
||||
{"9ffecbef", "aac0fd90f5acaf9db1412d059bfedd92"}, // counter: c8bb108b0ecdc71747b9d57ffffffff5
|
||||
{"ffc3e5b3", "10e9b0f8088e320a75c4512f2bcfa5fd"}, // counter: 706414d2de9b36ab3b900a9ffffffff6
|
||||
{"cfdd729d", "afee327e47b1d4e7c6da27a0fdde1544"}, // counter: cd0b96fe36b04e750584e56ffffffff7
|
||||
{"010ae3d486", "ecc0e9cc4a92aa4804a5fd6a909eec7d"}, // counter: e36c18e69406c49722808104fffffff8
|
||||
{"01b1107a9d", "27785ab3613dd235e2daa8d3244e7869"}, // counter: e6d56eaf9127912b6d62c6dcffffffff
|
||||
}
|
||||
key, err := sm4.NewCipher(make([]byte, 16))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
plaintext := make([]byte, 16*17+1)
|
||||
for i, test := range tests {
|
||||
nonce, _ := hex.DecodeString(test.nonce)
|
||||
want, _ := hex.DecodeString(test.tag)
|
||||
aead, err := cipher.NewGCMWithNonceSize(key, len(nonce))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := aead.Seal(nil, nonce, plaintext, nil)
|
||||
if !bytes.Equal(got[len(plaintext):], want) {
|
||||
t.Errorf("test[%v]: got: %x, want: %x", i, got[len(plaintext):], want)
|
||||
}
|
||||
_, err = aead.Open(nil, nonce, got, nil)
|
||||
if err != nil {
|
||||
t.Errorf("test[%v]: authentication failed", i)
|
||||
}
|
||||
}
|
||||
}
|
73
cipher/ofb_sm4_test.go
Normal file
73
cipher/ofb_sm4_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
type ofbTest struct {
|
||||
name string
|
||||
key []byte
|
||||
iv []byte
|
||||
in []byte
|
||||
out []byte
|
||||
}
|
||||
|
||||
var ofbTests = []ofbTest{
|
||||
{
|
||||
"OFB-SM4",
|
||||
[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
|
||||
[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
|
||||
[]byte{
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
|
||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
|
||||
},
|
||||
[]byte{
|
||||
0xbc, 0x71, 0x0d, 0x76, 0x2d, 0x07, 0x0b, 0x26, 0x36, 0x1d, 0xa8, 0x2b, 0x54, 0x56, 0x5e, 0x46,
|
||||
0x07, 0xa0, 0xc6, 0x28, 0x34, 0x74, 0x0a, 0xd3, 0x24, 0x0d, 0x23, 0x91, 0x25, 0xe1, 0x16, 0x21,
|
||||
0xd4, 0x76, 0xb2, 0x1c, 0xc9, 0xf0, 0x49, 0x51, 0xf0, 0x74, 0x1d, 0x2e, 0xf9, 0xe0, 0x94, 0x98,
|
||||
0x15, 0x84, 0xfc, 0x14, 0x2b, 0xf1, 0x3a, 0xa6, 0x26, 0xb8, 0x2f, 0x9d, 0x7d, 0x07, 0x6c, 0xce,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestOFB(t *testing.T) {
|
||||
for _, tt := range ofbTests {
|
||||
test := tt.name
|
||||
|
||||
c, err := sm4.NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
|
||||
for j := 0; j <= 5; j += 5 {
|
||||
plaintext := tt.in[0 : len(tt.in)-j]
|
||||
ofb := cipher.NewOFB(c, tt.iv)
|
||||
ciphertext := make([]byte, len(plaintext))
|
||||
ofb.XORKeyStream(ciphertext, plaintext)
|
||||
if !bytes.Equal(ciphertext, tt.out[:len(plaintext)]) {
|
||||
t.Errorf("%s/%d: encrypting\ninput % x\nhave % x\nwant % x", test, len(plaintext), plaintext, ciphertext, tt.out)
|
||||
}
|
||||
}
|
||||
|
||||
for j := 0; j <= 5; j += 5 {
|
||||
ciphertext := tt.out[0 : len(tt.in)-j]
|
||||
ofb := cipher.NewOFB(c, tt.iv)
|
||||
plaintext := make([]byte, len(ciphertext))
|
||||
ofb.XORKeyStream(plaintext, ciphertext)
|
||||
if !bytes.Equal(plaintext, tt.in[:len(ciphertext)]) {
|
||||
t.Errorf("%s/%d: decrypting\nhave % x\nwant % x", test, len(ciphertext), plaintext, tt.in)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
93
cipher/xts_sm4_test.go
Normal file
93
cipher/xts_sm4_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/cipher"
|
||||
"github.com/emmansun/gmsm/sm4"
|
||||
)
|
||||
|
||||
var xtsTestVectors = []struct {
|
||||
key string
|
||||
sector uint64
|
||||
plaintext string
|
||||
ciphertext string
|
||||
}{
|
||||
{ // XTS-SM4-128 applied for a data unit of 32 bytes
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
0,
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"d9b421f731c894fdc35b77291fe4e3b02a1fb76698d59f0e51376c4ada5bc75d",
|
||||
}, {
|
||||
"1111111111111111111111111111111122222222222222222222222222222222",
|
||||
0x3333333333,
|
||||
"4444444444444444444444444444444444444444444444444444444444444444",
|
||||
"a74d726c11196a32be04e001ff29d0c7932f9f3ec29bfcb64dd17f63cbd3ea31",
|
||||
}, {
|
||||
"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f022222222222222222222222222222222",
|
||||
0x3333333333,
|
||||
"4444444444444444444444444444444444444444444444444444444444444444",
|
||||
"7f76088effadf70c02ea9f95da0628d351bfcb9eac0563bcf17b710dab0a9826",
|
||||
}, { // XTS-SM4-128 applied for a data unit of 512 bytes
|
||||
"2718281828459045235360287471352631415926535897932384626433832795",
|
||||
0,
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
|
||||
"54dd65b6326faea8fad1a83c63614af39f721d8dfe177a30b66abf6a449980e1cdbe06afb73336f37a4d39de964a30d7d04a3799169c60258f6b748a61861aa5ec92a2c15b2b7c615a42aba499bbd6b71db9c789b2182089a25dd3df800ed1864d19f7ed45fd17a9480b0fb82d9b7fc3ed57e9a1140eaa778dd2dd679e3edc3dc4d55c950ebc531d9592f7c4638256d56518292a20af98fdd3a63600350a70ab5a40f4c285037ca01f251f19ecae0329ff77ad88cd5a4cdea2aeabc22148ffbd239bd10515bde1131dec8404e443dc763140d5f22bf33e0c6872d6b81d630f6f00cdd058fe80f9cbfb77707f93cee2ca92b915b8304027c190a84e2d65e018cc6a387d3766acdb28253284e8db9acf8f52280ddc6d0033d2ccaaa4f9aeff123669bc024fd6768edf8bc1f8d622c19c609ef97f609190cd110241e7fb084ed8942da1f9b9cf1b514b61a388b30ea61a4a745b381ee7ad6c4db1275453b8413f98df6e4a40986ee4b59af5dfaecd301265179067a00d7ca35ab95abd617adea28ec1c26a97de28b8bfe30120d6aefbd258c59e42d161e8065a78106bdca5cd90fb3aac4e93866c8a7f9676860a79145bd92e02e819a90be0b97cc522b32106856fdf0e54d88e4624155a2f1c14eaeaa163f858e99a806e791acd82f1b0e29f0028a4c38e976f571a93f4fd57d787c24db0e01ca304e5a5c4dd50cf8bdbf491e57c",
|
||||
}, { // Vector 5
|
||||
"2718281828459045235360287471352631415926535897932384626433832795",
|
||||
1,
|
||||
"27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568",
|
||||
"0e36ba273dd121afc77e0d8c00aa4a662b21f363470d333f2fe2ddcbcc51ecd523022f5fa7970062800cd3859cacead369263681543db431f3844a3638e837cf025cecc3b778e14ac1fd02bb684d0e3cc3d05758cf4b3827bae92f9f09a45487e0a830154a4206a14c4077bcc928e6039b78cdf8f915236c5a4efc21a0ba7173232cef6f18f8b53be5e1eb37282bed31a24f322cf1bba02dfd2583ce216a73726915116fd8ce46d58aa562b5a5d88076792d6e35cba40552db6a19776eaf255c3fc927adc41cb83a83884f98176267f37e543ce34fa32960d1d05aa05ff04103037a730175f1d59a32b64f308925fc9fa9c60421b4ab438e14504227cba20c8c06b508554fb02e52b92a1cd0a8e386511bc4c2fb62998d0ac5d9e7614080a10039b8cddf24a644b3e0aa02bb5d6c0897a84bfe0d12690cbd9fb92fd39b5b9504deeeaab0c5b9839b6283b87abe6439d28f0afb0508104fd4db9fd6e0301c6a488e76fd2a4801d2b7df57e0179506e9a8dbd7312be3922ea4e7339227061485452296dabc3b0f178a2e4ba012bbb6e836dec5d25abaa0f399ca622c5f075dfae7b2ffef4e396cd74b9bc3aeb7c212a5fd5c42b73fcf92e1f4ca458bb50e7257c4ffea253f30f7eaf9a6762ce15177f55ba250a4293d6ecdbd2e9a80c942b38dbdbd74773245a7a7db6b91d1f6c74bd32b7a7a193a2d260d266b64dd19b959ae42",
|
||||
}, { // XTS-SM4-128 applied for a data unit that is not a multiple of 16 bytes, but should be a complte byte
|
||||
"c46acc2e7e013cb71cdbf750cf76b000249fbf4fb6cd17607773c23ffa2c4330",
|
||||
94,
|
||||
"7e9c2289cba460e470222953439cdaa892a5433d4dab2a3f67",
|
||||
"c3cf5445c64aa518f4abce2848faddfb4605d9fb66f1f12c0c",
|
||||
}, {
|
||||
"56ffcc9bbbdf413f0fc0f888f44b7493bb1925a39b8adf02d9009bb16db0a887",
|
||||
144,
|
||||
"9a839cc14363bafcfc0cc93b14f8e769d35b94cc98267438e3",
|
||||
"af027012c829206c32a31706999d046f10a83bcacbc5c96353",
|
||||
},
|
||||
{
|
||||
"7454a43b87b1cf0dec95032c22873be3cace3bb795568854c1a008c07c5813f3",
|
||||
108,
|
||||
"41088fa15195b2733fe824d2c1fdc8306080863945fb2a73cf",
|
||||
"614ee9311a53791889338eb2f66fedff7dc15126349bed1465",
|
||||
},
|
||||
}
|
||||
|
||||
func fromHex(s string) []byte {
|
||||
ret, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("xts: invalid hex in test")
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func TestXTS(t *testing.T) {
|
||||
for i, test := range xtsTestVectors {
|
||||
c, err := cipher.NewXTS(sm4.NewCipher, fromHex(test.key))
|
||||
if err != nil {
|
||||
t.Errorf("#%d: failed to create cipher: %s", i, err)
|
||||
continue
|
||||
}
|
||||
plaintext := fromHex(test.plaintext)
|
||||
ciphertext := make([]byte, len(plaintext))
|
||||
|
||||
c.Encrypt(ciphertext, plaintext, test.sector)
|
||||
expectedCiphertext := fromHex(test.ciphertext)
|
||||
if !bytes.Equal(ciphertext, expectedCiphertext) {
|
||||
t.Errorf("#%d: encrypted failed, got: %x, want: %x", i, ciphertext, expectedCiphertext)
|
||||
continue
|
||||
}
|
||||
|
||||
decrypted := make([]byte, len(ciphertext))
|
||||
c.Decrypt(decrypted, ciphertext, test.sector)
|
||||
if !bytes.Equal(decrypted, plaintext) {
|
||||
t.Errorf("#%d: decryption failed, got: %x, want: %x", i, decrypted, plaintext)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
package cipher
|
||||
package cipher_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/emmansun/gmsm/cipher"
|
||||
)
|
||||
|
||||
// These test vectors have been taken from IEEE P1619/D16, Annex B.
|
||||
var xtsTestVectors = []struct {
|
||||
var xtsAesTestVectors = []struct {
|
||||
key string
|
||||
sector uint64
|
||||
plaintext string
|
||||
@ -63,17 +64,9 @@ var xtsTestVectors = []struct {
|
||||
},
|
||||
}
|
||||
|
||||
func fromHex(s string) []byte {
|
||||
ret, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("xts: invalid hex in test")
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func TestXTS(t *testing.T) {
|
||||
for i, test := range xtsTestVectors {
|
||||
c, err := NewXTS(aes.NewCipher, fromHex(test.key))
|
||||
func TestXTSWithAES(t *testing.T) {
|
||||
for i, test := range xtsAesTestVectors {
|
||||
c, err := cipher.NewXTS(aes.NewCipher, fromHex(test.key))
|
||||
if err != nil {
|
||||
t.Errorf("#%d: failed to create cipher: %s", i, err)
|
||||
continue
|
||||
@ -97,7 +90,7 @@ func TestXTS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestShorterCiphertext(t *testing.T) {
|
||||
c, err := NewXTS(aes.NewCipher, make([]byte, 32))
|
||||
c, err := cipher.NewXTS(aes.NewCipher, make([]byte, 32))
|
||||
if err != nil {
|
||||
t.Fatalf("NewCipher failed: %s", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user