From 9fcc41465165ac0c32e537b735368744a12cf94f Mon Sep 17 00:00:00 2001 From: Richard Pringle Date: Mon, 3 Feb 2025 17:47:01 -0500 Subject: [PATCH] Make bls.Signer api fallible --- go.mod | 2 +- go.sum | 4 +- network/peer/ip.go | 12 +- network/peer/peer_test.go | 25 +- utils/crypto/bls/signer.go | 4 +- .../bls/signer/localsigner/benchmark_test.go | 4 +- .../crypto/bls/signer/localsigner/bls_test.go | 247 ++++++++++-------- .../bls/signer/localsigner/localsigner.go | 18 +- .../signer/localsigner/serialization_test.go | 6 +- vms/platformvm/signer/proof_of_possession.go | 7 +- .../txs/executor/standard_tx_executor_test.go | 18 +- .../txs/executor/warp_verifier_test.go | 9 +- vms/platformvm/warp/signature_test.go | 54 ++-- vms/platformvm/warp/signer.go | 5 +- wallet/chain/p/builder_test.go | 10 +- .../examples/register-l1-validator/main.go | 5 +- .../examples/set-l1-validator-weight/main.go | 8 +- 17 files changed, 274 insertions(+), 164 deletions(-) diff --git a/go.mod b/go.mod index 2b9947b19fed..2435266e9764 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/NYTimes/gziphandler v1.1.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/coreth v0.14.2-verify-interface4 + github.com/ava-labs/coreth v0.14.1-rc.1.0.20250204181539-66241eebcbed github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 diff --git a/go.sum b/go.sum index 48ef3e918506..ec833955f4a0 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/coreth v0.14.2-verify-interface4 h1:AYeN8R6ZnNu/K8KwBQD4ELphvLpvNxAjkX3SBcJ+bps= -github.com/ava-labs/coreth v0.14.2-verify-interface4/go.mod h1:wQaeiolUP0vCHS1mC0lIMXzHF05vbjugSLCBFDnO4Gs= +github.com/ava-labs/coreth v0.14.1-rc.1.0.20250204181539-66241eebcbed h1:m9JXpuXXx9a/pcwHUQUJ8R1Vp3nndsJSnQxsT5brxDc= +github.com/ava-labs/coreth v0.14.1-rc.1.0.20250204181539-66241eebcbed/go.mod h1:cfL8GjzBa87pxGWIAG4iB4f6vSMyuBHtkmcUk9ms4sE= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 h1:EL66gtXOAwR/4KYBjOV03LTWgkEXvLePribLlJNu4g0= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60/go.mod h1:/7qKobTfbzBu7eSTVaXMTr56yTYk4j2Px6/8G+idxHo= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/peer/ip.go b/network/peer/ip.go index 08152b9748a6..94187dc702c4 100644 --- a/network/peer/ip.go +++ b/network/peer/ip.go @@ -39,13 +39,21 @@ func (ip *UnsignedIP) Sign(tlsSigner crypto.Signer, blsSigner bls.Signer) (*Sign hashing.ComputeHash256(ipBytes), crypto.SHA256, ) - blsSignature := blsSigner.SignProofOfPossession(ipBytes) + if err != nil { + return nil, err + } + + blsSignature, err := blsSigner.SignProofOfPossession(ipBytes) + if err != nil { + return nil, err + } + return &SignedIP{ UnsignedIP: *ip, TLSSignature: tlsSignature, BLSSignature: blsSignature, BLSSignatureBytes: bls.SignatureToBytes(blsSignature), - }, err + }, nil } func (ip *UnsignedIP) bytes() []byte { diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index b039b870f35f..e161ee26bcf9 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math/meter" @@ -556,7 +557,11 @@ func TestShouldDisconnect(t *testing.T) { id: peerID, version: version.CurrentApp, ip: &SignedIP{ - BLSSignature: blsKey.SignProofOfPossession([]byte("wrong message")), + BLSSignature: (func() *bls.Signature { + sig, err := blsKey.SignProofOfPossession([]byte("wrong message")) + require.NoError(t, err) + return sig + })(), }, }, expectedPeer: &peer{ @@ -578,7 +583,11 @@ func TestShouldDisconnect(t *testing.T) { id: peerID, version: version.CurrentApp, ip: &SignedIP{ - BLSSignature: blsKey.SignProofOfPossession([]byte("wrong message")), + BLSSignature: (func() *bls.Signature { + sig, err := blsKey.SignProofOfPossession([]byte("wrong message")) + require.NoError(t, err) + return sig + })(), }, }, expectedShouldDisconnect: true, @@ -604,7 +613,11 @@ func TestShouldDisconnect(t *testing.T) { id: peerID, version: version.CurrentApp, ip: &SignedIP{ - BLSSignature: blsKey.SignProofOfPossession((&UnsignedIP{}).bytes()), + BLSSignature: (func() *bls.Signature { + sig, err := blsKey.SignProofOfPossession((&UnsignedIP{}).bytes()) + require.NoError(t, err) + return sig + })(), }, }, expectedPeer: &peer{ @@ -626,7 +639,11 @@ func TestShouldDisconnect(t *testing.T) { id: peerID, version: version.CurrentApp, ip: &SignedIP{ - BLSSignature: blsKey.SignProofOfPossession((&UnsignedIP{}).bytes()), + BLSSignature: (func() *bls.Signature { + sig, err := blsKey.SignProofOfPossession((&UnsignedIP{}).bytes()) + require.NoError(t, err) + return sig + })(), }, txIDOfVerifiedBLSKey: txID, }, diff --git a/utils/crypto/bls/signer.go b/utils/crypto/bls/signer.go index 40c5a79cfba6..499b24d2cf3d 100644 --- a/utils/crypto/bls/signer.go +++ b/utils/crypto/bls/signer.go @@ -5,6 +5,6 @@ package bls type Signer interface { PublicKey() *PublicKey - Sign(msg []byte) *Signature - SignProofOfPossession(msg []byte) *Signature + Sign(msg []byte) (*Signature, error) + SignProofOfPossession(msg []byte) (*Signature, error) } diff --git a/utils/crypto/bls/signer/localsigner/benchmark_test.go b/utils/crypto/bls/signer/localsigner/benchmark_test.go index 701826918e39..96f812b4500d 100644 --- a/utils/crypto/bls/signer/localsigner/benchmark_test.go +++ b/utils/crypto/bls/signer/localsigner/benchmark_test.go @@ -14,7 +14,7 @@ import ( ) func BenchmarkSign(b *testing.B) { - privateKey, _ := NewKeyPair(require.New(b)) + privateKey := NewKeyPair(require.New(b)).signer for _, messageSize := range blstest.BenchmarkSizes { b.Run(strconv.Itoa(messageSize), func(b *testing.B) { message := utils.RandomBytes(messageSize) @@ -22,7 +22,7 @@ func BenchmarkSign(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - _ = privateKey.Sign(message) + _, _ = privateKey.Sign(message) } }) } diff --git a/utils/crypto/bls/signer/localsigner/bls_test.go b/utils/crypto/bls/signer/localsigner/bls_test.go index 3969529dde38..15b58cce68e2 100644 --- a/utils/crypto/bls/signer/localsigner/bls_test.go +++ b/utils/crypto/bls/signer/localsigner/bls_test.go @@ -24,46 +24,75 @@ func AggregateAndVerify(publicKeys []*bls.PublicKey, signatures []*bls.Signature return bls.Verify(aggPK, aggSig, message), nil } -func NewKeyPair(require *require.Assertions) (*LocalSigner, *bls.PublicKey) { +type keyPair struct { + signer *LocalSigner + pk *bls.PublicKey +} + +func NewKeyPair(require *require.Assertions) keyPair { sk, err := New() require.NoError(err) pk := sk.PublicKey() - return sk, pk + + return keyPair{sk, pk} +} + +func collectN[T any](n int, fn func() T) []T { + result := make([]T, n) + for i := 0; i < n; i++ { + result[i] = fn() + } + return result +} + +func mapWithError[T any, U any](arr []T, fn func(T) (U, error)) ([]U, error) { + result := make([]U, len(arr)) + for i, val := range arr { + newVal, err := fn(val) + if err != nil { + return nil, err + } + result[i] = newVal + } + return result, nil } func TestVerifyValidSignature(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyValidSignature local signer") - sig := signer.Sign(msg) + sig, err := keyPair.signer.Sign(msg) + require.NoError(err) - isValid := bls.Verify(pk, sig, msg) + isValid := bls.Verify(keyPair.pk, sig, msg) require.True(isValid) } func TestVerifyWrongMessageSignature(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyWrongMessageSignature local signer") wrongMsg := []byte("TestVerifyWrongMessageSignature local signer with wrong message") - sig := signer.Sign(msg) + sig, err := keyPair.signer.Sign(msg) + require.NoError(err) - isValid := bls.Verify(pk, sig, wrongMsg) + isValid := bls.Verify(keyPair.pk, sig, wrongMsg) require.False(isValid) } func TestVerifyWrongPubkeySignature(t *testing.T) { require := require.New(t) - signer, _ := NewKeyPair(require) - _, wrongPk := NewKeyPair(require) + signer := NewKeyPair(require).signer + wrongPk := NewKeyPair(require).pk msg := []byte("TestVerifyWrongPubkeySignature local signer") - sig := signer.Sign(msg) + sig, err := signer.Sign(msg) + require.NoError(err) isValid := bls.Verify(wrongPk, sig, msg) require.False(isValid) @@ -71,32 +100,34 @@ func TestVerifyWrongPubkeySignature(t *testing.T) { func TestVerifyWrongMessageSignedSignature(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyWrongMessageSignedSignature local signer") wrongMsg := []byte("TestVerifyWrongMessageSignedSignaturelocal local signer with wrong signature") - wrongSig := signer.Sign(wrongMsg) + wrongSig, err := keyPair.signer.Sign(wrongMsg) + require.NoError(err) - isValid := bls.Verify(pk, wrongSig, msg) + isValid := bls.Verify(keyPair.pk, wrongSig, msg) require.False(isValid) } func TestValidAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - sk3, pk3 := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2, pk3} + keyPairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) msg := []byte("TestValidAggregation local signer") - sigs := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(msg), - } + sigs, err := mapWithError(keyPairs, func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) + + pks, _ := mapWithError(keyPairs, func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) isValid, err := AggregateAndVerify(pks, sigs, msg) require.NoError(err) @@ -105,13 +136,14 @@ func TestValidAggregation(t *testing.T) { func TestSingleKeyAggregation(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) - pks := []*bls.PublicKey{pk} + pks := []*bls.PublicKey{keyPair.pk} msg := []byte("TestSingleKeyAggregation local signer") - sig := signer.Sign(msg) + sig, err := keyPair.signer.Sign(msg) + require.NoError(err) isValid, err := AggregateAndVerify(pks, []*bls.Signature{sig}, msg) require.NoError(err) @@ -120,19 +152,20 @@ func TestSingleKeyAggregation(t *testing.T) { func TestIncorrectMessageAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - sk3, pk3 := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2, pk3} + keyPairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) msg := []byte("TestIncorrectMessageAggregation local signer") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(msg), - } + signatures, err := mapWithError(keyPairs, func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) + + pks, _ := mapWithError(keyPairs, func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) isValid, err := AggregateAndVerify(pks, signatures, []byte("a different message")) require.NoError(err) @@ -141,20 +174,26 @@ func TestIncorrectMessageAggregation(t *testing.T) { func TestDifferentMessageAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - sk3, pk3 := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2, pk3} + keyPairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) msg := []byte("TestDifferentMessagesAggregation local signer") differentMsg := []byte("TestDifferentMessagesAggregation local signer with different message") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(differentMsg), - } + signatures, err := mapWithError(keyPairs, func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) + + wrongSig, err := keyPairs[0].signer.Sign(differentMsg) + require.NoError(err) + + signatures[0] = wrongSig + + pks, _ := mapWithError(keyPairs, func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) isValid, err := AggregateAndVerify(pks, signatures, msg) require.NoError(err) @@ -163,20 +202,20 @@ func TestDifferentMessageAggregation(t *testing.T) { func TestOneIncorrectPubKeyAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - sk3, _ := NewKeyPair(require) - _, wrongPk := NewKeyPair(require) + keyPairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) - pks := []*bls.PublicKey{pk1, pk2, wrongPk} + pks, _ := mapWithError(keyPairs[1:], func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) msg := []byte("TestOneIncorrectPubKeyAggregation local signer") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(msg), - } + signatures, err := mapWithError(keyPairs[:len(keyPairs)-1], func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) isValid, err := AggregateAndVerify(pks, signatures, msg) require.NoError(err) @@ -185,18 +224,20 @@ func TestOneIncorrectPubKeyAggregation(t *testing.T) { func TestMorePubkeysThanSignaturesAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - _, pk3 := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2, pk3} + pairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) msg := []byte("TestMorePubkeysThanSignatures local signer") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - } + signatures, err := mapWithError(pairs[1:], func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) + + pks, _ := mapWithError(pairs, func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) isValid, err := AggregateAndVerify(pks, signatures, msg) require.NoError(err) @@ -205,19 +246,20 @@ func TestMorePubkeysThanSignaturesAggregation(t *testing.T) { func TestMoreSignaturesThanPubkeysAggregation(t *testing.T) { require := require.New(t) - sk1, pk1 := NewKeyPair(require) - sk2, pk2 := NewKeyPair(require) - sk3, _ := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2} + pairs := collectN(3, func() keyPair { + return NewKeyPair(require) + }) msg := []byte("TestMoreSignaturesThanPubkeys local signer") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(msg), - } + signatures, err := mapWithError(pairs, func(pair keyPair) (*bls.Signature, error) { + return pair.signer.Sign(msg) + }) + require.NoError(err) + + pks, _ := mapWithError(pairs[1:], func(pair keyPair) (*bls.PublicKey, error) { + return pair.pk, nil + }) isValid, err := AggregateAndVerify(pks, signatures, msg) require.NoError(err) @@ -226,17 +268,16 @@ func TestMoreSignaturesThanPubkeysAggregation(t *testing.T) { func TestNoPubkeysAggregation(t *testing.T) { require := require.New(t) - sk1, _ := NewKeyPair(require) - sk2, _ := NewKeyPair(require) - sk3, _ := NewKeyPair(require) + sks := collectN(3, func() *LocalSigner { + return NewKeyPair(require).signer + }) msg := []byte("TestNoPubkeysAggregation local signer") - signatures := []*bls.Signature{ - sk1.Sign(msg), - sk2.Sign(msg), - sk3.Sign(msg), - } + signatures, err := mapWithError(sks, func(sk *LocalSigner) (*bls.Signature, error) { + return sk.Sign(msg) + }) + require.NoError(err) isValid, err := AggregateAndVerify(nil, signatures, msg) require.ErrorIs(err, bls.ErrNoPublicKeys) @@ -245,11 +286,9 @@ func TestNoPubkeysAggregation(t *testing.T) { func TestNoSignaturesAggregation(t *testing.T) { require := require.New(t) - _, pk1 := NewKeyPair(require) - _, pk2 := NewKeyPair(require) - _, pk3 := NewKeyPair(require) - - pks := []*bls.PublicKey{pk1, pk2, pk3} + pks := collectN(3, func() *bls.PublicKey { + return NewKeyPair(require).pk + }) msg := []byte("TestNoSignaturesAggregation local signer") @@ -260,51 +299,55 @@ func TestNoSignaturesAggregation(t *testing.T) { func TestVerifyValidProofOfPossession(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyValidProofOfPossession local signer") - sig := signer.SignProofOfPossession(msg) + sig, err := keyPair.signer.SignProofOfPossession(msg) + require.NoError(err) - isValid := bls.VerifyProofOfPossession(pk, sig, msg) + isValid := bls.VerifyProofOfPossession(keyPair.pk, sig, msg) require.True(isValid) } func TestVerifyWrongMessageProofOfPossession(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyWrongMessageProofOfPossession local signer") wrongMsg := []byte("TestVerifyWrongMessageProofOfPossession local signer with wrong message") - sig := signer.SignProofOfPossession(msg) + sig, err := keyPair.signer.SignProofOfPossession(msg) + require.NoError(err) - isValid := bls.VerifyProofOfPossession(pk, sig, wrongMsg) + isValid := bls.VerifyProofOfPossession(keyPair.pk, sig, wrongMsg) require.False(isValid) } func TestVerifyWrongPubkeyProofOfPossession(t *testing.T) { require := require.New(t) - signer, _ := NewKeyPair(require) - _, wrongPk := NewKeyPair(require) + correctSigner := NewKeyPair(require) + wrongSigner := NewKeyPair(require) msg := []byte("TestVerifyWrongPubkeyProofOfPossession local signer") - sig := signer.SignProofOfPossession(msg) + sig, err := correctSigner.signer.SignProofOfPossession(msg) + require.NoError(err) - isValid := bls.VerifyProofOfPossession(wrongPk, sig, msg) + isValid := bls.VerifyProofOfPossession(wrongSigner.pk, sig, msg) require.False(isValid) } func TestVerifyWrongMessageSignedProofOfPossession(t *testing.T) { require := require.New(t) - signer, pk := NewKeyPair(require) + keyPair := NewKeyPair(require) msg := []byte("TestVerifyWrongMessageSignedProofOfPossession local signer") wrongMsg := []byte("TestVerifyWrongMessageSignedProofOfPossession local signer with wrong signature") - wrongSig := signer.SignProofOfPossession(wrongMsg) + wrongSig, err := keyPair.signer.SignProofOfPossession(wrongMsg) + require.NoError(err) - isValid := bls.VerifyProofOfPossession(pk, wrongSig, msg) + isValid := bls.VerifyProofOfPossession(keyPair.pk, wrongSig, msg) require.False(isValid) } diff --git a/utils/crypto/bls/signer/localsigner/localsigner.go b/utils/crypto/bls/signer/localsigner/localsigner.go index 965b77fbe697..570f22736446 100644 --- a/utils/crypto/bls/signer/localsigner/localsigner.go +++ b/utils/crypto/bls/signer/localsigner/localsigner.go @@ -22,6 +22,7 @@ type secretKey = blst.SecretKey type LocalSigner struct { sk *secretKey + pk *bls.PublicKey } // NewSecretKey generates a new secret key from the local source of @@ -34,8 +35,9 @@ func New() (*LocalSigner, error) { } sk := blst.KeyGen(ikm[:]) ikm = [32]byte{} // zero out the ikm + pk := new(bls.PublicKey).From(sk) - return &LocalSigner{sk: sk}, nil + return &LocalSigner{sk: sk, pk: pk}, nil } // ToBytes returns the big-endian format of the secret key. @@ -53,21 +55,23 @@ func FromBytes(skBytes []byte) (*LocalSigner, error) { runtime.SetFinalizer(sk, func(sk *secretKey) { sk.Zeroize() }) - return &LocalSigner{sk: sk}, nil + pk := new(bls.PublicKey).From(sk) + + return &LocalSigner{sk: sk, pk: pk}, nil } // PublicKey returns the public key that corresponds to this secret // key. func (s *LocalSigner) PublicKey() *bls.PublicKey { - return new(bls.PublicKey).From(s.sk) + return s.pk } // Sign [msg] to authorize this message -func (s *LocalSigner) Sign(msg []byte) *bls.Signature { - return new(bls.Signature).Sign(s.sk, msg, bls.CiphersuiteSignature.Bytes()) +func (s *LocalSigner) Sign(msg []byte) (*bls.Signature, error) { + return new(bls.Signature).Sign(s.sk, msg, bls.CiphersuiteSignature.Bytes()), nil } // Sign [msg] to prove the ownership -func (s *LocalSigner) SignProofOfPossession(msg []byte) *bls.Signature { - return new(bls.Signature).Sign(s.sk, msg, bls.CiphersuiteProofOfPossession.Bytes()) +func (s *LocalSigner) SignProofOfPossession(msg []byte) (*bls.Signature, error) { + return new(bls.Signature).Sign(s.sk, msg, bls.CiphersuiteProofOfPossession.Bytes()), nil } diff --git a/utils/crypto/bls/signer/localsigner/serialization_test.go b/utils/crypto/bls/signer/localsigner/serialization_test.go index 34009ff99752..9d2bdfc1c35e 100644 --- a/utils/crypto/bls/signer/localsigner/serialization_test.go +++ b/utils/crypto/bls/signer/localsigner/serialization_test.go @@ -39,12 +39,14 @@ func TestSecretKeyBytes(t *testing.T) { sk, err := New() require.NoError(err) - sig := sk.Sign(msg) + sig, err := sk.Sign(msg) + require.NoError(err) skBytes := sk.ToBytes() sk2, err := FromBytes(skBytes) require.NoError(err) - sig2 := sk2.Sign(msg) + sig2, err := sk2.Sign(msg) + require.NoError(err) sk2Bytes := sk2.ToBytes() require.Equal(sk, sk2) diff --git a/vms/platformvm/signer/proof_of_possession.go b/vms/platformvm/signer/proof_of_possession.go index 82a54a85b94c..2f30a43f1fc0 100644 --- a/vms/platformvm/signer/proof_of_possession.go +++ b/vms/platformvm/signer/proof_of_possession.go @@ -30,8 +30,13 @@ type ProofOfPossession struct { func NewProofOfPossession(sk bls.Signer) (*ProofOfPossession, error) { pk := sk.PublicKey() + pkBytes := bls.PublicKeyToCompressedBytes(pk) - sig := sk.SignProofOfPossession(pkBytes) + sig, err := sk.SignProofOfPossession(pkBytes) + if err != nil { + return nil, err + } + sigBytes := bls.SignatureToBytes(sig) pop := &ProofOfPossession{ diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index b678c72e39df..bc96308dd12b 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -2830,11 +2830,11 @@ func TestStandardExecutorRegisterL1ValidatorTx(t *testing.T) { addressedCallPayload.Bytes(), )).Bytes(), )) + sig, err := sk.Sign(unsignedWarp.Bytes()) + require.NoError(t, err) warpSignature := &warp.BitSetSignature{ - Signers: set.NewBits(0).Bytes(), - Signature: ([bls.SignatureLen]byte)(bls.SignatureToBytes( - sk.Sign(unsignedWarp.Bytes()), - )), + Signers: set.NewBits(0).Bytes(), + Signature: ([bls.SignatureLen]byte)(bls.SignatureToBytes(sig)), } warpMessage := must[*warp.Message](t)(warp.NewMessage( unsignedWarp, @@ -3341,11 +3341,13 @@ func TestStandardExecutorSetL1ValidatorWeightTx(t *testing.T) { )).Bytes(), )).Bytes(), )) + + sig, err := sk.Sign(unsignedIncreaseWeightWarpMessage.Bytes()) + require.NoError(t, err) + warpSignature := &warp.BitSetSignature{ - Signers: set.NewBits(0).Bytes(), - Signature: ([bls.SignatureLen]byte)(bls.SignatureToBytes( - sk.Sign(unsignedIncreaseWeightWarpMessage.Bytes()), - )), + Signers: set.NewBits(0).Bytes(), + Signature: ([bls.SignatureLen]byte)(bls.SignatureToBytes(sig)), } increaseWeightWarpMessage := must[*warp.Message](t)(warp.NewMessage( unsignedIncreaseWeightWarpMessage, diff --git a/vms/platformvm/txs/executor/warp_verifier_test.go b/vms/platformvm/txs/executor/warp_verifier_test.go index cca492344911..e0742c80050c 100644 --- a/vms/platformvm/txs/executor/warp_verifier_test.go +++ b/vms/platformvm/txs/executor/warp_verifier_test.go @@ -59,10 +59,11 @@ func TestVerifyWarpMessages(t *testing.T) { ) require.NoError(t, err) - var ( - sig0 = sk0.Sign(validUnsignedWarpMessage.Bytes()) - sig1 = sk1.Sign(validUnsignedWarpMessage.Bytes()) - ) + sig0, err := sk0.Sign(validUnsignedWarpMessage.Bytes()) + require.NoError(t, err) + sig1, err := sk1.Sign(validUnsignedWarpMessage.Bytes()) + require.NoError(t, err) + sig, err := bls.AggregateSignatures([]*bls.Signature{sig0, sig1}) require.NoError(t, err) diff --git a/vms/platformvm/warp/signature_test.go b/vms/platformvm/warp/signature_test.go index c047b26d9de5..d2cd10beea39 100644 --- a/vms/platformvm/warp/signature_test.go +++ b/vms/platformvm/warp/signature_test.go @@ -346,8 +346,10 @@ func TestSignatureVerification(t *testing.T) { signers.Add(1) unsignedBytes := unsignedMsg.Bytes() - vdr0Sig := testVdrs[0].sk.Sign(unsignedBytes) - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) + vdr0Sig, err := testVdrs[0].sk.Sign(unsignedBytes) + require.NoError(err) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr0Sig, vdr1Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -420,7 +422,8 @@ func TestSignatureVerification(t *testing.T) { require.NoError(err) unsignedBytes := unsignedMsg.Bytes() - vdr0Sig := testVdrs[0].sk.Sign(unsignedBytes) + vdr0Sig, err := testVdrs[0].sk.Sign(unsignedBytes) + require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} copy(aggSigBytes[:], bls.SignatureToBytes(vdr0Sig)) @@ -460,10 +463,12 @@ func TestSignatureVerification(t *testing.T) { signers.Add(1) unsignedBytes := unsignedMsg.Bytes() - vdr0Sig := testVdrs[0].sk.Sign(unsignedBytes) + vdr0Sig, err := testVdrs[0].sk.Sign(unsignedBytes) + require.NoError(err) // Give sig from vdr[2] even though the bit vector says it // should be from vdr[1] - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr0Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -505,7 +510,8 @@ func TestSignatureVerification(t *testing.T) { signers.Add(1) unsignedBytes := unsignedMsg.Bytes() - vdr0Sig := testVdrs[0].sk.Sign(unsignedBytes) + vdr0Sig, err := testVdrs[0].sk.Sign(unsignedBytes) + require.NoError(err) // Don't give the sig from vdr[1] aggSigBytes := [bls.SignatureLen]byte{} copy(aggSigBytes[:], bls.SignatureToBytes(vdr0Sig)) @@ -546,11 +552,14 @@ func TestSignatureVerification(t *testing.T) { signers.Add(1) unsignedBytes := unsignedMsg.Bytes() - vdr0Sig := testVdrs[0].sk.Sign(unsignedBytes) - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) + vdr0Sig, err := testVdrs[0].sk.Sign(unsignedBytes) + require.NoError(err) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) // Give sig from vdr[2] even though the bit vector doesn't have // it - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr0Sig, vdr1Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -594,8 +603,10 @@ func TestSignatureVerification(t *testing.T) { signers.Add(2) unsignedBytes := unsignedMsg.Bytes() - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr1Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -639,8 +650,10 @@ func TestSignatureVerification(t *testing.T) { signers.Add(2) unsignedBytes := unsignedMsg.Bytes() - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr1Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -701,8 +714,10 @@ func TestSignatureVerification(t *testing.T) { signers.Add(1) // vdr[2] unsignedBytes := unsignedMsg.Bytes() - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr1Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} @@ -764,7 +779,8 @@ func TestSignatureVerification(t *testing.T) { unsignedBytes := unsignedMsg.Bytes() // Because vdr[1] and vdr[2] share a key, only one of them sign. - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} copy(aggSigBytes[:], bls.SignatureToBytes(vdr2Sig)) @@ -822,8 +838,10 @@ func TestSignatureVerification(t *testing.T) { signers.Add(2) unsignedBytes := unsignedMsg.Bytes() - vdr1Sig := testVdrs[1].sk.Sign(unsignedBytes) - vdr2Sig := testVdrs[2].sk.Sign(unsignedBytes) + vdr1Sig, err := testVdrs[1].sk.Sign(unsignedBytes) + require.NoError(err) + vdr2Sig, err := testVdrs[2].sk.Sign(unsignedBytes) + require.NoError(err) aggSig, err := bls.AggregateSignatures([]*bls.Signature{vdr1Sig, vdr2Sig}) require.NoError(err) aggSigBytes := [bls.SignatureLen]byte{} diff --git a/vms/platformvm/warp/signer.go b/vms/platformvm/warp/signer.go index 3fd51583483b..1af8b6096773 100644 --- a/vms/platformvm/warp/signer.go +++ b/vms/platformvm/warp/signer.go @@ -49,6 +49,9 @@ func (s *signer) Sign(msg *UnsignedMessage) ([]byte, error) { } msgBytes := msg.Bytes() - sig := s.sk.Sign(msgBytes) + sig, err := s.sk.Sign(msgBytes) + if err != nil { + return nil, err + } return bls.SignatureToBytes(sig), nil } diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 1ccbffd2008a..bb3bc20a5339 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -703,7 +703,9 @@ func TestRegisterL1ValidatorTx(t *testing.T) { signers := set.NewBits(0) unsignedBytes := unsignedWarp.Bytes() - sig := sk.Sign(unsignedBytes) + sig, err := sk.Sign(unsignedBytes) + require.NoError(t, err) + sigBytes := [bls.SignatureLen]byte{} copy(sigBytes[:], bls.SignatureToBytes(sig)) @@ -787,15 +789,15 @@ func TestSetL1ValidatorWeightTx(t *testing.T) { sk, err := localsigner.New() require.NoError(t, err) + sig, err := sk.Sign(unsignedWarp.Bytes()) + require.NoError(t, err) warp, err := warp.NewMessage( unsignedWarp, &warp.BitSetSignature{ Signers: set.NewBits(0).Bytes(), Signature: ([bls.SignatureLen]byte)( - bls.SignatureToBytes( - sk.Sign(unsignedWarp.Bytes()), - ), + bls.SignatureToBytes(sig), ), }, ) diff --git a/wallet/subnet/primary/examples/register-l1-validator/main.go b/wallet/subnet/primary/examples/register-l1-validator/main.go index 2281b6d1c718..1c28cbcbf307 100644 --- a/wallet/subnet/primary/examples/register-l1-validator/main.go +++ b/wallet/subnet/primary/examples/register-l1-validator/main.go @@ -112,7 +112,10 @@ func main() { signers := set.NewBits(0) unsignedBytes := unsignedWarp.Bytes() - sig := sk.Sign(unsignedBytes) + sig, err := sk.Sign(unsignedBytes) + if err != nil { + log.Fatalf("failed to sign message: %s\n", err) + } sigBytes := [bls.SignatureLen]byte{} copy(sigBytes[:], bls.SignatureToBytes(sig)) diff --git a/wallet/subnet/primary/examples/set-l1-validator-weight/main.go b/wallet/subnet/primary/examples/set-l1-validator-weight/main.go index af9af5d8b6e1..d5f72f36928a 100644 --- a/wallet/subnet/primary/examples/set-l1-validator-weight/main.go +++ b/wallet/subnet/primary/examples/set-l1-validator-weight/main.go @@ -91,15 +91,17 @@ func main() { if err != nil { log.Fatalf("failed to create unsigned Warp message: %s\n", err) } + signedWarp, err := sk.Sign(unsignedWarp.Bytes()) + if err != nil { + log.Fatalf("failed to sign Warp message: %s\n", err) + } warp, err := warp.NewMessage( unsignedWarp, &warp.BitSetSignature{ Signers: set.NewBits(0).Bytes(), Signature: ([bls.SignatureLen]byte)( - bls.SignatureToBytes( - sk.Sign(unsignedWarp.Bytes()), - ), + bls.SignatureToBytes(signedWarp), ), }, )