Hash_tree_root -> hash_tree_root_internal

Clarifies the distinction between "internal" hash roots (may be < 32 bytes for trivial objects) and "external" ones (zpadded to 32).
This commit is contained in:
vbuterin 2019-01-31 18:03:23 -06:00 committed by GitHub
parent 4cdb66728a
commit 8ffd9adcaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 5 deletions

View File

@ -371,7 +371,12 @@ return typ(**values), item_index
### Tree Hash ### Tree Hash
The below `hash_tree_root` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For the final output only (ie. not intermediate outputs), if the output is less than 32 bytes, right-zero-pad it to 32 bytes. The goal is collision resistance *within* each type, not between types. The below `hash_tree_root_internal` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For use as a "final output" (eg. for signing), use `hash_tree_root(x) = zpad(hash_tree_root_internal(x), 32)`, where `zpad` is a helper that extends the given `bytes` value to the desired `length` by adding zero bytes on the right:
```
def zpad(input: bytes, length: int) -> bytes:
return input + b'\x00' * (length - len(input))`
```
Refer to [the helper function `hash`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#hash) of Phase 0 of the [Eth2.0 specs](https://github.com/ethereum/eth2.0-specs) for a definition of the hash function used below, `hash(x)`. Refer to [the helper function `hash`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#hash) of Phase 0 of the [Eth2.0 specs](https://github.com/ethereum/eth2.0-specs) for a definition of the hash function used below, `hash(x)`.
@ -416,20 +421,20 @@ def merkle_hash(lst):
return hash(chunkz[0] + datalen) return hash(chunkz[0] + datalen)
``` ```
To `hash_tree_root` a list, we simply do: To `hash_tree_root_internal` a list, we simply do:
```python ```python
return merkle_hash([hash_tree_root(item) for item in value]) return merkle_hash([hash_tree_root_internal(item) for item in value])
``` ```
Where the inner `hash_tree_root` is a recursive application of the tree-hashing function (returning less than 32 bytes for short single values). Where the inner `hash_tree_root_internal` is a recursive application of the tree-hashing function (returning less than 32 bytes for short single values).
#### Container #### Container
Recursively tree hash the values in the container in the same order as the fields, and return the hash of the concatenation of the results. Recursively tree hash the values in the container in the same order as the fields, and return the hash of the concatenation of the results.
```python ```python
return hash(b''.join([hash_tree_root(getattr(x, field)) for field in value.fields])) return hash(b''.join([hash_tree_root_internal(getattr(x, field)) for field in value.fields]))
``` ```
## Implementations ## Implementations