// Package benchmark provides performance benchmarks for memguard security operations. package benchmark import ( "crypto/rand" "testing" "github.com/awnumar/memguard" "golang.org/x/crypto/argon2" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/securebytes" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/securestring" ) // BenchmarkPlainStringAllocation benchmarks plain string allocation. func BenchmarkPlainStringAllocation(b *testing.B) { for i := 0; i < b.N; i++ { s := "this is a test string with sensitive data" _ = s } } // BenchmarkSecureStringAllocation benchmarks SecureString allocation and cleanup. func BenchmarkSecureStringAllocation(b *testing.B) { for i := 0; i < b.N; i++ { s, err := securestring.NewSecureString("this is a test string with sensitive data") if err != nil { b.Fatal(err) } s.Wipe() } } // BenchmarkPlainBytesAllocation benchmarks plain byte slice allocation. func BenchmarkPlainBytesAllocation(b *testing.B) { for i := 0; i < b.N; i++ { data := make([]byte, 32) rand.Read(data) _ = data } } // BenchmarkSecureBytesAllocation benchmarks SecureBytes allocation and cleanup. func BenchmarkSecureBytesAllocation(b *testing.B) { for i := 0; i < b.N; i++ { data := make([]byte, 32) rand.Read(data) sb, err := securebytes.NewSecureBytes(data) if err != nil { b.Fatal(err) } sb.Wipe() } } // BenchmarkPasswordHashing_Plain benchmarks password hashing without memguard. func BenchmarkPasswordHashing_Plain(b *testing.B) { password := []byte("test_password_12345") salt := make([]byte, 16) rand.Read(salt) b.ResetTimer() for i := 0; i < b.N; i++ { _ = argon2.IDKey(password, salt, 3, 64*1024, 4, 32) } } // BenchmarkPasswordHashing_Secure benchmarks password hashing with memguard wiping. func BenchmarkPasswordHashing_Secure(b *testing.B) { password, err := securestring.NewSecureString("test_password_12345") if err != nil { b.Fatal(err) } defer password.Wipe() salt := make([]byte, 16) rand.Read(salt) b.ResetTimer() for i := 0; i < b.N; i++ { passwordBytes := password.Bytes() hash := argon2.IDKey(passwordBytes, salt, 3, 64*1024, 4, 32) memguard.WipeBytes(hash) } } // BenchmarkMemguardWipeBytes benchmarks the memguard.WipeBytes operation. func BenchmarkMemguardWipeBytes(b *testing.B) { for i := 0; i < b.N; i++ { data := make([]byte, 32) rand.Read(data) memguard.WipeBytes(data) } } // BenchmarkMemguardWipeBytes_Large benchmarks wiping larger byte slices. func BenchmarkMemguardWipeBytes_Large(b *testing.B) { for i := 0; i < b.N; i++ { data := make([]byte, 4096) rand.Read(data) memguard.WipeBytes(data) } } // BenchmarkLockedBuffer_Create benchmarks creating a memguard LockedBuffer. func BenchmarkLockedBuffer_Create(b *testing.B) { for i := 0; i < b.N; i++ { buf := memguard.NewBuffer(32) buf.Destroy() } } // BenchmarkLockedBuffer_FromBytes benchmarks creating a LockedBuffer from bytes. func BenchmarkLockedBuffer_FromBytes(b *testing.B) { data := make([]byte, 32) rand.Read(data) b.ResetTimer() for i := 0; i < b.N; i++ { buf := memguard.NewBufferFromBytes(data) buf.Destroy() } } // BenchmarkJWTTokenGeneration_Plain simulates JWT token generation without security. func BenchmarkJWTTokenGeneration_Plain(b *testing.B) { secret := make([]byte, 32) rand.Read(secret) b.ResetTimer() for i := 0; i < b.N; i++ { // Simulate token signing _ = secret } } // BenchmarkJWTTokenGeneration_Secure simulates JWT token generation with memguard. func BenchmarkJWTTokenGeneration_Secure(b *testing.B) { secret := make([]byte, 32) rand.Read(secret) b.ResetTimer() for i := 0; i < b.N; i++ { secretCopy := make([]byte, len(secret)) copy(secretCopy, secret) // Simulate token signing _ = secretCopy memguard.WipeBytes(secretCopy) } } // Run benchmarks with: // go test -bench=. -benchmem ./pkg/security/benchmark/