From aa436d91b2b3cc2434bccead18c991138139a81d Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 14 May 2020 22:04:13 +0800 Subject: [PATCH 1/2] Use NO_SIGNATURE (0x00...) approach --- configs/mainnet.yaml | 2 ++ configs/minimal.yaml | 2 ++ specs/phase1/beacon-chain.md | 34 +++++++++++++++++++++++++------- specs/phase1/shard-transition.md | 4 ++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/configs/mainnet.yaml b/configs/mainnet.yaml index 60bd1c087..0fb81a1c3 100644 --- a/configs/mainnet.yaml +++ b/configs/mainnet.yaml @@ -156,6 +156,8 @@ DOMAIN_SHARD_PROPOSAL: 0x80000000 DOMAIN_SHARD_COMMITTEE: 0x81000000 DOMAIN_LIGHT_CLIENT: 0x82000000 DOMAIN_CUSTODY_BIT_SLASHING: 0x83000000 +# Constant +NO_SIGNATURE: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 # Phase 1: Upgrade from Phase 0 diff --git a/configs/minimal.yaml b/configs/minimal.yaml index 5c1511e6d..6650eadc1 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -156,6 +156,8 @@ DOMAIN_SHARD_PROPOSAL: 0x80000000 DOMAIN_SHARD_COMMITTEE: 0x81000000 DOMAIN_LIGHT_CLIENT: 0x82000000 DOMAIN_CUSTODY_BIT_SLASHING: 0x83000000 +# Constant +NO_SIGNATURE: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 # Phase 1: Upgrade from Phase 0 diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 83d63ee2a..a52e2eb68 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -55,6 +55,8 @@ - [Updated `is_valid_indexed_attestation`](#updated-is_valid_indexed_attestation) - [`is_shard_attestation`](#is_shard_attestation) - [`is_winning_attestation`](#is_winning_attestation) + - [`optional_aggregate_verify`](#optional_aggregate_verify) + - [`optional_fast_aggregate_verify`](#optional_fast_aggregate_verify) - [Block processing](#block-processing) - [Operations](#operations) - [New Attestation processing](#new-attestation-processing) @@ -110,6 +112,7 @@ Configuration is not namespaced. Instead it is strictly an extension; | `DOMAIN_SHARD_PROPOSAL` | `DomainType('0x80000000')` | | | `DOMAIN_SHARD_COMMITTEE` | `DomainType('0x81000000')` | | | `DOMAIN_LIGHT_CLIENT` | `DomainType('0x82000000')` | | +| `NO_SIGNATURE` | `BLSSignature(b'\x00' * 96)` | | ## Updated containers @@ -633,6 +636,28 @@ def is_winning_attestation(state: BeaconState, ) ``` +#### `optional_aggregate_verify` + +```python +def optional_aggregate_verify(pubkeys: Sequence[BLSPubkey], + messages: Sequence[Bytes32], + signature: BLSSignature) -> bool: + if len(pubkeys) == 0: + return signature == NO_SIGNATURE + else: + return bls.AggregateVerify(pubkeys, messages, signature) +``` + +#### `optional_fast_aggregate_verify` + +```python +def optional_fast_aggregate_verify(pubkeys: Sequence[BLSPubkey], message: Bytes32, signature: BLSSignature) -> bool: + if len(pubkeys) == 0: + return signature == NO_SIGNATURE + else: + return bls.FastAggregateVerify(pubkeys, message, signature) +``` + ### Block processing ```python @@ -764,7 +789,7 @@ def apply_shard_transition(state: BeaconState, shard: Shard, transition: ShardTr for header in headers ] # Verify combined proposer signature - assert bls.AggregateVerify(pubkeys, signing_roots, signature=transition.proposer_signature_aggregate) + assert optional_aggregate_verify(pubkeys, signing_roots, transition.proposer_signature_aggregate) # Save updated state state.shard_states[shard] = transition.shard_states[len(transition.shard_states) - 1] @@ -942,12 +967,7 @@ def process_light_client_signatures(state: BeaconState, block_body: BeaconBlockB slot = compute_previous_slot(state.slot) signing_root = compute_signing_root(get_block_root_at_slot(state, slot), get_domain(state, DOMAIN_LIGHT_CLIENT, compute_epoch_at_slot(slot))) - if len(signer_pubkeys) == 0: - # TODO: handle the empty light_client_signature case? - assert block_body.light_client_signature == BLSSignature() - return - else: - assert bls.FastAggregateVerify(signer_pubkeys, signing_root, signature=block_body.light_client_signature) + assert optional_fast_aggregate_verify(signer_pubkeys, signing_root, block_body.light_client_signature) ``` ### Epoch transition diff --git a/specs/phase1/shard-transition.md b/specs/phase1/shard-transition.md index 5b6a72f28..36b3b80ab 100644 --- a/specs/phase1/shard-transition.md +++ b/specs/phase1/shard-transition.md @@ -277,13 +277,13 @@ def get_shard_transition(beacon_state: BeaconState, proposer_signatures = [] for proposal in proposals: shard_block_lengths.append(len(proposal.message.body)) - if proposal.signature != BLSSignature(): + if proposal.signature != NO_SIGNATURE: proposer_signatures.append(proposal.signature) if len(proposer_signatures) > 0: proposer_signature_aggregate = bls.Aggregate(proposer_signatures) else: - proposer_signature_aggregate = BLSSignature() + proposer_signature_aggregate = NO_SIGNATURE return ShardTransition( start_slot=start_slot, From f0c4623871d0f66a9f9878c3444379c5ec80f6a3 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Fri, 15 May 2020 01:05:32 +0800 Subject: [PATCH 2/2] Apply PR feedback: add docstring --- specs/phase1/beacon-chain.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index a52e2eb68..9a07e0a77 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -642,6 +642,10 @@ def is_winning_attestation(state: BeaconState, def optional_aggregate_verify(pubkeys: Sequence[BLSPubkey], messages: Sequence[Bytes32], signature: BLSSignature) -> bool: + """ + If ``pubkeys`` is an empty list, the given ``signature`` should be a stub ``NO_SIGNATURE``. + Otherwise, verify it with standard BLS AggregateVerify API. + """ if len(pubkeys) == 0: return signature == NO_SIGNATURE else: @@ -652,6 +656,10 @@ def optional_aggregate_verify(pubkeys: Sequence[BLSPubkey], ```python def optional_fast_aggregate_verify(pubkeys: Sequence[BLSPubkey], message: Bytes32, signature: BLSSignature) -> bool: + """ + If ``pubkeys`` is an empty list, the given ``signature`` should be a stub ``NO_SIGNATURE``. + Otherwise, verify it with standard BLS FastAggregateVerify API. + """ if len(pubkeys) == 0: return signature == NO_SIGNATURE else: