lnd/internal/musig2v040/bench_test.go
Oliver Gugger 0154226233
internal/musig2: rename to musig2v040 to avoid confusion
Since we explicitly keep an old version of a library in lnd for backward
compatibility we want to make sure the purpose and version of it is
clear and not misleading.
2023-02-03 18:30:09 +01:00

314 lines
6.7 KiB
Go

// Copyright 2013-2022 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package musig2v040
import (
"encoding/hex"
"fmt"
"testing"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
)
var (
testPrivBytes = hexToModNScalar("9e0699c91ca1e3b7e3c9ba71eb71c89890872be97576010fe593fbf3fd57e66d")
testMsg = hexToBytes("c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7")
)
func hexToBytes(s string) []byte {
b, err := hex.DecodeString(s)
if err != nil {
panic("invalid hex in source file: " + s)
}
return b
}
func hexToModNScalar(s string) *btcec.ModNScalar {
b, err := hex.DecodeString(s)
if err != nil {
panic("invalid hex in source file: " + s)
}
var scalar btcec.ModNScalar
if overflow := scalar.SetByteSlice(b); overflow {
panic("hex in source file overflows mod N scalar: " + s)
}
return &scalar
}
func genSigner(t *testing.B) signer {
privKey, err := btcec.NewPrivateKey()
if err != nil {
t.Fatalf("unable to gen priv key: %v", err)
}
pubKey, err := schnorr.ParsePubKey(
schnorr.SerializePubKey(privKey.PubKey()),
)
if err != nil {
t.Fatalf("unable to gen key: %v", err)
}
nonces, err := GenNonces()
if err != nil {
t.Fatalf("unable to gen nonces: %v", err)
}
return signer{
privKey: privKey,
pubKey: pubKey,
nonces: nonces,
}
}
var (
testSig *PartialSignature
testErr error
)
// BenchmarkPartialSign benchmarks how long it takes to generate a partial
// signature factoring in if the keys are sorted and also if we're in fast sign
// mode.
func BenchmarkPartialSign(b *testing.B) {
for _, numSigners := range []int{10, 100} {
for _, fastSign := range []bool{true, false} {
for _, sortKeys := range []bool{true, false} {
name := fmt.Sprintf("num_signers=%v/fast_sign=%v/sort=%v",
numSigners, fastSign, sortKeys)
signers := make(signerSet, numSigners)
for i := 0; i < numSigners; i++ {
signers[i] = genSigner(b)
}
combinedNonce, err := AggregateNonces(signers.pubNonces())
if err != nil {
b.Fatalf("unable to generate combined nonce: %v", err)
}
var sig *PartialSignature
var msg [32]byte
copy(msg[:], testMsg[:])
keys := signers.keys()
b.Run(name, func(b *testing.B) {
var signOpts []SignOption
if fastSign {
signOpts = append(signOpts, WithFastSign())
}
if sortKeys {
signOpts = append(signOpts, WithSortedKeys())
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sig, err = Sign(
signers[0].nonces.SecNonce, signers[0].privKey,
combinedNonce, keys, msg, signOpts...,
)
if err != nil {
b.Fatalf("unable to generate sig: %v", err)
}
}
testSig = sig
testErr = err
})
}
}
}
}
// TODO(roasbeef): add impact of sorting ^
var sigOk bool
// BenchmarkPartialVerify benchmarks how long it takes to verify a partial
// signature.
func BenchmarkPartialVerify(b *testing.B) {
for _, numSigners := range []int{10, 100} {
for _, sortKeys := range []bool{true, false} {
name := fmt.Sprintf("sort_keys=%v/num_signers=%v",
sortKeys, numSigners)
signers := make(signerSet, numSigners)
for i := 0; i < numSigners; i++ {
signers[i] = genSigner(b)
}
combinedNonce, err := AggregateNonces(
signers.pubNonces(),
)
if err != nil {
b.Fatalf("unable to generate combined "+
"nonce: %v", err)
}
var sig *PartialSignature
var msg [32]byte
copy(msg[:], testMsg[:])
b.ReportAllocs()
b.ResetTimer()
sig, err = Sign(
signers[0].nonces.SecNonce, signers[0].privKey,
combinedNonce, signers.keys(), msg,
)
if err != nil {
b.Fatalf("unable to generate sig: %v", err)
}
keys := signers.keys()
pubKey := signers[0].pubKey
b.Run(name, func(b *testing.B) {
var signOpts []SignOption
if sortKeys {
signOpts = append(
signOpts, WithSortedKeys(),
)
}
b.ResetTimer()
b.ReportAllocs()
var ok bool
for i := 0; i < b.N; i++ {
ok = sig.Verify(
signers[0].nonces.PubNonce, combinedNonce,
keys, pubKey, msg,
)
if !ok {
b.Fatalf("generated invalid sig!")
}
}
sigOk = ok
})
}
}
}
var finalSchnorrSig *schnorr.Signature
// BenchmarkCombineSigs benchmarks how long it takes to combine a set amount of
// signatures.
func BenchmarkCombineSigs(b *testing.B) {
for _, numSigners := range []int{10, 100} {
signers := make(signerSet, numSigners)
for i := 0; i < numSigners; i++ {
signers[i] = genSigner(b)
}
combinedNonce, err := AggregateNonces(signers.pubNonces())
if err != nil {
b.Fatalf("unable to generate combined nonce: %v", err)
}
var msg [32]byte
copy(msg[:], testMsg[:])
var finalNonce *btcec.PublicKey
for i := range signers {
signer := signers[i]
partialSig, err := Sign(
signer.nonces.SecNonce, signer.privKey,
combinedNonce, signers.keys(), msg,
)
if err != nil {
b.Fatalf("unable to generate partial sig: %v",
err)
}
signers[i].partialSig = partialSig
if finalNonce == nil {
finalNonce = partialSig.R
}
}
sigs := signers.partialSigs()
name := fmt.Sprintf("num_signers=%v", numSigners)
b.Run(name, func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
finalSig := CombineSigs(finalNonce, sigs)
finalSchnorrSig = finalSig
})
}
}
var testNonce [PubNonceSize]byte
// BenchmarkAggregateNonces benchmarks how long it takes to combine nonces.
func BenchmarkAggregateNonces(b *testing.B) {
for _, numSigners := range []int{10, 100} {
signers := make(signerSet, numSigners)
for i := 0; i < numSigners; i++ {
signers[i] = genSigner(b)
}
nonces := signers.pubNonces()
name := fmt.Sprintf("num_signers=%v", numSigners)
b.Run(name, func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
pubNonce, err := AggregateNonces(nonces)
if err != nil {
b.Fatalf("unable to generate nonces: %v", err)
}
testNonce = pubNonce
})
}
}
var testKey *btcec.PublicKey
// BenchmarkAggregateKeys benchmarks how long it takes to aggregate public
// keys.
func BenchmarkAggregateKeys(b *testing.B) {
for _, numSigners := range []int{10, 100} {
for _, sortKeys := range []bool{true, false} {
signers := make(signerSet, numSigners)
for i := 0; i < numSigners; i++ {
signers[i] = genSigner(b)
}
signerKeys := signers.keys()
name := fmt.Sprintf("num_signers=%v/sort_keys=%v",
numSigners, sortKeys)
uniqueKeyIndex := secondUniqueKeyIndex(signerKeys, false)
b.Run(name, func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
aggKey, _, _, _ := AggregateKeys(
signerKeys, sortKeys,
WithUniqueKeyIndex(uniqueKeyIndex),
)
testKey = aggKey.FinalKey
})
}
}
}