diff --git a/WORKSPACE b/WORKSPACE index 175601c342..16f43eca09 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -219,8 +219,8 @@ filegroup( visibility = ["//visibility:public"], ) """, - sha256 = "7e5f838e0f9110471ef8be9401ea687a8ed4d499664dc0eac34ecfdfd03c2ac3", - url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v0.12.3/general.tar.gz", + sha256 = "6b3498001de98c477aa2c256beffc20a85ce1b12b8e0f8e88502a5c3a18c01de", + url = "https://github.com/ethereum/eth2.0-spec-tests/releases/download/v1.0.0-rc.0/general.tar.gz", ) http_archive( diff --git a/beacon-chain/core/blocks/deposit_test.go b/beacon-chain/core/blocks/deposit_test.go index 6a4eec7c53..b9f4a29123 100644 --- a/beacon-chain/core/blocks/deposit_test.go +++ b/beacon-chain/core/blocks/deposit_test.go @@ -132,7 +132,8 @@ func TestProcessDeposits_AddsNewValidatorDeposit(t *testing.T) { } func TestProcessDeposits_RepeatedDeposit_IncreasesValidatorBalance(t *testing.T) { - sk := bls.RandKey() + sk, err := bls.RandKey() + require.NoError(t, err) deposit := ðpb.Deposit{ Data: ðpb.Deposit_Data{ PublicKey: sk.PublicKey().Marshal(), diff --git a/beacon-chain/core/blocks/exit_test.go b/beacon-chain/core/blocks/exit_test.go index 001ef046b2..50a91ab4ac 100644 --- a/beacon-chain/core/blocks/exit_test.go +++ b/beacon-chain/core/blocks/exit_test.go @@ -171,7 +171,9 @@ func TestProcessVoluntaryExits_AppliesCorrectStatus(t *testing.T) { err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch)) require.NoError(t, err) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) + val, err := state.ValidatorAtIndex(0) require.NoError(t, err) val.PublicKey = priv.PublicKey().Marshal() diff --git a/beacon-chain/core/blocks/header_test.go b/beacon-chain/core/blocks/header_test.go index c0c5de4219..03c4b37029 100644 --- a/beacon-chain/core/blocks/header_test.go +++ b/beacon-chain/core/blocks/header_test.go @@ -48,7 +48,8 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) { require.NoError(t, err) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) pID, err := helpers.BeaconProposerIndex(state) require.NoError(t, err) block := testutil.NewBeaconBlock() @@ -126,7 +127,8 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) { require.NoError(t, err) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv) require.NoError(t, err) validators[5896].PublicKey = priv.PublicKey().Marshal() @@ -164,7 +166,8 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) { bh.Slot = 9 require.NoError(t, state.SetLatestBlockHeader(bh)) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv) require.NoError(t, err) validators[5896].PublicKey = priv.PublicKey().Marshal() @@ -202,7 +205,8 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) { parentRoot, err := state.LatestBlockHeader().HashTreeRoot() require.NoError(t, err) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) blockSig, err := helpers.ComputeDomainAndSign(state, currentEpoch, []byte("hello"), params.BeaconConfig().DomainBeaconProposer, priv) require.NoError(t, err) @@ -247,7 +251,8 @@ func TestProcessBlockHeader_OK(t *testing.T) { require.NoError(t, err) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) pID, err := helpers.BeaconProposerIndex(state) require.NoError(t, err) block := testutil.NewBeaconBlock() @@ -307,7 +312,8 @@ func TestBlockSignatureSet_OK(t *testing.T) { require.NoError(t, err) currentEpoch := helpers.CurrentEpoch(state) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) pID, err := helpers.BeaconProposerIndex(state) require.NoError(t, err) block := testutil.NewBeaconBlock() diff --git a/beacon-chain/core/blocks/proposer_slashing_test.go b/beacon-chain/core/blocks/proposer_slashing_test.go index 89b84a8705..a883d516bd 100644 --- a/beacon-chain/core/blocks/proposer_slashing_test.go +++ b/beacon-chain/core/blocks/proposer_slashing_test.go @@ -194,6 +194,13 @@ func TestVerifyProposerSlashing(t *testing.T) { beaconState, sks := testutil.DeterministicGenesisState(t, 2) currentSlot := uint64(0) require.NoError(t, beaconState.SetSlot(currentSlot)) + rand1, err := bls.RandKey() + require.NoError(t, err) + sig1 := rand1.Sign([]byte("foo")).Marshal() + + rand2, err := bls.RandKey() + require.NoError(t, err) + sig2 := rand2.Sign([]byte("bar")).Marshal() tests := []struct { name string @@ -239,7 +246,7 @@ func TestVerifyProposerSlashing(t *testing.T) { BodyRoot: bytesutil.PadTo([]byte{}, 32), ParentRoot: bytesutil.PadTo([]byte{}, 32), }, - Signature: bls.RandKey().Sign([]byte("foo")).Marshal(), + Signature: sig1, }, Header_2: ðpb.SignedBeaconBlockHeader{ Header: ðpb.BeaconBlockHeader{ @@ -249,7 +256,7 @@ func TestVerifyProposerSlashing(t *testing.T) { BodyRoot: bytesutil.PadTo([]byte{}, 32), ParentRoot: bytesutil.PadTo([]byte{}, 32), }, - Signature: bls.RandKey().Sign([]byte("bar")).Marshal(), + Signature: sig2, }, }, beaconState: beaconState, diff --git a/beacon-chain/core/helpers/attestation_test.go b/beacon-chain/core/helpers/attestation_test.go index 2a85510a39..aa52706936 100644 --- a/beacon-chain/core/helpers/attestation_test.go +++ b/beacon-chain/core/helpers/attestation_test.go @@ -49,7 +49,8 @@ func TestAttestation_AggregateSignature(t *testing.T) { atts := make([]*ethpb.Attestation, 0, 100) msg := bytesutil.ToBytes32([]byte("hello")) for i := 0; i < 100; i++ { - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -66,7 +67,8 @@ func TestAttestation_AggregateSignature(t *testing.T) { atts := make([]*ethpb.Attestation, 0, 100) msg := []byte("hello") for i := 0; i < 100; i++ { - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg) pubkeys = append(pubkeys, pub) diff --git a/beacon-chain/core/state/transition_test.go b/beacon-chain/core/state/transition_test.go index 408f57b196..587e07ce1e 100644 --- a/beacon-chain/core/state/transition_test.go +++ b/beacon-chain/core/state/transition_test.go @@ -201,7 +201,8 @@ func TestProcessBlock_IncorrectProposerSlashing(t *testing.T) { func TestProcessBlock_IncorrectProcessBlockAttestations(t *testing.T) { beaconState, privKeys := testutil.DeterministicGenesisState(t, 100) - + priv, err := bls.RandKey() + require.NoError(t, err) att := ðpb.Attestation{ Data: ðpb.AttestationData{ Target: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)}, @@ -209,7 +210,7 @@ func TestProcessBlock_IncorrectProcessBlockAttestations(t *testing.T) { BeaconBlockRoot: make([]byte, 32), }, AggregationBits: bitfield.NewBitlist(3), - Signature: bls.RandKey().Sign([]byte("foo")).Marshal(), + Signature: priv.Sign([]byte("foo")).Marshal(), } block, err := testutil.GenerateFullBlock(beaconState, privKeys, nil, 1) @@ -675,7 +676,8 @@ func BenchmarkProcessBlk_65536Validators_FullBlock(b *testing.B) { // Set up randao reveal object for block proposerIdx, err := helpers.BeaconProposerIndex(s) require.NoError(b, err) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(b, err) v := s.Validators() v[proposerIdx].PublicKey = priv.PublicKey().Marshal() buf := make([]byte, 32) diff --git a/beacon-chain/operations/attestations/kv/aggregated_test.go b/beacon-chain/operations/attestations/kv/aggregated_test.go index a7b331c780..ff611604cb 100644 --- a/beacon-chain/operations/attestations/kv/aggregated_test.go +++ b/beacon-chain/operations/attestations/kv/aggregated_test.go @@ -15,7 +15,8 @@ import ( func TestKV_Aggregated_AggregateUnaggregatedAttestations(t *testing.T) { cache := NewAttCaches() - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig1 := priv.Sign([]byte{'a'}) sig2 := priv.Sign([]byte{'b'}) att1 := ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1, BeaconBlockRoot: make([]byte, 32), Target: ðpb.Checkpoint{Root: make([]byte, 32)}, Source: ðpb.Checkpoint{Root: make([]byte, 32)}}, AggregationBits: bitfield.Bitlist{0b1001}, Signature: sig1.Marshal()} @@ -46,7 +47,8 @@ func TestKV_Aggregated_AggregateUnaggregatedAttestationsBySlotIndex(t *testing.T } } genSign := func() []byte { - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) return priv.Sign([]byte{'a'}).Marshal() } diff --git a/beacon-chain/operations/attestations/prepare_forkchoice_test.go b/beacon-chain/operations/attestations/prepare_forkchoice_test.go index efd77de7f6..c8407293bd 100644 --- a/beacon-chain/operations/attestations/prepare_forkchoice_test.go +++ b/beacon-chain/operations/attestations/prepare_forkchoice_test.go @@ -19,8 +19,9 @@ func TestBatchAttestations_Multiple(t *testing.T) { s, err := NewService(context.Background(), &Config{Pool: NewPool()}) require.NoError(t, err) - sk := bls.RandKey() - sig := sk.Sign([]byte("dummy_test_data")) + priv, err := bls.RandKey() + require.NoError(t, err) + sig := priv.Sign([]byte("dummy_test_data")) var mockRoot [32]byte unaggregatedAtts := []*ethpb.Attestation{ @@ -115,8 +116,9 @@ func TestBatchAttestations_Single(t *testing.T) { s, err := NewService(context.Background(), &Config{Pool: NewPool()}) require.NoError(t, err) - sk := bls.RandKey() - sig := sk.Sign([]byte("dummy_test_data")) + priv, err := bls.RandKey() + require.NoError(t, err) + sig := priv.Sign([]byte("dummy_test_data")) mockRoot := [32]byte{} d := ðpb.AttestationData{ BeaconBlockRoot: mockRoot[:], @@ -156,8 +158,9 @@ func TestAggregateAndSaveForkChoiceAtts_Single(t *testing.T) { s, err := NewService(context.Background(), &Config{Pool: NewPool()}) require.NoError(t, err) - sk := bls.RandKey() - sig := sk.Sign([]byte("dummy_test_data")) + priv, err := bls.RandKey() + require.NoError(t, err) + sig := priv.Sign([]byte("dummy_test_data")) mockRoot := [32]byte{} d := ðpb.AttestationData{ BeaconBlockRoot: mockRoot[:], @@ -179,8 +182,9 @@ func TestAggregateAndSaveForkChoiceAtts_Multiple(t *testing.T) { s, err := NewService(context.Background(), &Config{Pool: NewPool()}) require.NoError(t, err) - sk := bls.RandKey() - sig := sk.Sign([]byte("dummy_test_data")) + priv, err := bls.RandKey() + require.NoError(t, err) + sig := priv.Sign([]byte("dummy_test_data")) mockRoot := [32]byte{} d := ðpb.AttestationData{ BeaconBlockRoot: mockRoot[:], diff --git a/beacon-chain/powchain/deposit_test.go b/beacon-chain/powchain/deposit_test.go index 40d72205be..1ccb70bdd7 100644 --- a/beacon-chain/powchain/deposit_test.go +++ b/beacon-chain/powchain/deposit_test.go @@ -191,14 +191,15 @@ func TestProcessDeposit_IncompleteDeposit(t *testing.T) { }, } - sk := bls.RandKey() - deposit.Data.PublicKey = sk.PublicKey().Marshal() + priv, err := bls.RandKey() + require.NoError(t, err) + deposit.Data.PublicKey = priv.PublicKey().Marshal() d, err := helpers.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil) require.NoError(t, err) signedRoot, err := helpers.ComputeSigningRoot(deposit.Data, d) require.NoError(t, err) - sig := sk.Sign(signedRoot[:]) + sig := priv.Sign(signedRoot[:]) deposit.Data.Signature = sig.Marshal() trie, err := trieutil.NewTrie(params.BeaconConfig().DepositContractTreeDepth) diff --git a/beacon-chain/rpc/validator/aggregator_test.go b/beacon-chain/rpc/validator/aggregator_test.go index 3dbe0f5b32..9a1bc1a700 100644 --- a/beacon-chain/rpc/validator/aggregator_test.go +++ b/beacon-chain/rpc/validator/aggregator_test.go @@ -59,7 +59,8 @@ func TestSubmitAggregateAndProof_CantFindValidatorIndex(t *testing.T) { BeaconDB: db, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'A'}) req := ðpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey(3)} wanted := "Could not locate validator index in DB" @@ -87,7 +88,8 @@ func TestSubmitAggregateAndProof_IsAggregatorAndNoAtts(t *testing.T) { AttPool: attestations.NewPool(), } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'A'}) v, err := s.ValidatorAtIndex(1) require.NoError(t, err) @@ -121,7 +123,8 @@ func TestSubmitAggregateAndProof_UnaggregateOk(t *testing.T) { P2P: &mockp2p.MockBroadcaster{}, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'B'}) v, err := beaconState.ValidatorAtIndex(1) require.NoError(t, err) @@ -159,7 +162,8 @@ func TestSubmitAggregateAndProof_AggregateOk(t *testing.T) { P2P: &mockp2p.MockBroadcaster{}, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'B'}) v, err := beaconState.ValidatorAtIndex(1) require.NoError(t, err) @@ -199,7 +203,8 @@ func TestSubmitAggregateAndProof_AggregateNotOk(t *testing.T) { P2P: &mockp2p.MockBroadcaster{}, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'B'}) v, err := beaconState.ValidatorAtIndex(1) require.NoError(t, err) @@ -332,7 +337,8 @@ func TestSubmitAggregateAndProof_PreferOwnAttestation(t *testing.T) { P2P: &mockp2p.MockBroadcaster{}, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'B'}) v, err := beaconState.ValidatorAtIndex(1) require.NoError(t, err) @@ -383,7 +389,8 @@ func TestSubmitAggregateAndProof_SelectsMostBitsWhenOwnAttestationNotPresent(t * P2P: &mockp2p.MockBroadcaster{}, } - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) sig := priv.Sign([]byte{'B'}) v, err := beaconState.ValidatorAtIndex(1) require.NoError(t, err) diff --git a/beacon-chain/rpc/validator/attester_test.go b/beacon-chain/rpc/validator/attester_test.go index ef86a1f97c..c4ec67dfd5 100644 --- a/beacon-chain/rpc/validator/attester_test.go +++ b/beacon-chain/rpc/validator/attester_test.go @@ -63,7 +63,8 @@ func TestProposeAttestation_OK(t *testing.T) { require.NoError(t, db.SaveState(ctx, state, root)) require.NoError(t, db.SaveHeadBlockRoot(ctx, root)) - sk := bls.RandKey() + sk, err := bls.RandKey() + require.NoError(t, err) sig := sk.Sign([]byte("dummy_test_data")) req := ðpb.Attestation{ Signature: sig.Marshal(), diff --git a/beacon-chain/rpc/validator/proposer_test.go b/beacon-chain/rpc/validator/proposer_test.go index 8a37ab43de..9bb1affa62 100644 --- a/beacon-chain/rpc/validator/proposer_test.go +++ b/beacon-chain/rpc/validator/proposer_test.go @@ -2087,8 +2087,9 @@ func TestProposer_DeleteAttsInPool_Aggregated(t *testing.T) { s := &Server{ AttPool: attestations.NewPool(), } - - sig := bls.RandKey().Sign([]byte("foo")).Marshal() + priv, err := bls.RandKey() + require.NoError(t, err) + sig := priv.Sign([]byte("foo")).Marshal() aggregatedAtts := []*ethpb.Attestation{{Data: ðpb.AttestationData{Slot: 1, BeaconBlockRoot: make([]byte, 32), Target: ðpb.Checkpoint{Root: make([]byte, 32)}, Source: ðpb.Checkpoint{Root: make([]byte, 32)}}, AggregationBits: bitfield.Bitlist{0b10101}, Signature: sig}, {Data: ðpb.AttestationData{Slot: 1, BeaconBlockRoot: make([]byte, 32), Target: ðpb.Checkpoint{Root: make([]byte, 32)}, Source: ðpb.Checkpoint{Root: make([]byte, 32)}}, AggregationBits: bitfield.Bitlist{0b11010}, Signature: sig}} unaggregatedAtts := []*ethpb.Attestation{{Data: ðpb.AttestationData{Slot: 1, BeaconBlockRoot: make([]byte, 32), Target: ðpb.Checkpoint{Root: make([]byte, 32)}, Source: ðpb.Checkpoint{Root: make([]byte, 32)}}, AggregationBits: bitfield.Bitlist{0b1001}, Signature: sig}, {Data: ðpb.AttestationData{Slot: 1, BeaconBlockRoot: make([]byte, 32), Target: ðpb.Checkpoint{Root: make([]byte, 32)}, Source: ðpb.Checkpoint{Root: make([]byte, 32)}}, AggregationBits: bitfield.Bitlist{0b0001}, Signature: sig}} diff --git a/beacon-chain/rpc/validator/server_test.go b/beacon-chain/rpc/validator/server_test.go index 96b21a557e..61c3474ea0 100644 --- a/beacon-chain/rpc/validator/server_test.go +++ b/beacon-chain/rpc/validator/server_test.go @@ -109,8 +109,10 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) { params.OverrideBeaconConfig(params.MainnetConfig()) ctx := context.Background() - priv1 := bls.RandKey() - priv2 := bls.RandKey() + priv1, err := bls.RandKey() + require.NoError(t, err) + priv2, err := bls.RandKey() + require.NoError(t, err) pubKey1 := priv1.PublicKey().Marshal() pubKey2 := priv2.PublicKey().Marshal() @@ -196,9 +198,12 @@ func TestWaitForActivation_ValidatorOriginallyExists(t *testing.T) { func TestWaitForActivation_MultipleStatuses(t *testing.T) { db, _ := dbutil.SetupDB(t) - priv1 := bls.RandKey() - priv2 := bls.RandKey() - priv3 := bls.RandKey() + priv1, err := bls.RandKey() + require.NoError(t, err) + priv2, err := bls.RandKey() + require.NoError(t, err) + priv3, err := bls.RandKey() + require.NoError(t, err) pubKey1 := priv1.PublicKey().Marshal() pubKey2 := priv2.PublicKey().Marshal() diff --git a/beacon-chain/sync/pending_attestations_queue_test.go b/beacon-chain/sync/pending_attestations_queue_test.go index 86857cfe0c..8c0918c901 100644 --- a/beacon-chain/sync/pending_attestations_queue_test.go +++ b/beacon-chain/sync/pending_attestations_queue_test.go @@ -67,9 +67,11 @@ func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) { stateSummaryCache: cache.NewStateSummaryCache(), } + priv, err := bls.RandKey() + require.NoError(t, err) a := ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ - Signature: bls.RandKey().Sign([]byte("foo")).Marshal(), + Signature: priv.Sign([]byte("foo")).Marshal(), AggregationBits: bitfield.Bitlist{0x02}, Data: ðpb.AttestationData{ Target: ðpb.Checkpoint{Root: make([]byte, 32)}, @@ -111,9 +113,11 @@ func TestProcessPendingAtts_NoBroadcastWithBadSignature(t *testing.T) { stateSummaryCache: cache.NewStateSummaryCache(), } + priv, err := bls.RandKey() + require.NoError(t, err) a := ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ - Signature: bls.RandKey().Sign([]byte("foo")).Marshal(), + Signature: priv.Sign([]byte("foo")).Marshal(), AggregationBits: bitfield.Bitlist{0x02}, Data: ðpb.AttestationData{ Target: ðpb.Checkpoint{Root: make([]byte, 32)}, diff --git a/beacon-chain/sync/validate_proposer_slashing_test.go b/beacon-chain/sync/validate_proposer_slashing_test.go index 7591ab02d3..e842234243 100644 --- a/beacon-chain/sync/validate_proposer_slashing_test.go +++ b/beacon-chain/sync/validate_proposer_slashing_test.go @@ -61,7 +61,8 @@ func setupValidProposerSlashing(t *testing.T) (*ethpb.ProposerSlashing, *stateTr }) require.NoError(t, err) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) someRoot := [32]byte{1, 2, 3} someRoot2 := [32]byte{4, 5, 6} header1 := ðpb.SignedBeaconBlockHeader{ diff --git a/beacon-chain/sync/validate_voluntary_exit_test.go b/beacon-chain/sync/validate_voluntary_exit_test.go index 9657262314..f23dade4ea 100644 --- a/beacon-chain/sync/validate_voluntary_exit_test.go +++ b/beacon-chain/sync/validate_voluntary_exit_test.go @@ -49,7 +49,8 @@ func setupValidExit(t *testing.T) (*ethpb.SignedVoluntaryExit, *stateTrie.Beacon err = state.SetSlot(state.Slot() + (params.BeaconConfig().ShardCommitteePeriod * params.BeaconConfig().SlotsPerEpoch)) require.NoError(t, err) - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) exit.Signature, err = helpers.ComputeDomainAndSign(state, helpers.CurrentEpoch(state), exit.Exit, params.BeaconConfig().DomainVoluntaryExit, priv) require.NoError(t, err) diff --git a/deps.bzl b/deps.bzl index 560e7bc062..b78b22e504 100644 --- a/deps.bzl +++ b/deps.bzl @@ -692,8 +692,8 @@ def prysm_deps(): go_repository( name = "com_github_herumi_bls_eth_go_binary", importpath = "github.com/herumi/bls-eth-go-binary", - sum = "h1:KUHKqKMt9r78Ko07pTvlvEW6vPq24+efv1YXWk9Ba1U=", - version = "v0.0.0-20201008062400-71567a52ad65", + sum = "h1:S7pKW74AvYc89WawL6IxGSnJRxF4TkE1GITYqKFyYy4=", + version = "v0.0.0-20201019012252-4b463a10c225", ) go_repository( name = "com_github_hpcloud_tail", @@ -3416,11 +3416,11 @@ def prysm_deps(): http_archive( name = "com_github_supranational_blst", urls = [ - "https://github.com/supranational/blst/archive/cd0847a7580b22677e9069f671a79f0d874442b3.tar.gz", + "https://github.com/supranational/blst/archive/03c38676b08bd0bdbb120b94464d9c692a509842.tar.gz", ], - strip_prefix = "blst-cd0847a7580b22677e9069f671a79f0d874442b3", + strip_prefix = "blst-03c38676b08bd0bdbb120b94464d9c692a509842", build_file = "//third_party:blst/blst.BUILD", - sha256 = "047aee659f6228b7d0d8a1c963d0e75de6e5d605756ff9cc1f3aafd2ea2b378b", + sha256 = "390695dd5084228de3e9f06e6800c79a5f90cdef4129fa36aaa18b1d24730138", ) go_repository( name = "com_github_nbutton23_zxcvbn_go", diff --git a/go.mod b/go.mod index d486297ace..c6d85ec0b1 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/grpc-gateway v1.14.6 github.com/hashicorp/golang-lru v0.5.4 - github.com/herumi/bls-eth-go-binary v0.0.0-20201008062400-71567a52ad65 + github.com/herumi/bls-eth-go-binary v0.0.0-20201019012252-4b463a10c225 github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279 github.com/influxdata/influxdb v1.8.0 // indirect github.com/ipfs/go-ipfs-addr v0.0.1 @@ -97,7 +97,7 @@ require ( github.com/sirupsen/logrus v1.6.0 github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect github.com/stretchr/testify v1.6.1 - github.com/supranational/blst v0.1.2-alpha.1.0.20200917144033-cd0847a7580b + github.com/supranational/blst v0.2.1-0.20201025154037-03c38676b08b github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef github.com/tyler-smith/go-bip39 v1.0.2 github.com/urfave/cli/v2 v2.2.0 diff --git a/go.sum b/go.sum index 52b865a191..0eb8941034 100644 --- a/go.sum +++ b/go.sum @@ -360,8 +360,8 @@ github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/herumi/bls-eth-go-binary v0.0.0-20200706085701-832d8c2c0f7d h1:P8yaFmLwc5ZlUx2sHuawcdQvpv5/0GM+WEGJ07ljN3g= github.com/herumi/bls-eth-go-binary v0.0.0-20200706085701-832d8c2c0f7d/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= -github.com/herumi/bls-eth-go-binary v0.0.0-20201008062400-71567a52ad65 h1:KUHKqKMt9r78Ko07pTvlvEW6vPq24+efv1YXWk9Ba1U= -github.com/herumi/bls-eth-go-binary v0.0.0-20201008062400-71567a52ad65/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= +github.com/herumi/bls-eth-go-binary v0.0.0-20201019012252-4b463a10c225 h1:S7pKW74AvYc89WawL6IxGSnJRxF4TkE1GITYqKFyYy4= +github.com/herumi/bls-eth-go-binary v0.0.0-20201019012252-4b463a10c225/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/holiman/uint256 v1.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw= github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= @@ -999,8 +999,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/supranational/blst v0.1.2-alpha.1.0.20200917144033-cd0847a7580b h1:ofaf5ea+Xq4P7OdOWTwHUuLO/0sjAIoQHiJTDbhjbB4= -github.com/supranational/blst v0.1.2-alpha.1.0.20200917144033-cd0847a7580b/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.2.1-0.20201025154037-03c38676b08b h1:r+p8ymKeCTy9qi6do3EHUpdnijQgU+37kGXmM4yZKmo= +github.com/supranational/blst v0.2.1-0.20201025154037-03c38676b08b/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= diff --git a/shared/aggregation/attestations/attestations_bench_test.go b/shared/aggregation/attestations/attestations_bench_test.go index 787b06eb84..b587795f1e 100644 --- a/shared/aggregation/attestations/attestations_bench_test.go +++ b/shared/aggregation/attestations/attestations_bench_test.go @@ -6,7 +6,7 @@ import ( "github.com/prysmaticlabs/go-bitfield" aggtesting "github.com/prysmaticlabs/prysm/shared/aggregation/testing" "github.com/prysmaticlabs/prysm/shared/bls" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -14,10 +14,10 @@ import ( func BenchmarkAggregateAttestations_Aggregate(b *testing.B) { // Override expensive BLS aggregation method with cheap no-op such that this benchmark profiles // the logic of aggregation selection rather than BLS logic. - aggregateSignatures = func(sigs []iface.Signature) iface.Signature { + aggregateSignatures = func(sigs []common.Signature) common.Signature { return sigs[0] } - signatureFromBytes = func(sig []byte) (iface.Signature, error) { + signatureFromBytes = func(sig []byte) (common.Signature, error) { return bls.NewAggregateSignature(), nil } defer func() { diff --git a/shared/bls/BUILD.bazel b/shared/bls/BUILD.bazel index 8f03dcd912..34006ac77f 100644 --- a/shared/bls/BUILD.bazel +++ b/shared/bls/BUILD.bazel @@ -1,3 +1,4 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") load("@prysm//tools/go:def.bzl", "go_library") go_library( @@ -5,6 +6,7 @@ go_library( srcs = [ "bls.go", "constants.go", + "error.go", "interface.go", "signature_set.go", ], @@ -12,8 +14,19 @@ go_library( visibility = ["//visibility:public"], deps = [ "//shared/bls/blst:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bls/herumi:go_default_library", - "//shared/bls/iface:go_default_library", "//shared/featureconfig:go_default_library", ], ) + +go_test( + name = "go_default_test", + srcs = ["bls_test.go"], + embed = [":go_default_library"], + deps = [ + "//shared/bls/common:go_default_library", + "//shared/featureconfig:go_default_library", + "//shared/testutil/require:go_default_library", + ], +) diff --git a/shared/bls/bls.go b/shared/bls/bls.go index 8a5515ee95..97e54f7813 100644 --- a/shared/bls/bls.go +++ b/shared/bls/bls.go @@ -5,8 +5,8 @@ package bls import ( "github.com/prysmaticlabs/prysm/shared/bls/blst" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/bls/herumi" - "github.com/prysmaticlabs/prysm/shared/bls/iface" "github.com/prysmaticlabs/prysm/shared/featureconfig" ) @@ -43,7 +43,7 @@ func AggregatePublicKeys(pubs [][]byte) (PublicKey, error) { } // AggregateSignatures converts a list of signatures into a single, aggregated sig. -func AggregateSignatures(sigs []iface.Signature) iface.Signature { +func AggregateSignatures(sigs []common.Signature) common.Signature { if featureconfig.Get().EnableBlst { return blst.AggregateSignatures(sigs) } @@ -51,7 +51,7 @@ func AggregateSignatures(sigs []iface.Signature) iface.Signature { } // VerifyMultipleSignatures verifies multiple signatures for distinct messages securely. -func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []iface.PublicKey) (bool, error) { +func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []common.PublicKey) (bool, error) { if featureconfig.Get().EnableBlst { return blst.VerifyMultipleSignatures(sigs, msgs, pubKeys) } @@ -69,7 +69,7 @@ func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []iface.Pu } // NewAggregateSignature creates a blank aggregate signature. -func NewAggregateSignature() iface.Signature { +func NewAggregateSignature() common.Signature { if featureconfig.Get().EnableBlst { return blst.NewAggregateSignature() } @@ -77,7 +77,7 @@ func NewAggregateSignature() iface.Signature { } // RandKey creates a new private key using a random input. -func RandKey() iface.SecretKey { +func RandKey() (common.SecretKey, error) { if featureconfig.Get().EnableBlst { return blst.RandKey() } diff --git a/shared/bls/bls_test.go b/shared/bls/bls_test.go new file mode 100644 index 0000000000..ca6977305f --- /dev/null +++ b/shared/bls/bls_test.go @@ -0,0 +1,51 @@ +package bls + +import ( + "testing" + + "github.com/prysmaticlabs/prysm/shared/bls/common" + "github.com/prysmaticlabs/prysm/shared/featureconfig" + "github.com/prysmaticlabs/prysm/shared/testutil/require" +) + +func TestDisallowZeroSecretKeys(t *testing.T) { + flags := &featureconfig.Flags{} + t.Run("herumi", func(t *testing.T) { + flags := &featureconfig.Flags{} + reset := featureconfig.InitWithReset(flags) + defer reset() + + _, err := SecretKeyFromBytes(common.ZeroSecretKey[:]) + require.Equal(t, common.ErrZeroKey, err) + }) + + t.Run("blst", func(t *testing.T) { + flags.EnableBlst = true + reset := featureconfig.InitWithReset(flags) + defer reset() + + _, err := SecretKeyFromBytes(common.ZeroSecretKey[:]) + require.Equal(t, common.ErrZeroKey, err) + }) +} + +func TestDisallowZeroPublicKeys(t *testing.T) { + flags := &featureconfig.Flags{} + + t.Run("herumi", func(t *testing.T) { + reset := featureconfig.InitWithReset(flags) + defer reset() + + _, err := PublicKeyFromBytes(common.InfinitePublicKey[:]) + require.Equal(t, common.ErrInfinitePubKey, err) + }) + + t.Run("blst", func(t *testing.T) { + flags.EnableBlst = true + reset := featureconfig.InitWithReset(flags) + defer reset() + + _, err := PublicKeyFromBytes(common.InfinitePublicKey[:]) + require.Equal(t, common.ErrInfinitePubKey, err) + }) +} diff --git a/shared/bls/blst/BUILD.bazel b/shared/bls/blst/BUILD.bazel index 9eb39d2801..9ac6c0e172 100644 --- a/shared/bls/blst/BUILD.bazel +++ b/shared/bls/blst/BUILD.bazel @@ -81,7 +81,7 @@ go_library( ":blst_enabled_android_amd64", ":blst_enabled_android_arm64", ): [ - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/featureconfig:go_default_library", "//shared/params:go_default_library", "//shared/rand:go_default_library", @@ -89,7 +89,7 @@ go_library( "@com_github_pkg_errors//:go_default_library", "@com_github_supranational_blst//:go_default_library", ], - "//conditions:default": ["//shared/bls/iface:go_default_library"], + "//conditions:default": ["//shared/bls/common:go_default_library"], }), ) @@ -116,7 +116,7 @@ go_test( ":blst_enabled_android_arm64", ): [ "//shared/bls/blst:go_default_library", - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/testutil/assert:go_default_library", "//shared/testutil/require:go_default_library", @@ -147,7 +147,7 @@ go_test( ":blst_enabled_android_amd64", ":blst_enabled_android_arm64", ): [ - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/testutil/assert:go_default_library", "//shared/testutil/require:go_default_library", @@ -174,7 +174,7 @@ go_test( ], deps = [ ":go_default_library", - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/hashutil:go_default_library", ], diff --git a/shared/bls/blst/bls_benchmark_test.go b/shared/bls/blst/bls_benchmark_test.go index 4e4b338803..8d3071a73a 100644 --- a/shared/bls/blst/bls_benchmark_test.go +++ b/shared/bls/blst/bls_benchmark_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/prysmaticlabs/prysm/shared/bls/blst" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" + "github.com/prysmaticlabs/prysm/shared/testutil/require" ) func BenchmarkSignature_Verify(b *testing.B) { - sk := blst.RandKey() + sk, err := blst.RandKey() + require.NoError(b, err) msg := []byte("Some msg") sig := sk.Sign(msg) @@ -27,12 +29,13 @@ func BenchmarkSignature_Verify(b *testing.B) { func BenchmarkSignature_AggregateVerify(b *testing.B) { sigN := 128 // MAX_ATTESTATIONS per block. - var pks []iface.PublicKey - var sigs []iface.Signature + var pks []common.PublicKey + var sigs []common.Signature var msgs [][32]byte for i := 0; i < sigN; i++ { msg := [32]byte{'s', 'i', 'g', 'n', 'e', 'd', byte(i)} - sk := blst.RandKey() + sk, err := blst.RandKey() + require.NoError(b, err) sig := sk.Sign(msg[:]) pks = append(pks, sk.PublicKey()) sigs = append(sigs, sig) @@ -50,7 +53,8 @@ func BenchmarkSignature_AggregateVerify(b *testing.B) { } func BenchmarkSecretKey_Marshal(b *testing.B) { - key := blst.RandKey() + key, err := blst.RandKey() + require.NoError(b, err) d := key.Marshal() b.ResetTimer() diff --git a/shared/bls/blst/public_key.go b/shared/bls/blst/public_key.go index 692c6db527..519efa7eba 100644 --- a/shared/bls/blst/public_key.go +++ b/shared/bls/blst/public_key.go @@ -8,7 +8,7 @@ import ( "github.com/dgraph-io/ristretto" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" ) @@ -26,7 +26,7 @@ type PublicKey struct { } // PublicKeyFromBytes creates a BLS public key from a BigEndian byte slice. -func PublicKeyFromBytes(pubKey []byte) (iface.PublicKey, error) { +func PublicKeyFromBytes(pubKey []byte) (common.PublicKey, error) { if featureconfig.Get().SkipBLSVerify { return &PublicKey{}, nil } @@ -36,19 +36,21 @@ func PublicKeyFromBytes(pubKey []byte) (iface.PublicKey, error) { if cv, ok := pubkeyCache.Get(string(pubKey)); ok { return cv.(*PublicKey).Copy(), nil } - p := new(blstPublicKey).Uncompress(pubKey) if p == nil { return nil, errors.New("could not unmarshal bytes into public key") } pubKeyObj := &PublicKey{p: p} + if pubKeyObj.IsInfinite() { + return nil, common.ErrInfinitePubKey + } copiedKey := pubKeyObj.Copy() pubkeyCache.Set(string(pubKey), copiedKey, 48) return pubKeyObj, nil } // AggregatePublicKeys aggregates the provided raw public keys into a single key. -func AggregatePublicKeys(pubs [][]byte) (iface.PublicKey, error) { +func AggregatePublicKeys(pubs [][]byte) (common.PublicKey, error) { if featureconfig.Get().SkipBLSVerify { return &PublicKey{}, nil } @@ -80,13 +82,19 @@ func (p *PublicKey) Marshal() []byte { } // Copy the public key to a new pointer reference. -func (p *PublicKey) Copy() iface.PublicKey { +func (p *PublicKey) Copy() common.PublicKey { np := *p.p return &PublicKey{p: &np} } +// IsInfinite checks if the public key is infinite. +func (p *PublicKey) IsInfinite() bool { + zeroKey := new(blstPublicKey) + return p.p.Equals(zeroKey) +} + // Aggregate two public keys. -func (p *PublicKey) Aggregate(p2 iface.PublicKey) iface.PublicKey { +func (p *PublicKey) Aggregate(p2 common.PublicKey) common.PublicKey { if featureconfig.Get().SkipBLSVerify { return p } diff --git a/shared/bls/blst/public_key_test.go b/shared/bls/blst/public_key_test.go index c0992309dc..b8fbc5dc13 100644 --- a/shared/bls/blst/public_key_test.go +++ b/shared/bls/blst/public_key_test.go @@ -64,11 +64,15 @@ func TestPublicKeyFromBytes(t *testing.T) { } func TestPublicKey_Copy(t *testing.T) { - pubkeyA := blst.RandKey().PublicKey() + priv, err := blst.RandKey() + require.NoError(t, err) + pubkeyA := priv.PublicKey() pubkeyBytes := pubkeyA.Marshal() pubkeyB := pubkeyA.Copy() - pubkeyB.Aggregate(blst.RandKey().PublicKey()) + priv2, err := blst.RandKey() + require.NoError(t, err) + pubkeyB.Aggregate(priv2.PublicKey()) require.DeepEqual(t, pubkeyA.Marshal(), pubkeyBytes, "Pubkey was mutated after copy") } diff --git a/shared/bls/blst/secret_key.go b/shared/bls/blst/secret_key.go index 3f08523e22..dd605672cf 100644 --- a/shared/bls/blst/secret_key.go +++ b/shared/bls/blst/secret_key.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/rand" @@ -20,35 +20,48 @@ type bls12SecretKey struct { } // RandKey creates a new private key using a random method provided as an io.Reader. -func RandKey() iface.SecretKey { +func RandKey() (common.SecretKey, error) { // Generate 32 bytes of randomness var ikm [32]byte _, err := rand.NewGenerator().Read(ikm[:]) if err != nil { - return nil + return nil, err } - return &bls12SecretKey{blst.KeyGen(ikm[:])} + // Defensive check, that we have not generated a secret key, + secKey := &bls12SecretKey{blst.KeyGen(ikm[:])} + if secKey.IsZero() { + return nil, common.ErrZeroKey + } + return secKey, nil } // SecretKeyFromBytes creates a BLS private key from a BigEndian byte slice. -func SecretKeyFromBytes(privKey []byte) (iface.SecretKey, error) { +func SecretKeyFromBytes(privKey []byte) (common.SecretKey, error) { if len(privKey) != params.BeaconConfig().BLSSecretKeyLength { return nil, fmt.Errorf("secret key must be %d bytes", params.BeaconConfig().BLSSecretKeyLength) } - secKey := new(blst.SecretKey).Deserialize(privKey) if secKey == nil { return nil, errors.New("could not unmarshal bytes into secret key") } - - return &bls12SecretKey{p: secKey}, nil + wrappedKey := &bls12SecretKey{p: secKey} + if wrappedKey.IsZero() { + return nil, common.ErrZeroKey + } + return wrappedKey, nil } // PublicKey obtains the public key corresponding to the BLS secret key. -func (s *bls12SecretKey) PublicKey() iface.PublicKey { +func (s *bls12SecretKey) PublicKey() common.PublicKey { return &PublicKey{p: new(blstPublicKey).From(s.p)} } +// IsZero checks if the secret key is a zero key. +func (s *bls12SecretKey) IsZero() bool { + zeroKey := new(blst.SecretKey) + return s.p.Equals(zeroKey) +} + // Sign a message using a secret key - in a beacon/validator client. // // In IETF draft BLS specification: @@ -57,7 +70,7 @@ func (s *bls12SecretKey) PublicKey() iface.PublicKey { // // In ETH2.0 specification: // def Sign(SK: int, message: Bytes) -> BLSSignature -func (s *bls12SecretKey) Sign(msg []byte) iface.Signature { +func (s *bls12SecretKey) Sign(msg []byte) common.Signature { if featureconfig.Get().SkipBLSVerify { return &Signature{} } diff --git a/shared/bls/blst/secret_key_test.go b/shared/bls/blst/secret_key_test.go index 0dd22b694b..88f892c981 100644 --- a/shared/bls/blst/secret_key_test.go +++ b/shared/bls/blst/secret_key_test.go @@ -15,7 +15,9 @@ import ( ) func TestMarshalUnmarshal(t *testing.T) { - b := blst.RandKey().Marshal() + priv, err := blst.RandKey() + require.NoError(t, err) + b := priv.Marshal() b32 := bytesutil.ToBytes32(b) pk, err := blst.SecretKeyFromBytes(b32[:]) require.NoError(t, err) @@ -75,9 +77,10 @@ func TestSecretKeyFromBytes(t *testing.T) { } func TestSerialize(t *testing.T) { - rk := blst.RandKey() + rk, err := blst.RandKey() + require.NoError(t, err) b := rk.Marshal() - _, err := blst.SecretKeyFromBytes(b) + _, err = blst.SecretKeyFromBytes(b) assert.NoError(t, err) } diff --git a/shared/bls/blst/signature.go b/shared/bls/blst/signature.go index 0061146c55..4ef3b8d349 100644 --- a/shared/bls/blst/signature.go +++ b/shared/bls/blst/signature.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/rand" @@ -25,7 +25,7 @@ type Signature struct { } // SignatureFromBytes creates a BLS signature from a LittleEndian byte slice. -func SignatureFromBytes(sig []byte) (iface.Signature, error) { +func SignatureFromBytes(sig []byte) (common.Signature, error) { if featureconfig.Get().SkipBLSVerify { return &Signature{}, nil } @@ -48,7 +48,7 @@ func SignatureFromBytes(sig []byte) (iface.Signature, error) { // // In ETH2.0 specification: // def Verify(PK: BLSPubkey, message: Bytes, signature: BLSSignature) -> bool -func (s *Signature) Verify(pubKey iface.PublicKey, msg []byte) bool { +func (s *Signature) Verify(pubKey common.PublicKey, msg []byte) bool { if featureconfig.Get().SkipBLSVerify { return true } @@ -68,7 +68,7 @@ func (s *Signature) Verify(pubKey iface.PublicKey, msg []byte) bool { // // In ETH2.0 specification: // def AggregateVerify(pairs: Sequence[PK: BLSPubkey, message: Bytes], signature: BLSSignature) -> boo -func (s *Signature) AggregateVerify(pubKeys []iface.PublicKey, msgs [][32]byte) bool { +func (s *Signature) AggregateVerify(pubKeys []common.PublicKey, msgs [][32]byte) bool { if featureconfig.Get().SkipBLSVerify { return true } @@ -98,7 +98,7 @@ func (s *Signature) AggregateVerify(pubKeys []iface.PublicKey, msgs [][32]byte) // // In ETH2.0 specification: // def FastAggregateVerify(PKs: Sequence[BLSPubkey], message: Bytes, signature: BLSSignature) -> bool -func (s *Signature) FastAggregateVerify(pubKeys []iface.PublicKey, msg [32]byte) bool { +func (s *Signature) FastAggregateVerify(pubKeys []common.PublicKey, msg [32]byte) bool { if featureconfig.Get().SkipBLSVerify { return true } @@ -114,13 +114,13 @@ func (s *Signature) FastAggregateVerify(pubKeys []iface.PublicKey, msg [32]byte) } // NewAggregateSignature creates a blank aggregate signature. -func NewAggregateSignature() iface.Signature { +func NewAggregateSignature() common.Signature { sig := blst.HashToG2([]byte{'m', 'o', 'c', 'k'}, dst).ToAffine() return &Signature{s: sig} } // AggregateSignatures converts a list of signatures into a single, aggregated sig. -func AggregateSignatures(sigs []iface.Signature) iface.Signature { +func AggregateSignatures(sigs []common.Signature) common.Signature { if len(sigs) == 0 { return nil } @@ -151,7 +151,7 @@ func AggregateSignatures(sigs []iface.Signature) iface.Signature { // def Aggregate(signatures: Sequence[BLSSignature]) -> BLSSignature // // Deprecated: Use AggregateSignatures. -func Aggregate(sigs []iface.Signature) iface.Signature { +func Aggregate(sigs []common.Signature) common.Signature { return AggregateSignatures(sigs) } @@ -162,7 +162,7 @@ func Aggregate(sigs []iface.Signature) iface.Signature { // P'_{i,j} = P_{i,j} * r_i // e(S*, G) = \prod_{i=1}^n \prod_{j=1}^{m_i} e(P'_{i,j}, M_{i,j}) // Using this we can verify multiple signatures safely. -func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []iface.PublicKey) (bool, error) { +func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []common.PublicKey) (bool, error) { if featureconfig.Get().SkipBLSVerify { return true, nil } @@ -205,7 +205,7 @@ func (s *Signature) Marshal() []byte { } // Copy returns a full deep copy of a signature. -func (s *Signature) Copy() iface.Signature { +func (s *Signature) Copy() common.Signature { sign := *s.s return &Signature{s: &sign} } diff --git a/shared/bls/blst/signature_test.go b/shared/bls/blst/signature_test.go index 6da074b31c..7d1c83bbc8 100644 --- a/shared/bls/blst/signature_test.go +++ b/shared/bls/blst/signature_test.go @@ -8,13 +8,14 @@ import ( "errors" "testing" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/testutil/assert" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) func TestSignVerify(t *testing.T) { - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() msg := []byte("hello") sig := priv.Sign(msg) @@ -22,12 +23,13 @@ func TestSignVerify(t *testing.T) { } func TestAggregateVerify(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) var msgs [][32]byte for i := 0; i < 100; i++ { msg := [32]byte{'h', 'e', 'l', 'l', 'o', byte(i)} - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -39,11 +41,12 @@ func TestAggregateVerify(t *testing.T) { } func TestFastAggregateVerify(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) msg := [32]byte{'h', 'e', 'l', 'l', 'o'} for i := 0; i < 100; i++ { - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -55,7 +58,8 @@ func TestFastAggregateVerify(t *testing.T) { } func TestVerifyCompressed(t *testing.T) { - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() msg := []byte("hello") sig := priv.Sign(msg) @@ -64,12 +68,13 @@ func TestVerifyCompressed(t *testing.T) { } func TestMultipleSignatureVerification(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) sigs := make([][]byte, 0, 100) var msgs [][32]byte for i := 0; i < 100; i++ { msg := [32]byte{'h', 'e', 'l', 'l', 'o', byte(i)} - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]).Marshal() pubkeys = append(pubkeys, pub) @@ -82,7 +87,7 @@ func TestMultipleSignatureVerification(t *testing.T) { } func TestFastAggregateVerify_ReturnsFalseOnEmptyPubKeyList(t *testing.T) { - var pubkeys []iface.PublicKey + var pubkeys []common.PublicKey msg := [32]byte{'h', 'e', 'l', 'l', 'o'} aggSig := NewAggregateSignature() @@ -140,7 +145,9 @@ func TestSignatureFromBytes(t *testing.T) { } func TestCopy(t *testing.T) { - key, ok := RandKey().(*bls12SecretKey) + priv, err := RandKey() + require.NoError(t, err) + key, ok := priv.(*bls12SecretKey) require.Equal(t, true, ok) signatureA := &Signature{s: new(blstSignature).Sign(key.p, []byte("foo"), dst)} diff --git a/shared/bls/blst/stub.go b/shared/bls/blst/stub.go index 1bdb0d5413..485d2d164f 100644 --- a/shared/bls/blst/stub.go +++ b/shared/bls/blst/stub.go @@ -2,7 +2,9 @@ package blst -import "github.com/prysmaticlabs/prysm/shared/bls/iface" +import ( + "github.com/prysmaticlabs/prysm/shared/bls/common" +) // This stub file exists until build issues can be resolved for darwin and windows. const err = "blst is only supported on linux with blst_enabled gotag" @@ -11,12 +13,12 @@ const err = "blst is only supported on linux with blst_enabled gotag" type SecretKey struct{} // PublicKey -- stub -func (s SecretKey) PublicKey() iface.PublicKey { +func (s SecretKey) PublicKey() common.PublicKey { panic(err) } // Sign -- stub -func (s SecretKey) Sign(_ []byte) iface.Signature { +func (s SecretKey) Sign(_ []byte) common.Signature { panic(err) } @@ -25,6 +27,11 @@ func (s SecretKey) Marshal() []byte { panic(err) } +// IsZero -- stub +func (s SecretKey) IsZero() bool { + panic(err) +} + // PublicKey -- stub type PublicKey struct{} @@ -34,12 +41,17 @@ func (p PublicKey) Marshal() []byte { } // Copy -- stub -func (p PublicKey) Copy() iface.PublicKey { +func (p PublicKey) Copy() common.PublicKey { panic(err) } // Aggregate -- stub -func (p PublicKey) Aggregate(_ iface.PublicKey) iface.PublicKey { +func (p PublicKey) Aggregate(_ common.PublicKey) common.PublicKey { + panic(err) +} + +// IsInfinite -- stub +func (s PublicKey) IsInfinite() bool { panic(err) } @@ -47,17 +59,17 @@ func (p PublicKey) Aggregate(_ iface.PublicKey) iface.PublicKey { type Signature struct{} // Verify -- stub -func (s Signature) Verify(_ iface.PublicKey, _ []byte) bool { +func (s Signature) Verify(_ common.PublicKey, _ []byte) bool { panic(err) } // AggregateVerify -- stub -func (s Signature) AggregateVerify(_ []iface.PublicKey, _ [][32]byte) bool { +func (s Signature) AggregateVerify(_ []common.PublicKey, _ [][32]byte) bool { panic(err) } // FastAggregateVerify -- stub -func (s Signature) FastAggregateVerify(_ []iface.PublicKey, _ [32]byte) bool { +func (s Signature) FastAggregateVerify(_ []common.PublicKey, _ [32]byte) bool { panic(err) } @@ -67,7 +79,7 @@ func (s Signature) Marshal() []byte { } // Copy -- stub -func (s Signature) Copy() iface.Signature { +func (s Signature) Copy() common.Signature { panic(err) } @@ -92,22 +104,22 @@ func AggregatePublicKeys(_ [][]byte) (PublicKey, error) { } // AggregateSignatures -- stub -func AggregateSignatures(_ []iface.Signature) iface.Signature { +func AggregateSignatures(_ []common.Signature) common.Signature { panic(err) } // VerifyMultipleSignatures -- stub -func VerifyMultipleSignatures(_ [][]byte, _ [][32]byte, _ []iface.PublicKey) (bool, error) { +func VerifyMultipleSignatures(_ [][]byte, _ [][32]byte, _ []common.PublicKey) (bool, error) { panic(err) } // NewAggregateSignature -- stub -func NewAggregateSignature() iface.Signature { +func NewAggregateSignature() common.Signature { panic(err) } // RandKey -- stub -func RandKey() iface.SecretKey { +func RandKey() (common.SecretKey, error) { panic(err) } diff --git a/shared/bls/common/BUILD.bazel b/shared/bls/common/BUILD.bazel new file mode 100644 index 0000000000..2e33af991e --- /dev/null +++ b/shared/bls/common/BUILD.bazel @@ -0,0 +1,12 @@ +load("@prysm//tools/go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "constants.go", + "error.go", + "interface.go", + ], + importpath = "github.com/prysmaticlabs/prysm/shared/bls/common", + visibility = ["//shared/bls:__subpackages__"], +) diff --git a/shared/bls/common/constants.go b/shared/bls/common/constants.go new file mode 100644 index 0000000000..e92c668338 --- /dev/null +++ b/shared/bls/common/constants.go @@ -0,0 +1,7 @@ +package common + +// ZeroSecretKey represents a zero secret key. +var ZeroSecretKey = [32]byte{} + +// InfinitePublicKey represents an infinite public key. +var InfinitePublicKey = [48]byte{0xC0} diff --git a/shared/bls/common/error.go b/shared/bls/common/error.go new file mode 100644 index 0000000000..66dc62d29d --- /dev/null +++ b/shared/bls/common/error.go @@ -0,0 +1,9 @@ +package common + +import "errors" + +// ErrZeroKey describes an error due to a zero secret key. +var ErrZeroKey = errors.New("received secret key is zero") + +// ErrInfinitePubKey describes an error due to an infinite public key. +var ErrInfinitePubKey = errors.New("received an infinite public key") diff --git a/shared/bls/iface/interface.go b/shared/bls/common/interface.go similarity index 84% rename from shared/bls/iface/interface.go rename to shared/bls/common/interface.go index ceff3f760c..2253b222f0 100644 --- a/shared/bls/iface/interface.go +++ b/shared/bls/common/interface.go @@ -1,15 +1,16 @@ -// Package iface provides the BLS interfaces that are implemented by the various BLS wrappers. +// Package common provides the BLS interfaces that are implemented by the various BLS wrappers. // // This package should not be used by downstream consumers. These interfaces are re-exporter by // github.com/prysmaticlabs/prysm/shared/bls. This package exists to prevent an import circular // dependency. -package iface +package common // SecretKey represents a BLS secret or private key. type SecretKey interface { PublicKey() PublicKey Sign(msg []byte) Signature Marshal() []byte + IsZero() bool } // PublicKey represents a BLS public key. @@ -17,6 +18,7 @@ type PublicKey interface { Marshal() []byte Copy() PublicKey Aggregate(p2 PublicKey) PublicKey + IsInfinite() bool } // Signature represents a BLS signature. diff --git a/shared/bls/constants.go b/shared/bls/constants.go index f66aa5517a..64db0fc487 100644 --- a/shared/bls/constants.go +++ b/shared/bls/constants.go @@ -1,7 +1,17 @@ package bls +import ( + "github.com/prysmaticlabs/prysm/shared/bls/common" +) + // DomainByteLength length of domain byte array. const DomainByteLength = 4 // CurveOrder for the BLS12-381 curve. const CurveOrder = "52435875175126190479447740508185965837690552500527637822603658699938581184513" + +// ZeroSecretKey represents a zero secret key. +var ZeroSecretKey = common.ZeroSecretKey + +// InfinitePublicKey represents an infinite public key. +var InfinitePublicKey = common.InfinitePublicKey diff --git a/shared/bls/error.go b/shared/bls/error.go new file mode 100644 index 0000000000..133c3c24c0 --- /dev/null +++ b/shared/bls/error.go @@ -0,0 +1,11 @@ +package bls + +import ( + "github.com/prysmaticlabs/prysm/shared/bls/common" +) + +// ErrZeroKey describes an error due to a zero secret key. +var ErrZeroKey = common.ErrZeroKey + +// ErrInfinitePubKey describes an error due to an infinite public key. +var ErrInfinitePubKey = common.ErrInfinitePubKey diff --git a/shared/bls/herumi/BUILD.bazel b/shared/bls/herumi/BUILD.bazel index 4b6725bf4b..fa2a9451fe 100644 --- a/shared/bls/herumi/BUILD.bazel +++ b/shared/bls/herumi/BUILD.bazel @@ -17,7 +17,7 @@ go_library( "//shared/bls:__pkg__", ], deps = [ - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/featureconfig:go_default_library", "//shared/params:go_default_library", @@ -37,7 +37,7 @@ go_test( ], embed = [":go_default_library"], deps = [ - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/testutil/assert:go_default_library", "//shared/testutil/require:go_default_library", @@ -63,7 +63,7 @@ go_test( ], deps = [ ":go_default_library", - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/hashutil:go_default_library", "@herumi_bls_eth_go_binary//:go_default_library", diff --git a/shared/bls/herumi/bls_benchmark_test.go b/shared/bls/herumi/bls_benchmark_test.go index 15f4686d6b..2ca2f48f0a 100644 --- a/shared/bls/herumi/bls_benchmark_test.go +++ b/shared/bls/herumi/bls_benchmark_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/herumi/bls-eth-go-binary/bls" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/bls/herumi" - "github.com/prysmaticlabs/prysm/shared/bls/iface" "github.com/prysmaticlabs/prysm/shared/hashutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -31,7 +31,8 @@ func BenchmarkPairing(b *testing.B) { } func BenchmarkSignature_Verify(b *testing.B) { - sk := herumi.RandKey() + sk, err := herumi.RandKey() + require.NoError(b, err) msg := []byte("Some msg") sig := sk.Sign(msg) @@ -45,12 +46,13 @@ func BenchmarkSignature_Verify(b *testing.B) { func BenchmarkSignature_AggregateVerify(b *testing.B) { sigN := 128 // MAX_ATTESTATIONS per block. - var pks []iface.PublicKey - var sigs []iface.Signature + var pks []common.PublicKey + var sigs []common.Signature var msgs [][32]byte for i := 0; i < sigN; i++ { msg := [32]byte{'s', 'i', 'g', 'n', 'e', 'd', byte(i)} - sk := herumi.RandKey() + sk, err := herumi.RandKey() + require.NoError(b, err) sig := sk.Sign(msg[:]) pks = append(pks, sk.PublicKey()) sigs = append(sigs, sig) @@ -66,7 +68,8 @@ func BenchmarkSignature_AggregateVerify(b *testing.B) { } func BenchmarkSecretKey_Marshal(b *testing.B) { - key := herumi.RandKey() + key, err := herumi.RandKey() + require.NoError(b, err) d := key.Marshal() b.ResetTimer() diff --git a/shared/bls/herumi/public_key.go b/shared/bls/herumi/public_key.go index abf94116c0..134cc60bc0 100644 --- a/shared/bls/herumi/public_key.go +++ b/shared/bls/herumi/public_key.go @@ -6,7 +6,7 @@ import ( "github.com/dgraph-io/ristretto" bls12 "github.com/herumi/bls-eth-go-binary/bls" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" ) @@ -24,7 +24,7 @@ type PublicKey struct { } // PublicKeyFromBytes creates a BLS public key from a BigEndian byte slice. -func PublicKeyFromBytes(pubKey []byte) (iface.PublicKey, error) { +func PublicKeyFromBytes(pubKey []byte) (common.PublicKey, error) { if featureconfig.Get().SkipBLSVerify { return &PublicKey{}, nil } @@ -40,12 +40,15 @@ func PublicKeyFromBytes(pubKey []byte) (iface.PublicKey, error) { return nil, errors.Wrap(err, "could not unmarshal bytes into public key") } pubKeyObj := &PublicKey{p: p} + if pubKeyObj.IsInfinite() { + return nil, common.ErrInfinitePubKey + } pubkeyCache.Set(string(pubKey), pubKeyObj.Copy(), 48) return pubKeyObj, nil } // AggregatePublicKeys aggregates the provided raw public keys into a single key. -func AggregatePublicKeys(pubs [][]byte) (iface.PublicKey, error) { +func AggregatePublicKeys(pubs [][]byte) (common.PublicKey, error) { if len(pubs) == 0 { return &PublicKey{}, nil } @@ -69,13 +72,18 @@ func (p *PublicKey) Marshal() []byte { } // Copy the public key to a new pointer reference. -func (p *PublicKey) Copy() iface.PublicKey { +func (p *PublicKey) Copy() common.PublicKey { np := *p.p return &PublicKey{p: &np} } +// IsInfinite checks if the public key is infinite. +func (p *PublicKey) IsInfinite() bool { + return p.p.IsZero() +} + // Aggregate two public keys. -func (p *PublicKey) Aggregate(p2 iface.PublicKey) iface.PublicKey { +func (p *PublicKey) Aggregate(p2 common.PublicKey) common.PublicKey { if featureconfig.Get().SkipBLSVerify { return p } diff --git a/shared/bls/herumi/public_key_test.go b/shared/bls/herumi/public_key_test.go index 5c4fc2f516..d7356405f9 100644 --- a/shared/bls/herumi/public_key_test.go +++ b/shared/bls/herumi/public_key_test.go @@ -7,6 +7,7 @@ import ( "github.com/prysmaticlabs/prysm/shared/bls/herumi" "github.com/prysmaticlabs/prysm/shared/testutil/assert" + "github.com/prysmaticlabs/prysm/shared/testutil/require" ) func TestPublicKeyFromBytes(t *testing.T) { @@ -59,11 +60,15 @@ func TestPublicKeyFromBytes(t *testing.T) { } func TestPublicKey_Copy(t *testing.T) { - pubkeyA := herumi.RandKey().PublicKey() + priv, err := herumi.RandKey() + require.NoError(t, err) + pubkeyA := priv.PublicKey() pubkeyBytes := pubkeyA.Marshal() pubkeyB := pubkeyA.Copy() - pubkeyB.Aggregate(herumi.RandKey().PublicKey()) + priv2, err := herumi.RandKey() + require.NoError(t, err) + pubkeyB.Aggregate(priv2.PublicKey()) if !bytes.Equal(pubkeyA.Marshal(), pubkeyBytes) { t.Fatal("Pubkey was mutated after copy") diff --git a/shared/bls/herumi/secret_key.go b/shared/bls/herumi/secret_key.go index 85b559434f..8384702858 100644 --- a/shared/bls/herumi/secret_key.go +++ b/shared/bls/herumi/secret_key.go @@ -5,7 +5,7 @@ import ( bls12 "github.com/herumi/bls-eth-go-binary/bls" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" ) @@ -16,14 +16,17 @@ type bls12SecretKey struct { } // RandKey creates a new private key using a random method provided as an io.Reader. -func RandKey() iface.SecretKey { +func RandKey() (common.SecretKey, error) { secKey := &bls12.SecretKey{} secKey.SetByCSPRNG() - return &bls12SecretKey{secKey} + if secKey.IsZero() { + return nil, errors.New("generated a zero secret key") + } + return &bls12SecretKey{secKey}, nil } // SecretKeyFromBytes creates a BLS private key from a BigEndian byte slice. -func SecretKeyFromBytes(privKey []byte) (iface.SecretKey, error) { +func SecretKeyFromBytes(privKey []byte) (common.SecretKey, error) { if len(privKey) != params.BeaconConfig().BLSSecretKeyLength { return nil, fmt.Errorf("secret key must be %d bytes", params.BeaconConfig().BLSSecretKeyLength) } @@ -32,11 +35,15 @@ func SecretKeyFromBytes(privKey []byte) (iface.SecretKey, error) { if err != nil { return nil, errors.Wrap(err, "could not unmarshal bytes into secret key") } - return &bls12SecretKey{p: secKey}, err + wrappedKey := &bls12SecretKey{p: secKey} + if wrappedKey.IsZero() { + return nil, common.ErrZeroKey + } + return wrappedKey, err } // PublicKey obtains the public key corresponding to the BLS secret key. -func (s *bls12SecretKey) PublicKey() iface.PublicKey { +func (s *bls12SecretKey) PublicKey() common.PublicKey { return &PublicKey{p: s.p.GetPublicKey()} } @@ -48,7 +55,7 @@ func (s *bls12SecretKey) PublicKey() iface.PublicKey { // // In ETH2.0 specification: // def Sign(SK: int, message: Bytes) -> BLSSignature -func (s *bls12SecretKey) Sign(msg []byte) iface.Signature { +func (s *bls12SecretKey) Sign(msg []byte) common.Signature { if featureconfig.Get().SkipBLSVerify { return &Signature{} } @@ -65,3 +72,8 @@ func (s *bls12SecretKey) Marshal() []byte { } return keyBytes } + +// IsZero checks if the secret key is a zero key. +func (s *bls12SecretKey) IsZero() bool { + return s.p.IsZero() +} diff --git a/shared/bls/herumi/secret_key_test.go b/shared/bls/herumi/secret_key_test.go index 84ff1a34c2..6cdb276714 100644 --- a/shared/bls/herumi/secret_key_test.go +++ b/shared/bls/herumi/secret_key_test.go @@ -11,7 +11,9 @@ import ( ) func TestMarshalUnmarshal(t *testing.T) { - b := herumi.RandKey().Marshal() + priv, err := herumi.RandKey() + require.NoError(t, err) + b := priv.Marshal() b32 := bytesutil.ToBytes32(b) pk, err := herumi.SecretKeyFromBytes(b32[:]) require.NoError(t, err) @@ -70,9 +72,10 @@ func TestSecretKeyFromBytes(t *testing.T) { } func TestSerialize(t *testing.T) { - rk := herumi.RandKey() + rk, err := herumi.RandKey() + require.NoError(t, err) b := rk.Marshal() - _, err := herumi.SecretKeyFromBytes(b) + _, err = herumi.SecretKeyFromBytes(b) assert.NoError(t, err) } diff --git a/shared/bls/herumi/signature.go b/shared/bls/herumi/signature.go index 3249771aec..11a1a77798 100644 --- a/shared/bls/herumi/signature.go +++ b/shared/bls/herumi/signature.go @@ -5,7 +5,7 @@ import ( bls12 "github.com/herumi/bls-eth-go-binary/bls" "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/params" @@ -18,7 +18,7 @@ type Signature struct { } // SignatureFromBytes creates a BLS signature from a LittleEndian byte slice. -func SignatureFromBytes(sig []byte) (iface.Signature, error) { +func SignatureFromBytes(sig []byte) (common.Signature, error) { if featureconfig.Get().SkipBLSVerify { return &Signature{}, nil } @@ -42,10 +42,14 @@ func SignatureFromBytes(sig []byte) (iface.Signature, error) { // // In ETH2.0 specification: // def Verify(PK: BLSPubkey, message: Bytes, signature: BLSSignature) -> bool -func (s *Signature) Verify(pubKey iface.PublicKey, msg []byte) bool { +func (s *Signature) Verify(pubKey common.PublicKey, msg []byte) bool { if featureconfig.Get().SkipBLSVerify { return true } + // Reject infinite public keys. + if pubKey.(*PublicKey).p.IsZero() { + return false + } return s.s.VerifyByte(pubKey.(*PublicKey).p, msg) } @@ -62,7 +66,7 @@ func (s *Signature) Verify(pubKey iface.PublicKey, msg []byte) bool { // // In ETH2.0 specification: // def AggregateVerify(pairs: Sequence[PK: BLSPubkey, message: Bytes], signature: BLSSignature) -> boo -func (s *Signature) AggregateVerify(pubKeys []iface.PublicKey, msgs [][32]byte) bool { +func (s *Signature) AggregateVerify(pubKeys []common.PublicKey, msgs [][32]byte) bool { if featureconfig.Get().SkipBLSVerify { return true } @@ -93,7 +97,7 @@ func (s *Signature) AggregateVerify(pubKeys []iface.PublicKey, msgs [][32]byte) // // In ETH2.0 specification: // def FastAggregateVerify(PKs: Sequence[BLSPubkey], message: Bytes, signature: BLSSignature) -> bool -func (s *Signature) FastAggregateVerify(pubKeys []iface.PublicKey, msg [32]byte) bool { +func (s *Signature) FastAggregateVerify(pubKeys []common.PublicKey, msg [32]byte) bool { if featureconfig.Get().SkipBLSVerify { return true } @@ -109,12 +113,12 @@ func (s *Signature) FastAggregateVerify(pubKeys []iface.PublicKey, msg [32]byte) } // NewAggregateSignature creates a blank aggregate signature. -func NewAggregateSignature() iface.Signature { +func NewAggregateSignature() common.Signature { return &Signature{s: bls12.HashAndMapToSignature([]byte{'m', 'o', 'c', 'k'})} } // AggregateSignatures converts a list of signatures into a single, aggregated sig. -func AggregateSignatures(sigs []iface.Signature) iface.Signature { +func AggregateSignatures(sigs []common.Signature) common.Signature { if len(sigs) == 0 { return nil } @@ -140,7 +144,7 @@ func AggregateSignatures(sigs []iface.Signature) iface.Signature { // def Aggregate(signatures: Sequence[BLSSignature]) -> BLSSignature // // Deprecated: Use AggregateSignatures. -func Aggregate(sigs []iface.Signature) iface.Signature { +func Aggregate(sigs []common.Signature) common.Signature { return AggregateSignatures(sigs) } @@ -151,7 +155,7 @@ func Aggregate(sigs []iface.Signature) iface.Signature { // P'_{i,j} = P_{i,j} * r_i // e(S*, G) = \prod_{i=1}^n \prod_{j=1}^{m_i} e(P'_{i,j}, M_{i,j}) // Using this we can verify multiple signatures safely. -func VerifyMultipleSignatures(sigs []iface.Signature, msgs [][32]byte, pubKeys []iface.PublicKey) (bool, error) { +func VerifyMultipleSignatures(sigs []common.Signature, msgs [][32]byte, pubKeys []common.PublicKey) (bool, error) { if featureconfig.Get().SkipBLSVerify { return true, nil } @@ -209,7 +213,7 @@ func (s *Signature) Marshal() []byte { } // Copy returns a full deep copy of a signature. -func (s *Signature) Copy() iface.Signature { +func (s *Signature) Copy() common.Signature { sign := *s.s return &Signature{s: &sign} } diff --git a/shared/bls/herumi/signature_test.go b/shared/bls/herumi/signature_test.go index e29c8a9c81..0f8271ad9e 100644 --- a/shared/bls/herumi/signature_test.go +++ b/shared/bls/herumi/signature_test.go @@ -5,13 +5,14 @@ import ( "testing" bls12 "github.com/herumi/bls-eth-go-binary/bls" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/testutil/assert" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) func TestSignVerify(t *testing.T) { - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() msg := []byte("hello") sig := priv.Sign(msg) @@ -19,12 +20,13 @@ func TestSignVerify(t *testing.T) { } func TestAggregateVerify(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) var msgs [][32]byte for i := 0; i < 100; i++ { msg := [32]byte{'h', 'e', 'l', 'l', 'o', byte(i)} - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -36,11 +38,12 @@ func TestAggregateVerify(t *testing.T) { } func TestFastAggregateVerify(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) msg := [32]byte{'h', 'e', 'l', 'l', 'o'} for i := 0; i < 100; i++ { - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -51,12 +54,13 @@ func TestFastAggregateVerify(t *testing.T) { } func TestMultipleSignatureVerification(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) var msgs [][32]byte for i := 0; i < 100; i++ { msg := [32]byte{'h', 'e', 'l', 'l', 'o', byte(i)} - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -69,12 +73,13 @@ func TestMultipleSignatureVerification(t *testing.T) { } func TestMultipleSignatureVerification_FailsCorrectly(t *testing.T) { - pubkeys := make([]iface.PublicKey, 0, 100) - sigs := make([]iface.Signature, 0, 100) + pubkeys := make([]common.PublicKey, 0, 100) + sigs := make([]common.Signature, 0, 100) var msgs [][32]byte for i := 0; i < 100; i++ { msg := [32]byte{'h', 'e', 'l', 'l', 'o', byte(i)} - priv := RandKey() + priv, err := RandKey() + require.NoError(t, err) pub := priv.PublicKey() sig := priv.Sign(msg[:]) pubkeys = append(pubkeys, pub) @@ -132,7 +137,7 @@ func TestMultipleSignatureVerification_FailsCorrectly(t *testing.T) { } func TestFastAggregateVerify_ReturnsFalseOnEmptyPubKeyList(t *testing.T) { - var pubkeys []iface.PublicKey + var pubkeys []common.PublicKey msg := [32]byte{'h', 'e', 'l', 'l', 'o'} aggSig := NewAggregateSignature() diff --git a/shared/bls/iface/BUILD.bazel b/shared/bls/iface/BUILD.bazel deleted file mode 100644 index 7c92325a2e..0000000000 --- a/shared/bls/iface/BUILD.bazel +++ /dev/null @@ -1,8 +0,0 @@ -load("@prysm//tools/go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["interface.go"], - importpath = "github.com/prysmaticlabs/prysm/shared/bls/iface", - visibility = ["//shared/bls:__subpackages__"], -) diff --git a/shared/bls/interface.go b/shared/bls/interface.go index b569a64006..62a8255fd7 100644 --- a/shared/bls/interface.go +++ b/shared/bls/interface.go @@ -1,14 +1,14 @@ package bls import ( - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" ) // PublicKey represents a BLS public key. -type PublicKey = iface.PublicKey +type PublicKey = common.PublicKey // SecretKey represents a BLS secret or private key. -type SecretKey = iface.SecretKey +type SecretKey = common.SecretKey // Signature represents a BLS signature. -type Signature = iface.Signature +type Signature = common.Signature diff --git a/shared/bls/spectest/BUILD.bazel b/shared/bls/spectest/BUILD.bazel index 98aad8fb6b..a127984064 100644 --- a/shared/bls/spectest/BUILD.bazel +++ b/shared/bls/spectest/BUILD.bazel @@ -32,7 +32,7 @@ go_test( tags = ["spectest"], deps = [ "//shared/bls:go_default_library", - "//shared/bls/iface:go_default_library", + "//shared/bls/common:go_default_library", "//shared/bytesutil:go_default_library", "//shared/featureconfig:go_default_library", "//shared/testutil:go_default_library", diff --git a/shared/bls/spectest/aggregate_test.go b/shared/bls/spectest/aggregate_test.go index 9777d5c61c..ca31eeeb73 100644 --- a/shared/bls/spectest/aggregate_test.go +++ b/shared/bls/spectest/aggregate_test.go @@ -8,7 +8,7 @@ import ( "github.com/ghodss/yaml" "github.com/prysmaticlabs/prysm/shared/bls" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" @@ -35,7 +35,7 @@ func testAggregateYaml(t *testing.T) { require.NoError(t, err) test := &AggregateTest{} require.NoError(t, yaml.Unmarshal(file, test)) - var sigs []iface.Signature + var sigs []common.Signature for _, s := range test.Input { sigBytes, err := hex.DecodeString(s[2:]) require.NoError(t, err) diff --git a/shared/bls/spectest/aggregate_verify_test.go b/shared/bls/spectest/aggregate_verify_test.go index 6b1ebddaa4..605853273b 100644 --- a/shared/bls/spectest/aggregate_verify_test.go +++ b/shared/bls/spectest/aggregate_verify_test.go @@ -2,15 +2,15 @@ package spectest import ( "encoding/hex" + "errors" "path" "testing" - "github.com/prysmaticlabs/prysm/shared/featureconfig" - "github.com/ghodss/yaml" "github.com/prysmaticlabs/prysm/shared/bls" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/bytesutil" + "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -36,13 +36,18 @@ func testAggregateVerifyYaml(t *testing.T) { require.NoError(t, err) test := &AggregateVerifyTest{} require.NoError(t, yaml.Unmarshal(file, test)) - pubkeys := make([]iface.PublicKey, 0, len(test.Input.Pubkeys)) + pubkeys := make([]common.PublicKey, 0, len(test.Input.Pubkeys)) msgs := make([][32]byte, 0, len(test.Input.Messages)) for _, pubKey := range test.Input.Pubkeys { pkBytes, err := hex.DecodeString(pubKey[2:]) require.NoError(t, err) pk, err := bls.PublicKeyFromBytes(pkBytes) - require.NoError(t, err) + if err != nil { + if test.Output == false && errors.Is(err, common.ErrInfinitePubKey) { + return + } + t.Fatalf("cannot unmarshal pubkey: %v", err) + } pubkeys = append(pubkeys, pk) } for _, msg := range test.Input.Messages { diff --git a/shared/bls/spectest/fast_aggregate_verify_test.go b/shared/bls/spectest/fast_aggregate_verify_test.go index 2d41da6ecc..61be1b587d 100644 --- a/shared/bls/spectest/fast_aggregate_verify_test.go +++ b/shared/bls/spectest/fast_aggregate_verify_test.go @@ -2,15 +2,15 @@ package spectest import ( "encoding/hex" + "errors" "path" "testing" - "github.com/prysmaticlabs/prysm/shared/featureconfig" - "github.com/ghodss/yaml" "github.com/prysmaticlabs/prysm/shared/bls" - "github.com/prysmaticlabs/prysm/shared/bls/iface" + "github.com/prysmaticlabs/prysm/shared/bls/common" "github.com/prysmaticlabs/prysm/shared/bytesutil" + "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -37,16 +37,26 @@ func testFastAggregateVerifyYaml(t *testing.T) { test := &FastAggregateVerifyTest{} require.NoError(t, yaml.Unmarshal(file, test)) - pubkeys := make([]iface.PublicKey, len(test.Input.Pubkeys)) + pubkeys := make([]common.PublicKey, len(test.Input.Pubkeys)) for j, raw := range test.Input.Pubkeys { pkBytes, err := hex.DecodeString(raw[2:]) require.NoError(t, err) pk, err := bls.PublicKeyFromBytes(pkBytes) - require.NoError(t, err) + if err != nil { + if test.Output == false && errors.Is(err, common.ErrInfinitePubKey) { + return + } + t.Fatalf("cannot unmarshal pubkey: %v", err) + } pubkeys[j] = pk } - msgBytes, err := hex.DecodeString(test.Input.Message[2:]) + msg := test.Input.Message + // TODO(#7632): Remove when https://github.com/ethereum/eth2.0-spec-tests/issues/22 is resolved. + if msg == "" { + msg = test.Input.Messages + } + msgBytes, err := hex.DecodeString(msg[2:]) require.NoError(t, err) sigBytes, err := hex.DecodeString(test.Input.Signature[2:]) require.NoError(t, err) diff --git a/shared/bls/spectest/fast_aggregate_verify_test.yaml.go b/shared/bls/spectest/fast_aggregate_verify_test.yaml.go index b0e1b42e51..8147468092 100644 --- a/shared/bls/spectest/fast_aggregate_verify_test.yaml.go +++ b/shared/bls/spectest/fast_aggregate_verify_test.yaml.go @@ -5,9 +5,11 @@ package spectest type FastAggregateVerifyTest struct { Input struct { - Pubkeys []string `json:"pubkeys"` - Message string `json:"message"` - Signature string `json:"signature"` + Pubkeys []string `json:"pubkeys"` + Message string `json:"message"` + // TODO(#7632): Remove when https://github.com/ethereum/eth2.0-spec-tests/issues/22 is resolved. + Messages string `json:"messages"` + Signature string `json:"signature"` } `json:"input"` Output bool `json:"output"` } diff --git a/shared/bls/spectest/sign_test.go b/shared/bls/spectest/sign_test.go index eb167dd585..f3884cef3f 100644 --- a/shared/bls/spectest/sign_test.go +++ b/shared/bls/spectest/sign_test.go @@ -5,13 +5,14 @@ package spectest import ( "bytes" "encoding/hex" + "errors" "path" "testing" - "github.com/prysmaticlabs/prysm/shared/featureconfig" - "github.com/ghodss/yaml" "github.com/prysmaticlabs/prysm/shared/bls" + "github.com/prysmaticlabs/prysm/shared/bls/common" + "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -40,8 +41,12 @@ func testSignMessageYaml(t *testing.T) { pkBytes, err := hex.DecodeString(test.Input.Privkey[2:]) require.NoError(t, err) sk, err := bls.SecretKeyFromBytes(pkBytes) - require.NoError(t, err) - + if err != nil { + if test.Output == "" && errors.Is(err, common.ErrZeroKey) { + return + } + t.Fatalf("cannot unmarshal secret key: %v", err) + } msgBytes, err := hex.DecodeString(test.Input.Message[2:]) require.NoError(t, err) sig := sk.Sign(msgBytes) diff --git a/shared/bls/spectest/verify_test.go b/shared/bls/spectest/verify_test.go index 3641bb04d2..f13a649624 100644 --- a/shared/bls/spectest/verify_test.go +++ b/shared/bls/spectest/verify_test.go @@ -2,13 +2,14 @@ package spectest import ( "encoding/hex" + "errors" "path" "testing" - "github.com/prysmaticlabs/prysm/shared/featureconfig" - "github.com/ghodss/yaml" "github.com/prysmaticlabs/prysm/shared/bls" + "github.com/prysmaticlabs/prysm/shared/bls/common" + "github.com/prysmaticlabs/prysm/shared/featureconfig" "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) @@ -38,8 +39,12 @@ func testVerifyMessageYaml(t *testing.T) { pkBytes, err := hex.DecodeString(test.Input.Pubkey[2:]) require.NoError(t, err) pk, err := bls.PublicKeyFromBytes(pkBytes) - require.NoError(t, err) - + if err != nil { + if test.Output == false && errors.Is(err, common.ErrInfinitePubKey) { + return + } + t.Fatalf("cannot unmarshal pubkey: %v", err) + } msgBytes, err := hex.DecodeString(test.Input.Message[2:]) require.NoError(t, err) diff --git a/shared/depositutil/deposit_test.go b/shared/depositutil/deposit_test.go index fd5e1bebef..8c8987e022 100644 --- a/shared/depositutil/deposit_test.go +++ b/shared/depositutil/deposit_test.go @@ -15,8 +15,10 @@ import ( ) func TestDepositInput_GeneratesPb(t *testing.T) { - k1 := bls.RandKey() - k2 := bls.RandKey() + k1, err := bls.RandKey() + require.NoError(t, err) + k2, err := bls.RandKey() + require.NoError(t, err) result, _, err := depositutil.DepositInput(k1, k2, 0) require.NoError(t, err) diff --git a/shared/keystore/key.go b/shared/keystore/key.go index 318cad8cb3..a0f354a738 100644 --- a/shared/keystore/key.go +++ b/shared/keystore/key.go @@ -152,7 +152,10 @@ func NewKeyFromBLS(blsKey bls.SecretKey) (*Key, error) { // NewKey generates a new random key. func NewKey() (*Key, error) { - secretKey := bls.RandKey() + secretKey, err := bls.RandKey() + if err != nil { + return nil, err + } return NewKeyFromBLS(secretKey) } diff --git a/shared/keystore/key_test.go b/shared/keystore/key_test.go index b75fa30730..ea696d384e 100644 --- a/shared/keystore/key_test.go +++ b/shared/keystore/key_test.go @@ -13,7 +13,8 @@ import ( func TestMarshalAndUnmarshal(t *testing.T) { testID := uuid.NewRandom() - blsKey := bls.RandKey() + blsKey, err := bls.RandKey() + require.NoError(t, err) key := &Key{ ID: testID, diff --git a/third_party/herumi/herumi.bzl b/third_party/herumi/herumi.bzl index d6bfdf412f..42ee24130e 100644 --- a/third_party/herumi/herumi.bzl +++ b/third_party/herumi/herumi.bzl @@ -11,31 +11,31 @@ def bls_dependencies(): _maybe( http_archive, name = "herumi_bls_eth_go_binary", - strip_prefix = "bls-eth-go-binary-4d3c66ab099d05706ccefcc3c1d1e0f70ff5b2bf", + strip_prefix = "bls-eth-go-binary-4b463a10c225efa46f6d7525ef44822e4b5b7b05", urls = [ - "https://github.com/herumi/bls-eth-go-binary/archive/4d3c66ab099d05706ccefcc3c1d1e0f70ff5b2bf.tar.gz", + "https://github.com/herumi/bls-eth-go-binary/archive/4b463a10c225efa46f6d7525ef44822e4b5b7b05.tar.gz", ], - sha256 = "584a95d4965aaa95445d8f4816a00be88d3ec2c30052dad331d9f5d4fcad9ffc", + sha256 = "23de2840e53818f650bc656bbd9e9a128806f686bcfec56918605868f05b5ac3", build_file = "@prysm//third_party/herumi:bls_eth_go_binary.BUILD", ) _maybe( http_archive, name = "herumi_mcl", - strip_prefix = "mcl-7b4eb83d5bf0940504bfe891f70335d41f5a6037", + strip_prefix = "mcl-bd5a3686924d4ef38f994bb400f87a684ee65fe8", urls = [ - "https://github.com/herumi/mcl/archive/7b4eb83d5bf0940504bfe891f70335d41f5a6037.tar.gz", + "https://github.com/herumi/mcl/archive/bd5a3686924d4ef38f994bb400f87a684ee65fe8.tar.gz", ], - sha256 = "ded0d4611d7115d949d9396cc45e111e8c4e58c4041975b2a0ab994b4de8fc9b", + sha256 = "db90a9c671f4bb59183e51ae2ae3bfe0d5c99b64877c0fca2e7b047fd88b2a41", build_file = "@prysm//third_party/herumi:mcl.BUILD", ) _maybe( http_archive, name = "herumi_bls", - strip_prefix = "bls-a1c04f30892d6d65b53d1d216baebaa26da695f1", + strip_prefix = "bls-f53dadd5a51900f94b7aecff0063feada2f4bb30", urls = [ - "https://github.com/herumi/bls/archive/a1c04f30892d6d65b53d1d216baebaa26da695f1.tar.gz", + "https://github.com/herumi/bls/archive/f53dadd5a51900f94b7aecff0063feada2f4bb30.tar.gz", ], - sha256 = "9ba743d0fc704ce38b084cbc036a709fb15e440b36f2efeed6a8c70e52bed82d", + sha256 = "201e779894ee22cfa9fbe07ccbf9fe4ba7ba2c6fb868c280bf765908c437c8d3", build_file = "@prysm//third_party/herumi:bls.BUILD", ) diff --git a/third_party/herumi/mcl.BUILD b/third_party/herumi/mcl.BUILD index 28b5971eb6..6e1549055a 100644 --- a/third_party/herumi/mcl.BUILD +++ b/third_party/herumi/mcl.BUILD @@ -44,7 +44,6 @@ cc_library( "src/fp_generator.hpp", "src/proto.hpp", "src/low_func_llvm.hpp", - "src/detect_cpu.hpp", ], ) @@ -66,6 +65,7 @@ cc_library( "include/mcl/lagrange.hpp", "include/mcl/bn.hpp", "include/mcl/operator.hpp", + "include/mcl/window_method.hpp", ], includes = ["include"], ) diff --git a/tools/genesis-state-gen/main_test.go b/tools/genesis-state-gen/main_test.go index 88c1bb80b2..80c6ef83b5 100644 --- a/tools/genesis-state-gen/main_test.go +++ b/tools/genesis-state-gen/main_test.go @@ -31,7 +31,8 @@ func createGenesisDepositData(t *testing.T) ([]*GenesisValidator, []*ethpb.Depos pubKeys := make([]bls.PublicKey, numKeys) privKeys := make([]bls.SecretKey, numKeys) for i := 0; i < numKeys; i++ { - randKey := bls.RandKey() + randKey, err := bls.RandKey() + require.NoError(t, err) privKeys[i] = randKey pubKeys[i] = randKey.PublicKey() } diff --git a/tools/keystores/main_test.go b/tools/keystores/main_test.go index 50d247827a..3178c5563c 100644 --- a/tools/keystores/main_test.go +++ b/tools/keystores/main_test.go @@ -51,7 +51,8 @@ func createRandomKeystore(t testing.TB, password string) (*keymanager.Keystore, encryptor := keystorev4.New() id, err := uuid.NewRandom() require.NoError(t, err) - validatingKey := bls.RandKey() + validatingKey, err := bls.RandKey() + require.NoError(t, err) pubKey := validatingKey.PublicKey().Marshal() cryptoFields, err := encryptor.Encrypt(validatingKey.Marshal(), password) require.NoError(t, err) @@ -118,7 +119,8 @@ func TestEncrypt(t *testing.T) { keystoresDir := setupRandomDir(t) password := "secretPassw0rd$1999" keystoreFilePath := filepath.Join(keystoresDir, "keystore.json") - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) cliCtx := setupCliContext(t, &cliConfig{ outputPath: keystoreFilePath, diff --git a/tools/unencrypted-keys-gen/main.go b/tools/unencrypted-keys-gen/main.go index f88afdd350..cdf237aaf4 100644 --- a/tools/unencrypted-keys-gen/main.go +++ b/tools/unencrypted-keys-gen/main.go @@ -46,7 +46,12 @@ func main() { var ctnr *keygen.UnencryptedKeysContainer if *random { - ctnr = generateRandomKeys(*numKeys) + ctnr, err = generateRandomKeys(*numKeys) + if err != nil { + // log.Fatal will prevent defer from being called + cleanup() + log.Fatal(err) + } } else { ctnr = generateUnencryptedKeys(*startIndex) } @@ -57,20 +62,23 @@ func main() { } } -func generateRandomKeys(num int) *keygen.UnencryptedKeysContainer { +func generateRandomKeys(num int) (*keygen.UnencryptedKeysContainer, error) { ctnr := &keygen.UnencryptedKeysContainer{ Keys: make([]*keygen.UnencryptedKeys, num), } for i := 0; i < num; i++ { - sk := bls.RandKey() + sk, err := bls.RandKey() + if err != nil { + return nil, err + } ctnr.Keys[i] = &keygen.UnencryptedKeys{ ValidatorKey: sk.Marshal(), WithdrawalKey: sk.Marshal(), } } - return ctnr + return ctnr, nil } func generateUnencryptedKeys(startIndex uint64) *keygen.UnencryptedKeysContainer { diff --git a/validator/accounts/accounts_import_test.go b/validator/accounts/accounts_import_test.go index aa2e5c47b7..f37e49bca3 100644 --- a/validator/accounts/accounts_import_test.go +++ b/validator/accounts/accounts_import_test.go @@ -286,7 +286,8 @@ func Test_importPrivateKeyAsAccount(t *testing.T) { privKeyFileName := filepath.Join(privKeyDir, "privatekey.txt") // We create a new private key and save it to a file on disk. - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) privKeyHex := fmt.Sprintf("%x", privKey.Marshal()) require.NoError( t, @@ -336,7 +337,8 @@ func Test_importPrivateKeyAsAccount(t *testing.T) { // Returns the fullPath to the newly created keystore file. func createKeystore(t *testing.T, path string) (*keymanager.Keystore, string) { - validatingKey := bls.RandKey() + validatingKey, err := bls.RandKey() + require.NoError(t, err) encryptor := keystorev4.New() cryptoFields, err := encryptor.Encrypt(validatingKey.Marshal(), password) require.NoError(t, err) @@ -360,7 +362,8 @@ func createKeystore(t *testing.T, path string) (*keymanager.Keystore, string) { // Returns the fullPath to the newly created keystore file. func createRandomNameKeystore(t *testing.T, path string) (*keymanager.Keystore, string) { - validatingKey := bls.RandKey() + validatingKey, err := bls.RandKey() + require.NoError(t, err) encryptor := keystorev4.New() cryptoFields, err := encryptor.Encrypt(validatingKey.Marshal(), password) require.NoError(t, err) diff --git a/validator/accounts/accounts_list_test.go b/validator/accounts/accounts_list_test.go index 4d3e01a073..f5de93ebba 100644 --- a/validator/accounts/accounts_list_test.go +++ b/validator/accounts/accounts_list_test.go @@ -41,7 +41,8 @@ func createRandomKeystore(t testing.TB, password string) *keymanager.Keystore { encryptor := keystorev4.New() id, err := uuid.NewRandom() require.NoError(t, err) - validatingKey := bls.RandKey() + validatingKey, err := bls.RandKey() + require.NoError(t, err) pubKey := validatingKey.PublicKey().Marshal() cryptoFields, err := encryptor.Encrypt(validatingKey.Marshal(), password) require.NoError(t, err) diff --git a/validator/client/propose_test.go b/validator/client/propose_test.go index 98a434ea32..1f82559be8 100644 --- a/validator/client/propose_test.go +++ b/validator/client/propose_test.go @@ -49,7 +49,8 @@ func (m mockSignature) Copy() bls.Signature { } func setup(t *testing.T) (*validator, *mocks, bls.SecretKey, func()) { - validatorKey := bls.RandKey() + validatorKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], validatorKey.PublicKey().Marshal()) valDB := testing2.SetupDB(t, [][48]byte{pubKey}) diff --git a/validator/client/validator_test.go b/validator/client/validator_test.go index e4da7689b6..70ba5ee89f 100644 --- a/validator/client/validator_test.go +++ b/validator/client/validator_test.go @@ -131,7 +131,8 @@ func TestWaitForChainStart_StreamSetupFails(t *testing.T) { defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -146,7 +147,7 @@ func TestWaitForChainStart_StreamSetupFails(t *testing.T) { gomock.Any(), &ptypes.Empty{}, ).Return(clientStream, errors.New("failed stream")) - err := v.WaitForChainStart(context.Background()) + err = v.WaitForChainStart(context.Background()) want := "could not setup beacon chain ChainStart streaming client" assert.ErrorContains(t, want, err) } @@ -271,7 +272,8 @@ func TestWaitActivation_ContextCanceled(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -304,7 +306,8 @@ func TestWaitActivation_StreamSetupFails(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -323,7 +326,7 @@ func TestWaitActivation_StreamSetupFails(t *testing.T) { PublicKeys: [][]byte{pubKey[:]}, }, ).Return(clientStream, errors.New("failed stream")) - err := v.WaitForActivation(context.Background()) + err = v.WaitForActivation(context.Background()) want := "could not setup validator WaitForActivation streaming client" assert.ErrorContains(t, want, err) } @@ -333,7 +336,8 @@ func TestWaitActivation_ReceiveErrorFromStream(t *testing.T) { defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -356,7 +360,7 @@ func TestWaitActivation_ReceiveErrorFromStream(t *testing.T) { nil, errors.New("fails"), ) - err := v.WaitForActivation(context.Background()) + err = v.WaitForActivation(context.Background()) want := "could not receive validator activation from stream" assert.ErrorContains(t, want, err) } @@ -366,7 +370,8 @@ func TestWaitActivation_LogsActivationEpochOK(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -433,7 +438,8 @@ func TestWaitMultipleActivation_LogsActivationEpochOK(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -469,7 +475,8 @@ func TestWaitActivation_NotAllValidatorsActivatedOK(t *testing.T) { defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -590,7 +597,8 @@ func TestUpdateDuties_ReturnsError(t *testing.T) { defer ctrl.Finish() client := mock.NewMockBeaconNodeValidatorClient(ctrl) - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ @@ -627,7 +635,8 @@ func TestUpdateDuties_OK(t *testing.T) { client := mock.NewMockBeaconNodeValidatorClient(ctrl) slot := params.BeaconConfig().SlotsPerEpoch - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := [48]byte{} copy(pubKey[:], privKey.PublicKey().Marshal()) km := &mockKeymanager{ diff --git a/validator/keymanager/derived/backup_test.go b/validator/keymanager/derived/backup_test.go index 40510b0ac0..2ad4487fee 100644 --- a/validator/keymanager/derived/backup_test.go +++ b/validator/keymanager/derived/backup_test.go @@ -17,7 +17,8 @@ func TestDerivedKeymanager_ExtractKeystores(t *testing.T) { validatingKeys := make([]bls.SecretKey, 10) lock.Lock() for i := 0; i < len(validatingKeys); i++ { - secretKey := bls.RandKey() + secretKey, err := bls.RandKey() + require.NoError(t, err) validatingKeys[i] = secretKey secretKeysCache[bytesutil.ToBytes48(secretKey.PublicKey().Marshal())] = secretKey } diff --git a/validator/keymanager/imported/backup_test.go b/validator/keymanager/imported/backup_test.go index 68ee5b3398..4658dbb462 100644 --- a/validator/keymanager/imported/backup_test.go +++ b/validator/keymanager/imported/backup_test.go @@ -17,7 +17,8 @@ func TestImportedKeymanager_ExtractKeystores(t *testing.T) { dr := &Keymanager{} validatingKeys := make([]bls.SecretKey, 10) for i := 0; i < len(validatingKeys); i++ { - secretKey := bls.RandKey() + secretKey, err := bls.RandKey() + require.NoError(t, err) validatingKeys[i] = secretKey secretKeysCache[bytesutil.ToBytes48(secretKey.PublicKey().Marshal())] = secretKey } diff --git a/validator/keymanager/imported/import_test.go b/validator/keymanager/imported/import_test.go index 794c8ed115..6b8ffc68b9 100644 --- a/validator/keymanager/imported/import_test.go +++ b/validator/keymanager/imported/import_test.go @@ -20,7 +20,8 @@ func createRandomKeystore(t testing.TB, password string) *keymanager.Keystore { encryptor := keystorev4.New() id, err := uuid.NewRandom() require.NoError(t, err) - validatingKey := bls.RandKey() + validatingKey, err := bls.RandKey() + require.NoError(t, err) pubKey := validatingKey.PublicKey().Marshal() cryptoFields, err := encryptor.Encrypt(validatingKey.Marshal(), password) require.NoError(t, err) @@ -38,7 +39,8 @@ func TestImportedKeymanager_CreateAccountsKeystore_NoDuplicates(t *testing.T) { pubKeys := make([][]byte, numKeys) privKeys := make([][]byte, numKeys) for i := 0; i < numKeys; i++ { - priv := bls.RandKey() + priv, err := bls.RandKey() + require.NoError(t, err) privKeys[i] = priv.Marshal() pubKeys[i] = priv.PublicKey().Marshal() } @@ -76,7 +78,8 @@ func TestImportedKeymanager_CreateAccountsKeystore_NoDuplicates(t *testing.T) { // Now, we run the function again but with a new priv and pubkey and this // time, we do expect a change. - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) privKeys = append(privKeys, privKey.Marshal()) pubKeys = append(pubKeys, privKey.PublicKey().Marshal()) diff --git a/validator/keymanager/imported/keymanager_test.go b/validator/keymanager/imported/keymanager_test.go index 11ba3824bd..6bd7bc626b 100644 --- a/validator/keymanager/imported/keymanager_test.go +++ b/validator/keymanager/imported/keymanager_test.go @@ -84,7 +84,8 @@ func TestImportedKeymanager_FetchValidatingPublicKeys(t *testing.T) { numAccounts := 10 wantedPubKeys := make([][48]byte, numAccounts) for i := 0; i < numAccounts; i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal()) wantedPubKeys[i] = pubKey dr.accountsStore.PublicKeys = append(dr.accountsStore.PublicKeys, pubKey[:]) @@ -116,7 +117,8 @@ func TestImportedKeymanager_FetchValidatingPrivateKeys(t *testing.T) { numAccounts := 10 wantedPrivateKeys := make([][32]byte, numAccounts) for i := 0; i < numAccounts; i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) privKeyData := privKey.Marshal() pubKey := bytesutil.ToBytes48(privKey.PublicKey().Marshal()) wantedPrivateKeys[i] = bytesutil.ToBytes32(privKeyData) diff --git a/validator/keymanager/imported/refresh_test.go b/validator/keymanager/imported/refresh_test.go index 958bb8ea32..91226170a2 100644 --- a/validator/keymanager/imported/refresh_test.go +++ b/validator/keymanager/imported/refresh_test.go @@ -28,7 +28,8 @@ func TestImportedKeymanager_reloadAccountsFromKeystore(t *testing.T) { privKeys := make([][]byte, numAccounts) pubKeys := make([][]byte, numAccounts) for i := 0; i < numAccounts; i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) privKeys[i] = privKey.Marshal() pubKeys[i] = privKey.PublicKey().Marshal() } diff --git a/validator/keymanager/remote/keymanager_test.go b/validator/keymanager/remote/keymanager_test.go index 8381ca71c7..467e7d751c 100644 --- a/validator/keymanager/remote/keymanager_test.go +++ b/validator/keymanager/remote/keymanager_test.go @@ -225,7 +225,8 @@ func TestRemoteKeymanager_Sign(t *testing.T) { } // Expected signing success. - randKey := bls.RandKey() + randKey, err := bls.RandKey() + require.NoError(t, err) data := []byte("hello-world") sig := randKey.Sign(data) m.EXPECT().Sign( diff --git a/validator/rpc/accounts_test.go b/validator/rpc/accounts_test.go index f06a811a27..b388f57633 100644 --- a/validator/rpc/accounts_test.go +++ b/validator/rpc/accounts_test.go @@ -134,7 +134,9 @@ func TestServer_ListAccounts(t *testing.T) { func Test_createAccountWithDepositData(t *testing.T) { ctx := context.Background() - pubKey := bls.RandKey().PublicKey().Marshal() + secretKey, err := bls.RandKey() + require.NoError(t, err) + pubKey := secretKey.PublicKey().Marshal() m := &mockAccountCreator{ data: ðpb.Deposit_Data{ PublicKey: pubKey, diff --git a/validator/rpc/wallet_test.go b/validator/rpc/wallet_test.go index 68ad9f4970..b7a35e0e6f 100644 --- a/validator/rpc/wallet_test.go +++ b/validator/rpc/wallet_test.go @@ -51,7 +51,8 @@ func createImportedWalletWithAccounts(t testing.TB, numAccounts int) (*Server, [ keystores := make([]string, numAccounts) pubKeys := make([][]byte, len(keystores)) for i := 0; i < len(keystores); i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := fmt.Sprintf("%x", privKey.PublicKey().Marshal()) id, err := uuid.NewRandom() require.NoError(t, err) @@ -116,7 +117,8 @@ func TestServer_CreateWallet_Imported(t *testing.T) { encryptor := keystorev4.New() keystores := make([]string, 3) for i := 0; i < len(keystores); i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := fmt.Sprintf("%x", privKey.PublicKey().Marshal()) id, err := uuid.NewRandom() require.NoError(t, err) @@ -352,7 +354,8 @@ func TestServer_ImportKeystores_OK(t *testing.T) { keystores := make([]string, 3) pubKeys := make([][]byte, 3) for i := 0; i < len(keystores); i++ { - privKey := bls.RandKey() + privKey, err := bls.RandKey() + require.NoError(t, err) pubKey := fmt.Sprintf("%x", privKey.PublicKey().Marshal()) id, err := uuid.NewRandom() require.NoError(t, err)