795 lines
20 KiB
Go
795 lines
20 KiB
Go
package xcipher
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/aes"
|
||
"crypto/cipher"
|
||
"crypto/rand"
|
||
"encoding/binary"
|
||
"fmt"
|
||
"io"
|
||
"io/ioutil"
|
||
"runtime"
|
||
"testing"
|
||
|
||
"golang.org/x/crypto/chacha20poly1305"
|
||
)
|
||
|
||
var (
|
||
benchmarkKey = make([]byte, chacha20poly1305.KeySize)
|
||
benchmarkAESKey = make([]byte, 32) // 256-bit AES key
|
||
benchmarkSmallData = make([]byte, 1024) // 1KB
|
||
benchmarkMediumData = make([]byte, 64*1024) // 64KB
|
||
benchmarkLargeData = make([]byte, 1024*1024) // 1MB
|
||
benchmarkHugeData = make([]byte, 10*1024*1024) // 10MB
|
||
)
|
||
|
||
func init() {
|
||
// 初始化测试数据
|
||
rand.Read(benchmarkKey)
|
||
rand.Read(benchmarkAESKey)
|
||
rand.Read(benchmarkSmallData)
|
||
rand.Read(benchmarkMediumData)
|
||
rand.Read(benchmarkLargeData)
|
||
rand.Read(benchmarkHugeData)
|
||
}
|
||
|
||
// 标准库 ChaCha20Poly1305 实现
|
||
func encryptWithStdChaCha20Poly1305(plaintext, additionalData []byte) ([]byte, error) {
|
||
aead, err := chacha20poly1305.NewX(benchmarkKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
nonce := make([]byte, chacha20poly1305.NonceSizeX)
|
||
if _, err := rand.Read(nonce); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
ciphertext := aead.Seal(nil, nonce, plaintext, additionalData)
|
||
result := make([]byte, len(nonce)+len(ciphertext))
|
||
copy(result, nonce)
|
||
copy(result[len(nonce):], ciphertext)
|
||
return result, nil
|
||
}
|
||
|
||
func decryptWithStdChaCha20Poly1305(ciphertext, additionalData []byte) ([]byte, error) {
|
||
aead, err := chacha20poly1305.NewX(benchmarkKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
if len(ciphertext) < chacha20poly1305.NonceSizeX {
|
||
return nil, fmt.Errorf("ciphertext too short")
|
||
}
|
||
|
||
nonce := ciphertext[:chacha20poly1305.NonceSizeX]
|
||
encrypted := ciphertext[chacha20poly1305.NonceSizeX:]
|
||
|
||
return aead.Open(nil, nonce, encrypted, additionalData)
|
||
}
|
||
|
||
// 标准库 AES-GCM 实现
|
||
func encryptWithAESGCM(plaintext, additionalData []byte) ([]byte, error) {
|
||
block, err := aes.NewCipher(benchmarkAESKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
aead, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
nonce := make([]byte, aead.NonceSize())
|
||
if _, err := rand.Read(nonce); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
ciphertext := aead.Seal(nil, nonce, plaintext, additionalData)
|
||
result := make([]byte, len(nonce)+len(ciphertext))
|
||
copy(result, nonce)
|
||
copy(result[len(nonce):], ciphertext)
|
||
return result, nil
|
||
}
|
||
|
||
func decryptWithAESGCM(ciphertext, additionalData []byte) ([]byte, error) {
|
||
block, err := aes.NewCipher(benchmarkAESKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
aead, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
if len(ciphertext) < aead.NonceSize() {
|
||
return nil, fmt.Errorf("ciphertext too short")
|
||
}
|
||
|
||
nonce := ciphertext[:aead.NonceSize()]
|
||
encrypted := ciphertext[aead.NonceSize():]
|
||
|
||
return aead.Open(nil, nonce, encrypted, additionalData)
|
||
}
|
||
|
||
// XCipher 流式加密的标准库模拟实现
|
||
func streamEncryptWithStdChaCha20Poly1305(r io.Reader, w io.Writer, additionalData []byte) error {
|
||
aead, err := chacha20poly1305.NewX(benchmarkKey)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 写入基础随机数
|
||
baseNonce := make([]byte, chacha20poly1305.NonceSizeX)
|
||
if _, err := rand.Read(baseNonce); err != nil {
|
||
return err
|
||
}
|
||
if _, err := w.Write(baseNonce); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 分块处理
|
||
buffer := make([]byte, 64*1024) // 64KB 缓冲区
|
||
blockNonce := make([]byte, chacha20poly1305.NonceSizeX)
|
||
copy(blockNonce, baseNonce)
|
||
counter := uint64(0)
|
||
|
||
for {
|
||
n, err := r.Read(buffer)
|
||
if err != nil && err != io.EOF {
|
||
return err
|
||
}
|
||
|
||
if n > 0 {
|
||
// 为每个块创建唯一的随机数
|
||
binary.LittleEndian.PutUint64(blockNonce[chacha20poly1305.NonceSizeX-8:], counter)
|
||
counter++
|
||
|
||
// 加密数据块
|
||
sealed := aead.Seal(nil, blockNonce, buffer[:n], additionalData)
|
||
|
||
// 写入加密数据块长度
|
||
lengthBytes := make([]byte, 4)
|
||
binary.BigEndian.PutUint32(lengthBytes, uint32(len(sealed)))
|
||
if _, err := w.Write(lengthBytes); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 写入加密数据
|
||
if _, err := w.Write(sealed); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// 标准库模拟流式解密实现
|
||
func streamDecryptWithStdChaCha20Poly1305(r io.Reader, w io.Writer, additionalData []byte) error {
|
||
aead, err := chacha20poly1305.NewX(benchmarkKey)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 读取基础随机数
|
||
baseNonce := make([]byte, chacha20poly1305.NonceSizeX)
|
||
if _, err := io.ReadFull(r, baseNonce); err != nil {
|
||
return fmt.Errorf("failed to read nonce: %v", err)
|
||
}
|
||
|
||
// 准备读取数据块
|
||
blockNonce := make([]byte, chacha20poly1305.NonceSizeX)
|
||
copy(blockNonce, baseNonce)
|
||
counter := uint64(0)
|
||
lengthBuf := make([]byte, 4)
|
||
|
||
for {
|
||
// 读取数据块长度
|
||
_, err := io.ReadFull(r, lengthBuf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
|
||
// 解析数据块长度
|
||
blockLen := binary.BigEndian.Uint32(lengthBuf)
|
||
encBuffer := make([]byte, blockLen)
|
||
|
||
// 读取加密数据块
|
||
_, err = io.ReadFull(r, encBuffer)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 为每个块创建唯一的随机数
|
||
binary.LittleEndian.PutUint64(blockNonce[chacha20poly1305.NonceSizeX-8:], counter)
|
||
counter++
|
||
|
||
// 解密数据块
|
||
decrypted, err := aead.Open(nil, blockNonce, encBuffer, additionalData)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 写入解密数据
|
||
if _, err := w.Write(decrypted); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// 对比基本加密性能
|
||
func BenchmarkCompareEncrypt(b *testing.B) {
|
||
testCases := []struct {
|
||
name string
|
||
size int
|
||
data []byte
|
||
}{
|
||
{"Small_1KB", 1 * 1024, benchmarkSmallData},
|
||
{"Medium_64KB", 64 * 1024, benchmarkMediumData},
|
||
{"Large_1MB", 1 * 1024 * 1024, benchmarkLargeData},
|
||
{"Huge_10MB", 10 * 1024 * 1024, benchmarkHugeData},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
// XCipher
|
||
b.Run(fmt.Sprintf("XCipher_%s", tc.name), func(b *testing.B) {
|
||
cipher := NewXCipher(benchmarkKey)
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := cipher.Encrypt(tc.data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// Standard ChaCha20Poly1305
|
||
b.Run(fmt.Sprintf("StdChaCha20Poly1305_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := encryptWithStdChaCha20Poly1305(tc.data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// AES-GCM
|
||
b.Run(fmt.Sprintf("AES_GCM_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := encryptWithAESGCM(tc.data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// 对比基本解密性能
|
||
func BenchmarkCompareDecrypt(b *testing.B) {
|
||
testCases := []struct {
|
||
name string
|
||
size int
|
||
data []byte
|
||
}{
|
||
{"Small_1KB", 1 * 1024, benchmarkSmallData},
|
||
{"Medium_64KB", 64 * 1024, benchmarkMediumData},
|
||
{"Large_1MB", 1 * 1024 * 1024, benchmarkLargeData},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
// XCipher 加密准备
|
||
xcipher := NewXCipher(benchmarkKey)
|
||
xcipherEncrypted, _ := xcipher.Encrypt(tc.data, nil)
|
||
|
||
// 标准库 ChaCha20Poly1305 加密准备
|
||
stdChachaEncrypted, _ := encryptWithStdChaCha20Poly1305(tc.data, nil)
|
||
|
||
// AES-GCM 加密准备
|
||
aesGcmEncrypted, _ := encryptWithAESGCM(tc.data, nil)
|
||
|
||
// XCipher
|
||
b.Run(fmt.Sprintf("XCipher_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := xcipher.Decrypt(xcipherEncrypted, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// Standard ChaCha20Poly1305
|
||
b.Run(fmt.Sprintf("StdChaCha20Poly1305_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := decryptWithStdChaCha20Poly1305(stdChachaEncrypted, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// AES-GCM
|
||
b.Run(fmt.Sprintf("AES_GCM_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := decryptWithAESGCM(aesGcmEncrypted, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// 对比流式加密性能
|
||
func BenchmarkCompareStreamEncrypt(b *testing.B) {
|
||
testCases := []struct {
|
||
name string
|
||
size int
|
||
data []byte
|
||
}{
|
||
{"Medium_64KB", 64 * 1024, benchmarkMediumData},
|
||
{"Large_1MB", 1 * 1024 * 1024, benchmarkLargeData},
|
||
{"Huge_10MB", 10 * 1024 * 1024, benchmarkHugeData},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
// XCipher 顺序流式加密
|
||
b.Run(fmt.Sprintf("XCipher_Sequential_%s", tc.name), func(b *testing.B) {
|
||
xcipher := NewXCipher(benchmarkKey)
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = false
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(tc.data)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := xcipher.EncryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// XCipher 并行流式加密
|
||
b.Run(fmt.Sprintf("XCipher_Parallel_%s", tc.name), func(b *testing.B) {
|
||
xcipher := NewXCipher(benchmarkKey)
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = true
|
||
options.MaxWorkers = runtime.NumCPU()
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(tc.data)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := xcipher.EncryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 标准库模拟流式加密
|
||
b.Run(fmt.Sprintf("StdChacha20Poly1305_Stream_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(tc.data)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
err := streamEncryptWithStdChaCha20Poly1305(reader, writer, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// 对比流式解密性能
|
||
func BenchmarkCompareStreamDecrypt(b *testing.B) {
|
||
testCases := []struct {
|
||
name string
|
||
size int
|
||
data []byte
|
||
}{
|
||
{"Medium_64KB", 64 * 1024, benchmarkMediumData},
|
||
{"Large_1MB", 1 * 1024 * 1024, benchmarkLargeData},
|
||
{"Huge_10MB", 10 * 1024 * 1024, benchmarkHugeData},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
// 准备XCipher加密数据
|
||
xcipher := NewXCipher(benchmarkKey)
|
||
var xCipherBuf bytes.Buffer
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = false
|
||
_, _ = xcipher.EncryptStreamWithOptions(bytes.NewReader(tc.data), &xCipherBuf, options)
|
||
xCipherEncData := xCipherBuf.Bytes()
|
||
|
||
// 准备标准库加密数据
|
||
var stdBuf bytes.Buffer
|
||
_ = streamEncryptWithStdChaCha20Poly1305(bytes.NewReader(tc.data), &stdBuf, nil)
|
||
stdEncData := stdBuf.Bytes()
|
||
|
||
// XCipher 顺序流式解密
|
||
b.Run(fmt.Sprintf("XCipher_Sequential_%s", tc.name), func(b *testing.B) {
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = false
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(xCipherEncData)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := xcipher.DecryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// XCipher 并行流式解密
|
||
b.Run(fmt.Sprintf("XCipher_Parallel_%s", tc.name), func(b *testing.B) {
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = true
|
||
options.MaxWorkers = runtime.NumCPU()
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(xCipherEncData)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := xcipher.DecryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 标准库模拟流式解密
|
||
b.Run(fmt.Sprintf("StdChacha20Poly1305_Stream_%s", tc.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(tc.size))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(stdEncData)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
err := streamDecryptWithStdChaCha20Poly1305(reader, writer, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// 多核心优化性能测试
|
||
func BenchmarkMultiCoreScaling(b *testing.B) {
|
||
// 使用较大数据块展示并行处理优势
|
||
dataSize := 32 * 1024 * 1024 // 32MB
|
||
largeData := make([]byte, dataSize)
|
||
rand.Read(largeData)
|
||
|
||
// 测试在不同CPU核心数下的性能表现
|
||
maxCores := runtime.NumCPU()
|
||
for cores := 1; cores <= maxCores; cores *= 2 {
|
||
// 如果cores超过最大核心数,使用最大核心数
|
||
testCores := cores
|
||
if testCores > maxCores {
|
||
testCores = maxCores
|
||
}
|
||
|
||
coreName := fmt.Sprintf("%d_Cores", testCores)
|
||
|
||
// 限制使用的CPU数量
|
||
runtime.GOMAXPROCS(testCores)
|
||
|
||
// XCipher并行加密
|
||
b.Run(fmt.Sprintf("XCipher_Parallel_%s", coreName), func(b *testing.B) {
|
||
xcipher := NewXCipher(benchmarkKey)
|
||
options := DefaultStreamOptions()
|
||
options.UseParallel = true
|
||
options.MaxWorkers = testCores
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(dataSize))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(largeData)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := xcipher.EncryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 标准库加密
|
||
b.Run(fmt.Sprintf("StdChaCha20Poly1305_%s", coreName), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(dataSize))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(largeData)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
err := streamEncryptWithStdChaCha20Poly1305(reader, writer, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 恢复默认的CPU核心数设置
|
||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||
}
|
||
|
||
// HardwareAccelerationTest 测试硬件加速性能
|
||
func BenchmarkHardwareAcceleration(b *testing.B) {
|
||
// 测试不同算法在硬件加速下的性能表现
|
||
dataSize := 16 * 1024 * 1024 // 16MB
|
||
data := make([]byte, dataSize)
|
||
rand.Read(data)
|
||
|
||
// 获取CPU架构信息
|
||
info := GetSystemOptimizationInfo()
|
||
|
||
// ChaCha20-Poly1305(XCipher)
|
||
b.Run(fmt.Sprintf("XCipher_HW=%v_AVX2=%v", true, info.HasAVX2), func(b *testing.B) {
|
||
cipher := NewXCipher(benchmarkKey)
|
||
|
||
// 使用优化选项
|
||
options := GetOptimizedStreamOptions()
|
||
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(dataSize))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(data)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
_, err := cipher.EncryptStreamWithOptions(reader, writer, options)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 标准库 ChaCha20-Poly1305
|
||
b.Run(fmt.Sprintf("StdChaCha20Poly1305_HW=%v", true), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(dataSize))
|
||
for i := 0; i < b.N; i++ {
|
||
b.StopTimer()
|
||
reader := bytes.NewReader(data)
|
||
writer := ioutil.Discard
|
||
b.StartTimer()
|
||
|
||
err := streamEncryptWithStdChaCha20Poly1305(reader, writer, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// AES-GCM (如果硬件支持AES-NI,可能会有很好的性能)
|
||
b.Run(fmt.Sprintf("AES_GCM_HW=%v", true), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(dataSize))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := encryptWithAESGCM(data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 内存使用测试 - 检查不同大小数据时的内存分配情况
|
||
func BenchmarkMemoryUsage(b *testing.B) {
|
||
sizes := []struct {
|
||
name string
|
||
size int
|
||
}{
|
||
{"4KB", 4 * 1024},
|
||
{"1MB", 1 * 1024 * 1024},
|
||
{"10MB", 10 * 1024 * 1024},
|
||
}
|
||
|
||
for _, size := range sizes {
|
||
data := make([]byte, size.size)
|
||
rand.Read(data)
|
||
|
||
// XCipher
|
||
b.Run(fmt.Sprintf("XCipher_%s", size.name), func(b *testing.B) {
|
||
cipher := NewXCipher(benchmarkKey)
|
||
b.ResetTimer()
|
||
b.ReportAllocs() // 报告内存分配情况
|
||
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := cipher.Encrypt(data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 标准库
|
||
b.Run(fmt.Sprintf("StdChaCha20Poly1305_%s", size.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.ReportAllocs() // 报告内存分配情况
|
||
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := encryptWithStdChaCha20Poly1305(data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// 综合性能矩阵测试,对比不同算法在各种场景下的性能
|
||
func BenchmarkPerformanceMatrix(b *testing.B) {
|
||
// 测试参数矩阵
|
||
sizes := []struct {
|
||
name string
|
||
size int
|
||
}{
|
||
{"4KB", 4 * 1024},
|
||
{"64KB", 64 * 1024},
|
||
{"1MB", 1 * 1024 * 1024},
|
||
}
|
||
|
||
methods := []struct {
|
||
name string
|
||
encrypt func([]byte, []byte) ([]byte, error)
|
||
decrypt func([]byte, []byte) ([]byte, error)
|
||
}{
|
||
{
|
||
name: "XCipher",
|
||
encrypt: func(data, aad []byte) ([]byte, error) {
|
||
cipher := NewXCipher(benchmarkKey)
|
||
return cipher.Encrypt(data, aad)
|
||
},
|
||
decrypt: func(data, aad []byte) ([]byte, error) {
|
||
cipher := NewXCipher(benchmarkKey)
|
||
return cipher.Decrypt(data, aad)
|
||
},
|
||
},
|
||
{
|
||
name: "StdChaCha20Poly1305",
|
||
encrypt: encryptWithStdChaCha20Poly1305,
|
||
decrypt: decryptWithStdChaCha20Poly1305,
|
||
},
|
||
{
|
||
name: "AES_GCM",
|
||
encrypt: encryptWithAESGCM,
|
||
decrypt: decryptWithAESGCM,
|
||
},
|
||
}
|
||
|
||
// 针对每种数据大小
|
||
for _, size := range sizes {
|
||
data := make([]byte, size.size)
|
||
rand.Read(data)
|
||
|
||
// 针对每种加密方法
|
||
for _, method := range methods {
|
||
// 加密基准测试
|
||
b.Run(fmt.Sprintf("Encrypt_%s_%s", method.name, size.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(size.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := method.encrypt(data, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 解密基准测试
|
||
encrypted, _ := method.encrypt(data, nil)
|
||
b.Run(fmt.Sprintf("Decrypt_%s_%s", method.name, size.name), func(b *testing.B) {
|
||
b.ResetTimer()
|
||
b.SetBytes(int64(size.size))
|
||
for i := 0; i < b.N; i++ {
|
||
_, err := method.decrypt(encrypted, nil)
|
||
if err != nil {
|
||
b.Fatal(err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
// 报告辅助函数 - 在测试运行期间收集相关信息
|
||
func TestPrintBenchmarkGuide(t *testing.T) {
|
||
if testing.Short() {
|
||
t.Skip("跳过报告生成")
|
||
}
|
||
|
||
fmt.Println("======= XCipher 与标准库加密性能对比测试指南 =======")
|
||
fmt.Println("运行以下命令以执行全面性能对比测试:")
|
||
fmt.Println("go test -bench=Benchmark -benchmem -benchtime=1s")
|
||
fmt.Println()
|
||
fmt.Println("或运行特定测试:")
|
||
fmt.Println("go test -bench=BenchmarkCompareEncrypt -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkCompareDecrypt -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkCompareStreamEncrypt -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkCompareStreamDecrypt -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkMultiCoreScaling -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkHardwareAcceleration -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkMemoryUsage -benchmem")
|
||
fmt.Println("go test -bench=BenchmarkPerformanceMatrix -benchmem")
|
||
fmt.Println()
|
||
|
||
// 获取CPU和系统信息
|
||
fmt.Println("系统信息:")
|
||
fmt.Printf("CPU: %d 核心\n", runtime.NumCPU())
|
||
fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0))
|
||
fmt.Printf("架构: %s\n", runtime.GOARCH)
|
||
|
||
// 获取优化相关信息
|
||
info := GetSystemOptimizationInfo()
|
||
fmt.Println("\n硬件加速支持:")
|
||
fmt.Printf("AVX: %v\n", info.HasAVX)
|
||
fmt.Printf("AVX2: %v\n", info.HasAVX2)
|
||
fmt.Printf("SSE4.1: %v\n", info.HasSSE41)
|
||
fmt.Printf("ARM NEON: %v\n", info.HasNEON)
|
||
|
||
fmt.Println("\n推荐优化参数:")
|
||
fmt.Printf("建议缓冲区大小: %d 字节\n", info.RecommendedBufferSize)
|
||
fmt.Printf("建议工作线程数: %d\n", info.RecommendedWorkers)
|
||
fmt.Printf("并行处理阈值: %d 字节\n", info.ParallelThreshold)
|
||
fmt.Println("\n测试结果将显示各种加密算法和方法的性能差异。")
|
||
fmt.Println("=================================================")
|
||
}
|