mirror of
https://github.com/luxfi/crypto.git
synced 2026-10-30 16:59:13 +00:00
- Implement ML-DSA-65 (FIPS 204) using cloudflare/circl * Single implementation with automatic CGO optimization * Sign ~440μs, Verify ~130μs, KeyGen ~165μs on M1 Max * All 11 tests passing - Simplify ML-KEM implementation * Remove redundant optimized versions * Use circl ML-KEM-768 directly - Simplify SLH-DSA implementation * Remove premature optimizations * Clean stub for future circl support (FIPS 205) - Add comprehensive cache package * LRU cache from luxfi/node * Metercacher for metrics integration * Test utilities - Add crypto utils * Atomic operations * Bytes utilities * Complete utils package from luxfi/node - Update secp256k1 and BLS * All BLS tests passing (23 tests) * secp256k1 fuzz test added All post-quantum implementations now use cloudflare/circl as single source of truth, following DRY principle and ensuring FIPS compliance.
149 lines
2.9 KiB
Plaintext
149 lines
2.9 KiB
Plaintext
package mldsa
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func BenchmarkMLDSA44(b *testing.B) {
|
|
benchmarkMLDSA(b, MLDSA44)
|
|
}
|
|
|
|
func BenchmarkMLDSA65(b *testing.B) {
|
|
benchmarkMLDSA(b, MLDSA65)
|
|
}
|
|
|
|
func BenchmarkMLDSA87(b *testing.B) {
|
|
benchmarkMLDSA(b, MLDSA87)
|
|
}
|
|
|
|
func benchmarkMLDSA(b *testing.B, mode Mode) {
|
|
message := make([]byte, 32)
|
|
rand.Read(message)
|
|
|
|
b.Run("GenerateKey", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := GenerateKey(rand.Reader, mode)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
|
|
priv, err := GenerateKey(rand.Reader, mode)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
b.Run("Sign", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := priv.Sign(rand.Reader, message, nil)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
|
|
sig, err := priv.Sign(rand.Reader, message, nil)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
b.Run("Verify", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
valid := priv.PublicKey.Verify(message, sig, nil)
|
|
if !valid {
|
|
b.Fatal("verification failed")
|
|
}
|
|
}
|
|
})
|
|
|
|
b.Run("Serialize", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = priv.Bytes()
|
|
_ = priv.PublicKey.Bytes()
|
|
}
|
|
})
|
|
|
|
privBytes := priv.Bytes()
|
|
pubBytes := priv.PublicKey.Bytes()
|
|
|
|
b.Run("Deserialize", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := PrivateKeyFromBytes(privBytes, mode)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
_, err = PublicKeyFromBytes(pubBytes, mode)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// Batch verification benchmark
|
|
func BenchmarkMLDSABatchVerify(b *testing.B) {
|
|
modes := []struct {
|
|
name string
|
|
mode Mode
|
|
}{
|
|
{"MLDSA44", MLDSA44},
|
|
{"MLDSA65", MLDSA65},
|
|
{"MLDSA87", MLDSA87},
|
|
}
|
|
|
|
for _, m := range modes {
|
|
b.Run(m.name, func(b *testing.B) {
|
|
// Generate multiple signatures
|
|
numSigs := 10
|
|
messages := make([][]byte, numSigs)
|
|
signatures := make([][]byte, numSigs)
|
|
|
|
priv, _ := GenerateKey(rand.Reader, m.mode)
|
|
for i := 0; i < numSigs; i++ {
|
|
messages[i] = make([]byte, 32)
|
|
rand.Read(messages[i])
|
|
signatures[i], _ = priv.Sign(rand.Reader, messages[i], nil)
|
|
}
|
|
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Verify all signatures
|
|
for j := 0; j < numSigs; j++ {
|
|
if !priv.PublicKey.Verify(messages[j], signatures[j], nil) {
|
|
b.Fatal("verification failed")
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Different message sizes
|
|
func BenchmarkMLDSAMessageSizes(b *testing.B) {
|
|
sizes := []int{32, 64, 128, 256, 512, 1024}
|
|
priv, _ := GenerateKey(rand.Reader, MLDSA65)
|
|
|
|
for _, size := range sizes {
|
|
b.Run(fmt.Sprintf("Size%d", size), func(b *testing.B) {
|
|
message := make([]byte, size)
|
|
rand.Read(message)
|
|
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
sig, _ := priv.Sign(rand.Reader, message, nil)
|
|
if !priv.PublicKey.Verify(message, sig, nil) {
|
|
b.Fatal("verification failed")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
} |