From 7c833fafc5d04278a63ed3e36d4bc5b77e4a33e8 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 13 Dec 2018 12:09:39 -0600 Subject: [PATCH 01/16] clean up casper slashing with helper functions etc --- specs/core/0_beacon-chain.md | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 040d0490c..15cd4f6e5 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -77,6 +77,8 @@ - [`get_domain`](#get_domain) - [`hash_tree_root`](#hash_tree_root) - [`verify_slashable_vote_data`](#verify_slashable_vote_data) + - [`is_double_vote`](#is_double_vote) + - [`is_surround_vote`](#is_surround_vote) - [`integer_squareroot`](#integer_squareroot) - [`bls_verify`](#bls_verify) - [`bls_verify_multiple`](#bls_verify_multiple) @@ -1036,6 +1038,26 @@ def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData) ) ``` +#### `is_double_vote` + +```python +def is_double_vote(attestation_data_1: AttestationData, + attestation_data_2: AttestationData) -> bool + return attestation_data_1.slot == attestation_data_2.slot +``` + +#### `is_surround_vote` + +```python +def is_surround_vote(attestation_data_1: AttestationData, + attestation_data_2: AttestationData) -> bool + return ( + (attestation_data_1.justified_slot < attestation_data_2.justified_slot) and + (attestat_data_2.justified_slot + 1 == attestation_data_2.slot) and + (attestation_data_2.slot < attestation_data_1.slot) + ) +``` + #### `integer_squareroot` ```python @@ -1389,13 +1411,15 @@ Verify that `len(block.body.casper_slashings) <= MAX_CASPER_SLASHINGS`. For each `casper_slashing` in `block.body.casper_slashings`: -* Verify that `casper_slashing.slashable_vote_data_1.data != casper_slashing.slashable_vote_data_2.data`. -* Let `indices(vote) = vote.aggregate_signature_poc_0_indices + vote.aggregate_signature_poc_1_indices`. -* Let `intersection = [x for x in indices(casper_slashing.slashable_vote_data_1) if x in indices(casper_slashing.slashable_vote_data_2)]`. +* Let `slashable_vote_data_1 = casper_slashing.slashable_vote_data_1`. +* Let `slashable_vote_data_2 = casper_slashing.slashable_vote_data_2`. +* Let `indices(slashable_vote_data) = slashable_vote_data.aggregate_signature_poc_0_indices + slashable_vote_data.aggregate_signature_poc_1_indices`. +* Let `intersection = [x for x in indices(slashable_vote_data_1) if x in indices(slashable_vote_data_2)]`. * Verify that `len(intersection) >= 1`. -* Verify that `casper_slashing.slashable_vote_data_1.data.justified_slot + 1 < casper_slashing.slashable_vote_data_2.data.justified_slot + 1 == casper_slashing.slashable_vote_data_2.data.slot < casper_slashing.slashable_vote_data_1.data.slot` or `casper_slashing.slashable_vote_data_1.data.slot == casper_slashing.slashable_vote_data_2.data.slot`. -* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_1)`. -* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_2)`. +* Verify that `slashable_vote_data_1.data != slashable_vote_data_2.data`. +* Verify that `is_double_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)` or `is_surround_vote(slashable_vote_data_1.data, slashable_vote_data_2.data)`. +* Verify that `verify_slashable_vote_data(state, slashable_vote_data_1)`. +* Verify that `verify_slashable_vote_data(state, slashable_vote_data_2)`. * For each [validator](#dfn-validator) index `i` in `intersection`, if `state.validator_registry[i].status` does not equal `EXITED_WITH_PENALTY`, then run `update_validator_status(state, i, new_status=EXITED_WITH_PENALTY)` #### Attestations From 697d3c5eb58df26239bea03154db298e171b2ece Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 13 Dec 2018 12:17:39 -0600 Subject: [PATCH 02/16] add doc string for new slashing helper funtions --- specs/core/0_beacon-chain.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 15cd4f6e5..30fb27c19 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1043,6 +1043,11 @@ def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData) ```python def is_double_vote(attestation_data_1: AttestationData, attestation_data_2: AttestationData) -> bool + """ + Assumes ``attestation_data_1`` is distinct from ``attestation_data_2``. + Returns True if the provided ``AttestationData`` are slashable + due to a 'double vote'. + """ return attestation_data_1.slot == attestation_data_2.slot ``` @@ -1051,6 +1056,13 @@ def is_double_vote(attestation_data_1: AttestationData, ```python def is_surround_vote(attestation_data_1: AttestationData, attestation_data_2: AttestationData) -> bool + """ + Assumes ``attestation_data_1`` is distinct from ``attestation_data_2``. + Returns True if the provided ``AttestationData`` is slashable + due to a 'surround vote'. + Note: parameter order matters as this function only checks + that ``attestation_data_1`` surrounds ``attestation_data_2``. + """ return ( (attestation_data_1.justified_slot < attestation_data_2.justified_slot) and (attestat_data_2.justified_slot + 1 == attestation_data_2.slot) and From cd9e7ecaeb2f0ccaa3e5cbe4bcd5aa178278b4c7 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 13 Dec 2018 12:18:29 -0600 Subject: [PATCH 03/16] minor fix --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 30fb27c19..6f3a02976 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1058,7 +1058,7 @@ def is_surround_vote(attestation_data_1: AttestationData, attestation_data_2: AttestationData) -> bool """ Assumes ``attestation_data_1`` is distinct from ``attestation_data_2``. - Returns True if the provided ``AttestationData`` is slashable + Returns True if the provided ``AttestationData`` are slashable due to a 'surround vote'. Note: parameter order matters as this function only checks that ``attestation_data_1`` surrounds ``attestation_data_2``. From f30d40485610c13c0589ae9202fff9bc401b9a78 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 13 Dec 2018 13:50:50 -0600 Subject: [PATCH 04/16] add ValidatorRegistryDeltaBlock ssz object --- specs/core/0_beacon-chain.md | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 040d0490c..9c77a40fb 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -49,6 +49,7 @@ - [`CandidatePoWReceiptRootRecord`](#candidatepowreceiptrootrecord) - [`PendingAttestationRecord`](#pendingattestationrecord) - [`ForkData`](#forkdata) + - [`ValidatorRegistryDeltaBlock`](#validatorregistrydeltablock) - [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract) - [Deposit arguments](#deposit-arguments) - [`Eth1Deposit` logs](#eth1deposit-logs) @@ -578,6 +579,17 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted } ``` +#### `ValidatorRegistryDeltaBlock` + +```python +{ + latest_registry_delta_root: 'hash32', + validator_index: 'uint24', + pubkey: 'uint384', + flag: 'uint64', +} +``` + ## Ethereum 1.0 deposit contract The initial deployment phases of Ethereum 2.0 are implemented without consensus changes to Ethereum 1.0. A deposit contract at address `DEPOSIT_CONTRACT_ADDRESS` is added to Ethereum 1.0 for deposits of ETH to the beacon chain. Validator balances will be withdrawable to the shards when the EVM2.0 is deployed and the shards have state. @@ -967,17 +979,19 @@ def get_effective_balance(validator: ValidatorRecord) -> int: ```python def get_new_validator_registry_delta_chain_tip(current_validator_registry_delta_chain_tip: Hash32, - index: int, + validator_index: int, pubkey: int, flag: int) -> Hash32: """ - Compute the next hash in the validator registry delta hash chain. + Compute the next root in the validator registry delta hash chain. """ - return hash( - current_validator_registry_delta_chain_tip + - bytes1(flag) + - bytes3(index) + - bytes48(pubkey) + return tree_hash_root( + ValidatorRegistryDeltaBlock( + current_validator_registry_delta_chain_tip, + validator_index=validator_index, + pubkey=pubkey, + flag=flag, + ) ) ``` @@ -1081,7 +1095,7 @@ A valid block with slot `INITIAL_SLOT_NUMBER` (a "genesis block") has the follow } ``` -`STARTUP_STATE_ROOT` (in the above "genesis block") is generated from the `get_initial_beacon_state` function below. When enough full deposits have been made to the deposit contract and the `ChainStart` log has been emitted, `get_initial_beacon_state` will execute to compute the `ssz_tree_hash` of `BeaconState`. +`STARTUP_STATE_ROOT` (in the above "genesis block") is generated from the `get_initial_beacon_state` function below. When enough full deposits have been made to the deposit contract and the `ChainStart` log has been emitted, `get_initial_beacon_state` will execute to compute the `tree_hash_root` of `BeaconState`. ```python def get_initial_beacon_state(initial_validator_deposits: List[Deposit], From 96aade9a2c4d30e579c301baeb216a9f6c6df8ec Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 13 Dec 2018 14:03:22 -0600 Subject: [PATCH 05/16] add proofofpossessiondata ssz object --- specs/core/0_beacon-chain.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 9c77a40fb..0e8f57210 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -34,6 +34,7 @@ - [`Deposit`](#deposit) - [`DepositData`](#depositdata) - [`DepositInput`](#depositinput) + - [`ProofOfPossessionData`](#proofofpossessiondata) - [Exits](#exits) - [`Exit`](#exit) - [Beacon chain blocks](#beacon-chain-blocks) @@ -378,6 +379,16 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted } ``` +#### `ProofOfPossessionData` + +```python +{ + 'pubkey': 'uint384', + 'withdrawal_credentials': 'hash32', + 'randao_commitment': 'hash32', +} +``` + #### Exits ##### `Exit` @@ -985,7 +996,7 @@ def get_new_validator_registry_delta_chain_tip(current_validator_registry_delta_ """ Compute the next root in the validator registry delta hash chain. """ - return tree_hash_root( + return hash_tree_root( ValidatorRegistryDeltaBlock( current_validator_registry_delta_chain_tip, validator_index=validator_index, @@ -1095,7 +1106,7 @@ A valid block with slot `INITIAL_SLOT_NUMBER` (a "genesis block") has the follow } ``` -`STARTUP_STATE_ROOT` (in the above "genesis block") is generated from the `get_initial_beacon_state` function below. When enough full deposits have been made to the deposit contract and the `ChainStart` log has been emitted, `get_initial_beacon_state` will execute to compute the `tree_hash_root` of `BeaconState`. +`STARTUP_STATE_ROOT` (in the above "genesis block") is generated from the `get_initial_beacon_state` function below. When enough full deposits have been made to the deposit contract and the `ChainStart` log has been emitted, `get_initial_beacon_state` will execute to compute the `hash_tree_root` of `BeaconState`. ```python def get_initial_beacon_state(initial_validator_deposits: List[Deposit], @@ -1192,9 +1203,15 @@ def process_deposit(state: BeaconState, Process a deposit from Ethereum 1.0. Note that this function mutates ``state``. """ + proof_of_possession_data = ProofOfPossessionData( + pubkey=pubkey, + withdrawal_credentials=withdrawal_credentials, + randao_commitment=randao_commitment, + ) + assert bls_verify( pubkey=pubkey, - message=hash(bytes32(pubkey) + withdrawal_credentials + randao_commitment), + message=hash_tree_root(proof_of_possession_data), signature=proof_of_possession, domain=get_domain( state.fork_data, @@ -1348,7 +1365,7 @@ Below are the processing steps that happen at every slot. ### Block roots -* Let `previous_block_root` be the `tree_hash_root` of the previous beacon block processed in the chain. +* Let `previous_block_root` be the `hash_tree_root` of the previous beacon block processed in the chain. * Set `state.latest_block_roots = state.latest_block_roots[1:] + [previous_block_root]`. * If `state.slot % LATEST_BLOCK_ROOTS_LENGTH == 0` append `merkle_root(state.latest_block_roots)` to `state.batched_block_roots`. From add628d26bcb0b55d7f1a4b4c3031f4241922c66 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 13 Dec 2018 19:06:07 -0500 Subject: [PATCH 06/16] Edit BLS spec as per issue #300 See https://github.com/ethereum/eth2.0-specs/issues/300 --- specs/{bls_verify.md => bls_signature.md} | 10 ++++++++++ 1 file changed, 10 insertions(+) rename specs/{bls_verify.md => bls_signature.md} (91%) diff --git a/specs/bls_verify.md b/specs/bls_signature.md similarity index 91% rename from specs/bls_verify.md rename to specs/bls_signature.md index a6c41e555..47f7b69c0 100644 --- a/specs/bls_verify.md +++ b/specs/bls_signature.md @@ -117,6 +117,16 @@ Let `bls_verify(pubkey: uint384, message: bytes32, signature: [uint384], domain: * Verify that `signature` is a valid G2 point. * Verify that `e(pubkey, hash_to_G2(message, domain)) == e(g, signature)`. +## Operations involving aggregate signatures + +### `bls_aggregate_pubkeys` + +Let `bls_aggregate_pubkeys(pubkeys: [uint384]) -> uint384` return `pubkeys[0] + .... + pubkeys[len(pubkeys)-1]`, where `+` is the elliptic curve addition operation over the G1 curve. + +### `bls_aggregate_signatures` + +Let `bls_aggregate_signatures(signatures: [[uint384]]) -> [uint384]` return `signatures[0] + .... + signatures[len(signatures)-1]`, where `+` is the elliptic curve addition operation over the G2 curve. + ### `bls_verify_multiple` Let `bls_verify_multiple(pubkeys: [uint384], messages: [bytes32], signature: [uint384], domain: uint64) -> bool`: From c43724132b06086ae51a11001794dce802c74644 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 13 Dec 2018 23:01:32 -0500 Subject: [PATCH 07/16] Clarify block hash -> block root --- specs/core/0_beacon-chain.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 42929bbd6..485069d25 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -140,6 +140,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted * **Attester** - a [validator](#dfn-validator) that is part of a committee that needs to sign off on a beacon chain block while simultaneously creating a link (crosslink) to a recent shard block on a particular shard chain. * **Beacon chain** - the central PoS chain that is the base of the sharding system. * **Shard chain** - one of the chains on which user transactions take place and account data is stored. +* **Block root** - a 32-byte Merkle root of a beacon chain block or shard chain block. Previously called "block hash". * **Crosslink** - a set of signatures from a committee attesting to a block in a shard chain, which can be included into the beacon chain. Crosslinks are the main means by which the beacon chain "learns about" the updated state of shard chains. * **Slot** - a period of `SLOT_DURATION` seconds, during which one proposer has the ability to create a beacon chain block and some attesters have the ability to make attestations * **Epoch** - an aligned span of slots during which all [validators](#dfn-validator) get exactly one chance to make an attestation @@ -508,7 +509,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted { # Slot number 'slot': 'uint64', - # Shard block hash + # Shard block root 'shard_block_root': 'hash32', } ``` @@ -894,7 +895,7 @@ def get_shard_committees_at_slot(state: BeaconState, def get_block_root(state: BeaconState, slot: int) -> Hash32: """ - Returns the block hash at a recent ``slot``. + Returns the block root at a recent ``slot``. """ earliest_slot_in_array = state.slot - len(state.latest_block_roots) assert earliest_slot_in_array <= slot < state.slot From 221874efcb47bebb4708e35785914220af82fa6f Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 14 Dec 2018 09:29:49 -0600 Subject: [PATCH 08/16] pr feedback --- specs/core/0_beacon-chain.md | 40 +++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 0e8f57210..b75f8a014 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -61,6 +61,7 @@ - [Beacon chain state transition function](#beacon-chain-state-transition-function) - [Helper functions](#helper-functions) - [`hash`](#hash) + - [`hash_tree_root`](#hash_tree_root) - [`is_active_validator`](#is_active_validator) - [`get_active_validator_indices`](#get_active_validator_indices) - [`shuffle`](#shuffle) @@ -77,7 +78,6 @@ - [`get_new_validator_registry_delta_chain_tip`](#get_new_validator_registry_delta_chain_tip) - [`get_fork_version`](#get_fork_version) - [`get_domain`](#get_domain) - - [`hash_tree_root`](#hash_tree_root) - [`verify_slashable_vote_data`](#verify_slashable_vote_data) - [`integer_squareroot`](#integer_squareroot) - [`bls_verify`](#bls_verify) @@ -164,6 +164,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted | `BLS_WITHDRAWAL_PREFIX_BYTE` | `0x00` | - | | `MAX_CASPER_VOTES` | `2**10` (= 1,024) | votes | | `LATEST_BLOCK_ROOTS_LENGTH` | `2**13` (= 8,192) | block roots | +| `EMPTY_SIGNATURE` | `[bytes48(0), bytes48(0)]` | - | * For the safety of crosslinks a minimum committee size of 111 is [recommended](https://vitalik.ca/files/Ithaca201807_Sharding.pdf). (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) The shuffling algorithm generally ensures (assuming sufficient validators) committee sizes at least `TARGET_COMMITTEE_SIZE // 2`. @@ -370,22 +371,12 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted { # BLS pubkey 'pubkey': 'uint384', - # BLS proof of possession (a BLS signature) - 'proof_of_possession': ['uint384'], # Withdrawal credentials 'withdrawal_credentials': 'hash32', # Initial RANDAO commitment 'randao_commitment': 'hash32', -} -``` - -#### `ProofOfPossessionData` - -```python -{ - 'pubkey': 'uint384', - 'withdrawal_credentials': 'hash32', - 'randao_commitment': 'hash32', + # a BLS signature of this ``DepositInput`` + 'proof_of_possession': ['uint384'], } ``` @@ -750,6 +741,10 @@ The hash function is denoted by `hash`. In Phase 0 the beacon chain is deployed Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethereum 2.0 deployment phase. +#### `hash_tree_root` + +`hash_tree_root` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash). + #### `is_active_validator` ```python def is_active_validator(validator: ValidatorRecord) -> bool: @@ -994,11 +989,11 @@ def get_new_validator_registry_delta_chain_tip(current_validator_registry_delta_ pubkey: int, flag: int) -> Hash32: """ - Compute the next root in the validator registry delta hash chain. + Compute the next root in the validator registry delta chain. """ return hash_tree_root( ValidatorRegistryDeltaBlock( - current_validator_registry_delta_chain_tip, + validator_registry_delta_chain_tip=current_validator_registry_delta_chain_tip, validator_index=validator_index, pubkey=pubkey, flag=flag, @@ -1029,10 +1024,6 @@ def get_domain(fork_data: ForkData, ) * 2**32 + domain_type ``` -#### `hash_tree_root` - -`hash_tree_root` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash). - #### `verify_slashable_vote_data` ```python @@ -1095,7 +1086,7 @@ A valid block with slot `INITIAL_SLOT_NUMBER` (a "genesis block") has the follow state_root=STARTUP_STATE_ROOT, randao_reveal=ZERO_HASH, candidate_pow_receipt_root=ZERO_HASH, - proposer_signature=[0, 0], + proposer_signature=EMPTY_SIGNATURE, 'body': BeaconBlockBody( proposer_slashings=[], casper_slashings=[], @@ -1203,10 +1194,11 @@ def process_deposit(state: BeaconState, Process a deposit from Ethereum 1.0. Note that this function mutates ``state``. """ - proof_of_possession_data = ProofOfPossessionData( + proof_of_possession_data = DepositInput( pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, randao_commitment=randao_commitment, + proof_of_possession=EMPTY_SIGNATURE, ) assert bls_verify( @@ -1287,7 +1279,7 @@ def activate_validator(state: BeaconState, validator.latest_status_change_slot = state.slot state.validator_registry_delta_chain_tip = get_new_validator_registry_delta_chain_tip( validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip, - index=index, + validator_index=index, pubkey=validator.pubkey, flag=ACTIVATION, ) @@ -1341,7 +1333,7 @@ def exit_validator(state: BeaconState, validator.exit_count = state.validator_registry_exit_count state.validator_registry_delta_chain_tip = get_new_validator_registry_delta_chain_tip( validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip, - index=index, + validator_index=index, pubkey=validator.pubkey, flag=EXIT ) @@ -1379,7 +1371,7 @@ Below are the processing steps that happen at every `block`. ### Proposer signature -* Let `block_without_signature_root` be the `hash_tree_root` of `block` where `block.signature` is set to `[0, 0]`. +* Let `block_without_signature_root` be the `hash_tree_root` of `block` where `block.signature` is set to `EMPTY_SIGNATURE`. * Let `proposal_root = hash_tree_root(ProposalSignedData(state.slot, BEACON_CHAIN_SHARD_NUMBER, block_without_signature_root))`. * Verify that `bls_verify(pubkey=state.validator_registry[get_beacon_proposer_index(state, state.slot)].pubkey, data=proposal_root, signature=block.signature, domain=get_domain(state.fork_data, state.slot, DOMAIN_PROPOSAL))`. From 7b4c4f299da3ce19ec84f2344ada723ea4a5d4a9 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 14 Dec 2018 09:39:14 -0600 Subject: [PATCH 09/16] add bls_aggregate_pubkeys ref in beacon chain spec --- specs/core/0_beacon-chain.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 198c4872a..f6ee34c01 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -84,6 +84,7 @@ - [`integer_squareroot`](#integer_squareroot) - [`bls_verify`](#bls_verify) - [`bls_verify_multiple`](#bls_verify_multiple) + - [`bls_aggregate_pubkeys`](#bls_aggregate_pubkeys) - [On startup](#on-startup) - [Routine for processing deposits](#routine-for-processing-deposits) - [Routine for updating validator status](#routine-for-updating-validator-status) @@ -1104,11 +1105,15 @@ def integer_squareroot(n: int) -> int: #### `bls_verify` -`bls_verify` is a function for verifying a BLS12-381 signature, defined in the [BLS Verification spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_verify.md#bls_verify). +`bls_verify` is a function for verifying a BLS12-381 signature, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_verify). #### `bls_verify_multiple` -`bls_verify_multiple` is a function for verifying a BLS12-381 signature constructed from multiple messages, defined in the [BLS Verification spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_verify.md#bls_verify_multiple). +`bls_verify_multiple` is a function for verifying a BLS12-381 signature constructed from multiple messages, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_verify_multiple). + +#### `bls_aggregate_pubkeys` + +`bls_aggregate_pubkeys` is a function for aggregating a BLS12-381 public keys into a single aggregate key, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_aggregate_pubkeys). ### On startup @@ -1473,7 +1478,7 @@ For each `attestation` in `block.body.attestations`: * Verify that either `attestation.data.latest_crosslink_root` or `attestation.data.shard_block_root` equals `state.latest_crosslinks[shard].shard_block_root`. * `aggregate_signature` verification: * Let `participants = get_attestation_participants(state, attestation.data, attestation.participation_bitfield)`. - * Let `group_public_key = BLSAddPubkeys([state.validator_registry[v].pubkey for v in participants])`. + * Let `group_public_key = bls_aggregate_pubkeys([state.validator_registry[v].pubkey for v in participants])`. * Verify that `bls_verify(pubkey=group_public_key, message=hash_tree_root(attestation.data) + bytes1(0), signature=attestation.aggregate_signature, domain=get_domain(state.fork_data, attestation.data.slot, DOMAIN_ATTESTATION))`. * [TO BE REMOVED IN PHASE 1] Verify that `attestation.data.shard_block_root == ZERO_HASH`. * Append `PendingAttestationRecord(data=attestation.data, participation_bitfield=attestation.participation_bitfield, custody_bitfield=attestation.custody_bitfield, slot_included=state.slot)` to `state.latest_attestations`. From 179352dbfefe7708758d61d3544fceb54e97930f Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 14 Dec 2018 15:20:21 -0600 Subject: [PATCH 10/16] remove ProofOfPossessionData --- specs/core/0_beacon-chain.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 198c4872a..d8d0290b3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -34,7 +34,6 @@ - [`Deposit`](#deposit) - [`DepositData`](#depositdata) - [`DepositInput`](#depositinput) - - [`ProofOfPossessionData`](#proofofpossessiondata) - [Exits](#exits) - [`Exit`](#exit) - [Beacon chain blocks](#beacon-chain-blocks) From 62b95fbe334d915910ed838935d1136e48a8b2da Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 14 Dec 2018 15:21:32 -0600 Subject: [PATCH 11/16] fix process_deposit function signature --- specs/core/0_beacon-chain.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index d8d0290b3..2097f6a0e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1222,8 +1222,7 @@ def process_deposit(state: BeaconState, deposit: int, proof_of_possession: bytes, withdrawal_credentials: Hash32, - randao_commitment: Hash32, - status: int) -> int: + randao_commitment: Hash32) -> int: """ Process a deposit from Ethereum 1.0. Note that this function mutates ``state``. From 829911c0fdd0d2337fda320a6c333ae053eaa3d0 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Fri, 14 Dec 2018 19:55:05 -0500 Subject: [PATCH 12/16] Swapped order of aggregate and verify --- specs/bls_signature.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/specs/bls_signature.md b/specs/bls_signature.md index 47f7b69c0..394d6bbc3 100644 --- a/specs/bls_signature.md +++ b/specs/bls_signature.md @@ -99,6 +99,16 @@ def modular_squareroot(value: int) -> int: return None ``` +## Operations involving asignature aggregation + +### `bls_aggregate_pubkeys` + +Let `bls_aggregate_pubkeys(pubkeys: [uint384]) -> uint384` return `pubkeys[0] + .... + pubkeys[len(pubkeys)-1]`, where `+` is the elliptic curve addition operation over the G1 curve. + +### `bls_aggregate_signatures` + +Let `bls_aggregate_signatures(signatures: [[uint384]]) -> [uint384]` return `signatures[0] + .... + signatures[len(signatures)-1]`, where `+` is the elliptic curve addition operation over the G2 curve. + ## Signature verification In the following `e` is the pairing function and `g` is the G1 generator with the following coordinates (see [here](https://github.com/zkcrypto/pairing/tree/master/src/bls12_381#g1)): @@ -117,16 +127,6 @@ Let `bls_verify(pubkey: uint384, message: bytes32, signature: [uint384], domain: * Verify that `signature` is a valid G2 point. * Verify that `e(pubkey, hash_to_G2(message, domain)) == e(g, signature)`. -## Operations involving aggregate signatures - -### `bls_aggregate_pubkeys` - -Let `bls_aggregate_pubkeys(pubkeys: [uint384]) -> uint384` return `pubkeys[0] + .... + pubkeys[len(pubkeys)-1]`, where `+` is the elliptic curve addition operation over the G1 curve. - -### `bls_aggregate_signatures` - -Let `bls_aggregate_signatures(signatures: [[uint384]]) -> [uint384]` return `signatures[0] + .... + signatures[len(signatures)-1]`, where `+` is the elliptic curve addition operation over the G2 curve. - ### `bls_verify_multiple` Let `bls_verify_multiple(pubkeys: [uint384], messages: [bytes32], signature: [uint384], domain: uint64) -> bool`: From f09a1fa4f5bd524b2f64fafa2d727ae10e067e77 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Sat, 15 Dec 2018 03:25:25 -0500 Subject: [PATCH 13/16] Add pointers to explanatory materials in readme. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd8748d5e..1182ff637 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ethereum 2.0 Specifications -[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). To learn more about sharding and eth2.0/Serenity, see the [sharding FAQ](https://github.com/ethereum/wiki/wiki/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/oa8wCimaTPGBl2nHuBTXWQ). This repo hosts the current eth2.0 specifications. Discussions about design rationale and proposed changes can be brought up and discussed as issues. Solidified, agreed upon changes to spec can be made through pull requests. From 3dc37d258e8f26513f3e837fe343faba74ea4d15 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 15 Dec 2018 04:59:18 -0500 Subject: [PATCH 14/16] Update README.md Co-Authored-By: vbuterin --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1182ff637..25d9abe83 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Ethereum 2.0 Specifications -[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). To learn more about sharding and eth2.0/Serenity, see the [sharding FAQ](https://github.com/ethereum/wiki/wiki/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/oa8wCimaTPGBl2nHuBTXWQ). +[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). +To learn more about sharding and eth2.0/Serenity, see the [sharding FAQ](https://github.com/ethereum/wiki/wiki/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/s/H1PGqDhpm). This repo hosts the current eth2.0 specifications. Discussions about design rationale and proposed changes can be brought up and discussed as issues. Solidified, agreed upon changes to spec can be made through pull requests. From 9e6c1a6244a60e678d4738f20d90a8552a9329ca Mon Sep 17 00:00:00 2001 From: vbuterin Date: Sat, 15 Dec 2018 06:44:18 -0500 Subject: [PATCH 15/16] Remove clamp Removed the use of `clamp` from the spec, as there's no point in a helper function that's used exactly once; it only increases the amount people have to jump around the spec to understand what's going on. --- specs/core/0_beacon-chain.md | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 2097f6a0e..7623eae70 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -65,7 +65,6 @@ - [`get_active_validator_indices`](#get_active_validator_indices) - [`shuffle`](#shuffle) - [`split`](#split) - - [`clamp`](#clamp) - [`get_new_shuffling`](#get_new_shuffling) - [`get_shard_committees_at_slot`](#get_shard_committees_at_slot) - [`get_block_root`](#get_block_root) @@ -833,21 +832,6 @@ def split(values: List[Any], split_count: int) -> List[Any]: ] ``` -#### `clamp` - -```python -def clamp(minval: int, maxval: int, x: int) -> int: - """ - Clamps ``x`` between ``minval`` and ``maxval``. - """ - if x <= minval: - return minval - elif x >= maxval: - return maxval - else: - return x -``` - #### `get_new_shuffling` ```python @@ -859,10 +843,12 @@ def get_new_shuffling(seed: Hash32, """ active_validator_indices = get_active_validator_indices(validators) - committees_per_slot = clamp( + committees_per_slot = max( 1, - SHARD_COUNT // EPOCH_LENGTH, - len(active_validator_indices) // EPOCH_LENGTH // TARGET_COMMITTEE_SIZE, + min( + SHARD_COUNT // EPOCH_LENGTH, + len(active_validator_indices) // EPOCH_LENGTH // TARGET_COMMITTEE_SIZE, + ) ) # Shuffle with seed From 06fd809549397dd8e9a9f58e610e2891ba2114f1 Mon Sep 17 00:00:00 2001 From: chainsafe Date: Sat, 15 Dec 2018 09:28:13 -0500 Subject: [PATCH 16/16] cleaning up README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 25d9abe83..9563c97ed 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # Ethereum 2.0 Specifications -[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). +[![Join the chat at https://gitter.im/ethereum/sharding](https://badges.gitter.im/ethereum/sharding.svg)](https://gitter.im/ethereum/sharding?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + To learn more about sharding and eth2.0/Serenity, see the [sharding FAQ](https://github.com/ethereum/wiki/wiki/Sharding-FAQs) and the [research compendium](https://notes.ethereum.org/s/H1PGqDhpm). -This repo hosts the current eth2.0 specifications. Discussions about design rationale and proposed changes can be brought up and discussed as issues. Solidified, agreed upon changes to spec can be made through pull requests. +This repo hosts the current eth2.0 specifications. Discussions about design rationale and proposed changes can be brought up and discussed as issues. Solidified, agreed upon changes to spec can be made through pull requests. # Specs