This commit introduces several optimizations for elliptic curve operations in the secp256k1 library. Key changes include the implementation of the `ecmultStraussGLV` function for efficient scalar multiplication using the Strauss algorithm with GLV endomorphism, and the addition of windowed multiplication techniques to improve performance. Additionally, the benchmark tests have been updated to focus on the P256K1Signer implementation, streamlining the comparison process and enhancing clarity in performance evaluations.
169 lines
3.7 KiB
Go
169 lines
3.7 KiB
Go
//go:build !nocgo
|
|
// +build !nocgo
|
|
|
|
package bench
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"testing"
|
|
|
|
"p256k1.mleku.dev/signer"
|
|
)
|
|
|
|
// This file contains benchmarks for the P256K1Signer implementation
|
|
// (pure Go port from Bitcoin Core secp256k1)
|
|
|
|
var (
|
|
benchSeckey []byte
|
|
benchMsghash []byte
|
|
compBenchSignerP256K1 *signer.P256K1Signer
|
|
compBenchSignerP256K12 *signer.P256K1Signer
|
|
compBenchSigP256K1 []byte
|
|
)
|
|
|
|
func initComparisonBenchData() {
|
|
// Generate a fixed secret key for benchmarks
|
|
if benchSeckey == nil {
|
|
benchSeckey = []byte{
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
}
|
|
|
|
// Ensure it's valid (non-zero and less than order)
|
|
// We'll validate by trying to create a signer
|
|
for {
|
|
testSigner := signer.NewP256K1Signer()
|
|
if err := testSigner.InitSec(benchSeckey); err == nil {
|
|
break
|
|
}
|
|
if _, err := rand.Read(benchSeckey); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Create message hash
|
|
benchMsghash = make([]byte, 32)
|
|
if _, err := rand.Read(benchMsghash); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Setup P256K1Signer (this repo's implementation)
|
|
signer1 := signer.NewP256K1Signer()
|
|
if err := signer1.InitSec(benchSeckey); err != nil {
|
|
panic(err)
|
|
}
|
|
compBenchSignerP256K1 = signer1
|
|
|
|
var err error
|
|
compBenchSigP256K1, err = signer1.Sign(benchMsghash)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Generate second key pair for ECDH
|
|
seckey2 := make([]byte, 32)
|
|
for {
|
|
if _, err := rand.Read(seckey2); err != nil {
|
|
panic(err)
|
|
}
|
|
// Validate by trying to create a signer
|
|
testSigner := signer.NewP256K1Signer()
|
|
if err := testSigner.InitSec(seckey2); err == nil {
|
|
break
|
|
}
|
|
}
|
|
|
|
// P256K1Signer second key pair
|
|
signer12 := signer.NewP256K1Signer()
|
|
if err := signer12.InitSec(seckey2); err != nil {
|
|
panic(err)
|
|
}
|
|
compBenchSignerP256K12 = signer12
|
|
}
|
|
|
|
// BenchmarkPubkeyDerivation benchmarks public key derivation from private key
|
|
func BenchmarkPubkeyDerivation(b *testing.B) {
|
|
if benchSeckey == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
s := signer.NewP256K1Signer()
|
|
if err := s.InitSec(benchSeckey); err != nil {
|
|
b.Fatalf("failed to create signer: %v", err)
|
|
}
|
|
_ = s.Pub()
|
|
}
|
|
}
|
|
|
|
|
|
// BenchmarkSign benchmarks Schnorr signing
|
|
func BenchmarkSign(b *testing.B) {
|
|
if benchSeckey == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
if compBenchSignerP256K1 == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
_, err := compBenchSignerP256K1.Sign(benchMsghash)
|
|
if err != nil {
|
|
b.Fatalf("failed to sign: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// BenchmarkVerify benchmarks Schnorr verification
|
|
func BenchmarkVerify(b *testing.B) {
|
|
if benchSeckey == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
|
|
if compBenchSignerP256K1 == nil || compBenchSigP256K1 == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
verifier := signer.NewP256K1Signer()
|
|
if err := verifier.InitPub(compBenchSignerP256K1.Pub()); err != nil {
|
|
b.Fatalf("failed to create verifier: %v", err)
|
|
}
|
|
valid, err := verifier.Verify(benchMsghash, compBenchSigP256K1)
|
|
if err != nil {
|
|
b.Fatalf("verification error: %v", err)
|
|
}
|
|
if !valid {
|
|
b.Fatalf("verification failed")
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// BenchmarkECDH benchmarks ECDH shared secret generation
|
|
func BenchmarkECDH(b *testing.B) {
|
|
if benchSeckey == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
if compBenchSignerP256K1 == nil || compBenchSignerP256K12 == nil {
|
|
initComparisonBenchData()
|
|
}
|
|
_, err := compBenchSignerP256K1.ECDH(compBenchSignerP256K12.Pub())
|
|
if err != nil {
|
|
b.Fatalf("ECDH failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
|