From e4407c64e3d88a32ee04a0e03bf4cf950444dcab Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sun, 11 Sep 2022 02:19:01 +0800 Subject: [PATCH 1/2] Add `test_process_deposit::test_key_validate_invalid` --- .../core/pyspec/eth2spec/test/helpers/deposits.py | 15 +++++++++++---- .../block_processing/test_process_deposit.py | 14 ++++++++++++++ tests/core/pyspec/eth2spec/utils/bls.py | 5 +++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/helpers/deposits.py b/tests/core/pyspec/eth2spec/test/helpers/deposits.py index dae05c2ebe..18929b1d79 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/deposits.py +++ b/tests/core/pyspec/eth2spec/test/helpers/deposits.py @@ -137,14 +137,21 @@ def prepare_random_genesis_deposits(spec, return deposits, root, deposit_data_list -def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_credentials=None, signed=False): +def prepare_state_and_deposit(spec, state, validator_index, amount, + pubkey=None, + privkey=None, + withdrawal_credentials=None, + signed=False): """ Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. """ deposit_data_list = [] - pubkey = pubkeys[validator_index] - privkey = privkeys[validator_index] + if pubkey is None: + pubkey = pubkeys[validator_index] + + if privkey is None: + privkey = privkeys[validator_index] # insecurely use pubkey as withdrawal key if no credentials provided if withdrawal_credentials is None: @@ -196,7 +203,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef yield 'post', state - if not effective: + if not effective or not bls.KeyValidate(deposit.data.pubkey): assert len(state.validators) == pre_validator_count assert len(state.balances) == pre_validator_count if validator_index < pre_validator_count: diff --git a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py index df0bd2a17c..f1a27f8ec9 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py @@ -233,3 +233,17 @@ def test_bad_merkle_proof(spec, state): sign_deposit_data(spec, deposit.data, privkeys[validator_index]) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=False) + + +@with_all_phases +@spec_state_test +def test_key_validate_invalid(spec, state): + validator_index = len(state.validators) + amount = spec.MAX_EFFECTIVE_BALANCE + + # All-zero pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception. + pubkey = b'\x00' * 48 + + deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True) + + yield from run_deposit_processing(spec, state, deposit, validator_index) diff --git a/tests/core/pyspec/eth2spec/utils/bls.py b/tests/core/pyspec/eth2spec/utils/bls.py index e33017ade5..fd5fd89bfb 100644 --- a/tests/core/pyspec/eth2spec/utils/bls.py +++ b/tests/core/pyspec/eth2spec/utils/bls.py @@ -138,3 +138,8 @@ def pairing_check(values): * pairing(p_q_2[1], p_q_2[0], final_exponentiate=False) ) return final_exponentiation == FQ12.one() + + +@only_with_bls(alt_return=True) +def KeyValidate(pubkey): + return py_ecc_bls.KeyValidate(pubkey) From 4d2cfff2d64469c8a6083845c95c6128d7e67d7e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 12 Sep 2022 22:59:29 +0800 Subject: [PATCH 2/2] Add `test_key_validate_invalid_decompression` --- .../block_processing/test_process_deposit.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py index f1a27f8ec9..8922032b41 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py @@ -237,7 +237,7 @@ def test_bad_merkle_proof(spec, state): @with_all_phases @spec_state_test -def test_key_validate_invalid(spec, state): +def test_key_validate_invalid_subgroup(spec, state): validator_index = len(state.validators) amount = spec.MAX_EFFECTIVE_BALANCE @@ -247,3 +247,19 @@ def test_key_validate_invalid(spec, state): deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True) yield from run_deposit_processing(spec, state, deposit, validator_index) + + +@with_all_phases +@spec_state_test +def test_key_validate_invalid_decompression(spec, state): + validator_index = len(state.validators) + amount = spec.MAX_EFFECTIVE_BALANCE + + # `deserialization_fails_infinity_with_true_b_flag` BLS G1 deserialization test case. + # This pubkey would not pass `bls.KeyValidate`, but `process_deposit` would not throw exception. + pubkey_hex = 'c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + pubkey = bytes.fromhex(pubkey_hex) + + deposit = prepare_state_and_deposit(spec, state, validator_index, amount, pubkey=pubkey, signed=True) + + yield from run_deposit_processing(spec, state, deposit, validator_index)