Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-969: style corrections + syntax HLing + make C-code blob a drop-in snippet. #979

Merged
merged 6 commits into from Apr 16, 2018
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
194 changes: 113 additions & 81 deletions EIPS/eip-969.md
@@ -1,8 +1,8 @@
---
eip: 969
title: Modifications to ethash to invalidate existing dedicated hardware implementations
author: David Stanfill <david@airsquirrels.com>
discussions-to: https://gitter.im/ethereum/topics/topic/5ac4d974109bb043328911ce/eip-969-discussion
eip: 969
title: Modifications to ethash to invalidate existing dedicated hardware implementations
author: David Stanfill <david@airsquirrels.com>
discussions-to: https://gitter.im/ethereum/topics/topic/5ac4d974109bb043328911ce/eip-969-discussion
status: Draft
type: Standards Track
category: Core
Expand All @@ -26,81 +26,83 @@ may *"break"* these miners if they are in-fact built as traditional ASICs.

## Motivation

ASIC based miners will have lower operational costs than GPU based miners which
will result in GPU based mining quickly becoming unprofitable. Given that
production of ASIC based miners has a high barrier to entry and few market players,
this will cause a trend towards centralization of mining power.
ASIC-based miners will have lower operational costs than GPU-based miners, which
will result in GPU-based mining quickly becoming unprofitable. Given that
production of ASIC-based miners has a high barrier to entry and few market players,
this will cause a trend towards centralization of mining power.

Risks include market dominance by a single manufacturer that may utilize production
stock to mine themselves, introduce backdoors in their hardware, or otherwise
facilitate a 51% attack that would be infeasible.
Risks include market dominance by a single manufacturer that may utilize production
stock to mine themselves, introduce backdoors in their hardware, or facilitate a 51%
attack that would otherwise be infeasible.

This trend towards centralization has a negative effect on network security,
putting significant control of the network in the hands of only a few entities.

Ethash remains ASIC resistant, however ASIC manufacturer technology is advancing
Ethash remains ASIC-resistant, however ASIC manufacturer technology is advancing
and ethash may require further changes in order to remain resistant to unforeseen
design techniques. This EIP seeks explicitly to buy time during which newly developed
ASIC technology will face a barrier while more long term mechanisms to ensure
continued ASIC resistance can be explored.
design techniques. This EIP seeks explicitly to buy time during which newly-developed
ASIC technology will face a barrier while more long-term mechanisms to ensure
continued ASIC resistance can be explored.

## Specification

If `block.number >= ASIC_MITIGATION_FORK_BLKNUM`, require that the ethash solution
If `block.number >= ASIC_MITIGATION_FORK_BLKNUM`, require that the ethash solution
sealing the block has been mined using `ethashV2`.

## EthashV2

`ethashV2` will be identical in specification to the current `ethash`(v1) algorithm, with
the exception of the implementation of `fnv`.
the exception of the implementation of `fnv`.

The new algorithm replaces the 5 current uses of `fnv` inside `hashimoto` with 5
separate instances defined as `fnvA`, `fnvB`, `fnvC`, `fnvD`, and `fnvE`, utilizing

`FNV_PRIME_A=0x10001a7`
`FNV_PRIME_B=0x10001ab`
`FNV_PRIME_C=0x10001cf`
`FNV_PRIME_D=0x10001e3`
`FNV_PRIME_E=0x10001f9`
The new algorithm replaces the 5 current uses of `fnv` inside `hashimoto` with 5
separate instances defined as `fnvA`, `fnvB`, `fnvC`, `fnvD`, and `fnvE`, utilizing

``` c
FNV_PRIME_A=0x10001a7
FNV_PRIME_B=0x10001ab
FNV_PRIME_C=0x10001cf
FNV_PRIME_D=0x10001e3
FNV_PRIME_E=0x10001f9
```

`fnvA` replaces `fnv` in the DAG item selection step
`fnvB` replaces `fnv` in the DAG item mix step
`fnvC(fnvD(fnvE` replaces `fnv(fnv(fnv(` in the compress mix step
`fnvA` replaces `fnv` in the DAG item selection step;
`fnvB` replaces `fnv` in the DAG item mix step;
`fnvC(fnvD(fnvE` replaces `fnv(fnv(fnv(` in the compress mix step.

`fnv` as utilized in DAG-item creation should remain unchanged.

## Agent Changes (Optional Variant)

The JSON-RPC `eth_GetWork` call may optionally return the proposed blocks algorithm.
While a miner or pool may infer the requirement for ethashV2 based on the computed
While a miner or pool may infer the requirement for `ethashV2` based on the computed
epoch of the provided seedHash, it is beneficial to explicitly provide this
field so a miner does not require special configuration when mining on a chain
that chooses not to implement the ASIC_Mitigation hardfork.
that chooses not to implement the `ASIC_Mitigation` hardfork.

Due to compatibility concerns with implementations that already add additional
parameters to GetWork, it is desired to add BlockNumber as an explicit 4th parameter
as suggested in https://github.com/ethereum/go-ethereum/issues/2333. Algorithm
should then be returned as either `"ethash"` or `"ethashV2"` according to the
`block.number >= ASIC_MITIGATION_FORK_BLKNUM` criteria.
Due to compatibility concerns with implementations that already add additional
parameters to `GetWork`, it is desired to add `BlockNumber` as an explicit 4th parameter
as suggested in https://github.com/ethereum/go-ethereum/issues/2333. Algorithm
should then be returned as either `"ethash"` or `"ethashV2"` according to the
`block.number >= ASIC_MITIGATION_FORK_BLKNUM` criteria.

## Rationale

This EIP is aimed at breaking existing ASIC based miners via small changes to the
This EIP is aimed at breaking existing ASIC-based miners via small changes to the
existing ethash algorithm. We hope to accomplish the following:

1. Break existing ASIC based miners.
1. Break existing ASIC-based miners.
2. Demonstrate a willingness to fork in the event of future ASIC miner production.

Goal #1 is something that we can only do probabilistically without detailed
knowledge of existing ASIC miner design. The known released miner is available for
purchase [here](https://shop.bitmain.com/product/detail?pid=00020180403174908564M8dMJKtz06B7) with delivery slated for mid-summer.
knowledge of existing ASIC miner design. The known released miner is available for
purchase [here](https://shop.bitmain.com/product/detail?pid=00020180403174908564M8dMJKtz06B7),
with delivery slated for mid-summer 2018.

Our approach should balance the inherent security risks involved with changing
Our approach should balance the inherent security risks involved with changing
the mining algorithm with the risk that the change we make does not break existing
ASIC miners. This EIP leans towards minimizing the security risks by making minimal
changes to the algorithm accepting the risk that the change may not break dedicated
hardware miners that utilize partially or fully configurable logic.
ASIC miners. This EIP leans towards minimizing the security risks by making minimal
changes to the algorithm, accepting the risk that the change may not break dedicated
hardware miners that utilize partially- or fully-configurable logic.

Furthermore, we do not wish to introduce significant algorithm changes that
may alter the power utilization or performance profile of existing GPU hardware.
Expand All @@ -112,25 +114,27 @@ It is proposed that `ASIC_MITIGATION_FORK_BLKNUM` be no more than 5550000 (epoch
around 30 days of notice to node and miner developers and a sufficient window
for formal analysis of the changes by experts. We must weigh this window against
the risk introduced by allowing ASICs that may exist to continue to propagate
on the network, as well as the risk of providing too much advanced warning to
ASIC developers.
on the network, as well as the risk of providing too much advanced warning to
ASIC developers.

It is further understood that this change will not prevent redesign of existing
dedicated hardware with new ASIC chips. The intention of this change is only
to disable currently active or mid-production hardware and provide time for
POS development as well as larger algorithim changes to be well analyzed by
POS development as well as larger algorithim changes to be well analyzed by
experts.

The choice of FNV constants is made based on the formal specification at
https://tools.ietf.org/html/draft-eastlake-fnv-14#section-2.1

@goobur provided the following python code to output primes matching this criteria
@goobur provided the following python code to output primes matching this criteria:

`candidates = [2**24 + 2**8 + _ for _ in xrange(256)]`</br>
`candidates = [_ for _ in candidates if is_prime(_)]`</br>
`["0x%x" % _ for _ in candidates if _ % (2**40 - 2**24 - 1) > (2**24 + 2**8 + 2**7)]`</br>
``` python
candidates = [2**24 + 2**8 + _ for _ in xrange(256)]
candidates = [_ for _ in candidates if is_prime(_)]
["0x%x" % _ for _ in candidates if _ % (2**40 - 2**24 - 1) > (2**24 + 2**8 + 2**7)]
```

The minimal prime constraint was relaxed, as has already been the case in ethashV1.
The minimal prime constraint was relaxed, as has already been the case in `ethashV1`.

Typical ASIC synthesis tools would optimize multiplication of a constant
in the FNV algorithm, while reducing the area needed for the multiplier according
Expand All @@ -139,48 +143,76 @@ through minor mask changes, we propose choosing new constants with a larger
hamming weight, however care should be taken not to choose constants with too
large of a weight.

The current FNV prime, 0x1000193 has a hamming weight of 6.
`HammingWeight(0x10001a7) = 7;`
`HammingWeight(0x10001ab) = 7;`
`HammingWeight(0x10001cf) = 8;`
`HammingWeight(0x10001e3) = 7;`
`HammingWeight(0x10001ef) = 9; // Not chosen`
`HammingWeight(0x10001f9) = 8;`
`HammingWeight(0x10001fb) = 9; // Not chosen`

An exhaustive analysis was done regarding the dispersion of these constants as compared to 0x01000193
using the following process.
The current FNV prime, `0x1000193`, has a hamming weight of 6.

``` c
HammingWeight(0x10001a7) = 7;
HammingWeight(0x10001ab) = 7;
HammingWeight(0x10001cf) = 8;
HammingWeight(0x10001e3) = 7;
HammingWeight(0x10001ef) = 9; // Not chosen
HammingWeight(0x10001f9) = 8;
HammingWeight(0x10001fb) = 9; // Not chosen
```
uint32_t candidate = 0;
uint32_t dups = 0;
uint32_t fnv_candidate = 0x10001a7;
uint8_t *counts = malloc(0xFFFFFFFF);
memset(counts, '\0', 0xFFFFFFFF);
for ( candidate = 0; candidate <= 0xFFFFFFFF; candidate++) {
uint32_t result = (uint_32)(candidate * fnv_candidate);
uint8_t oldCount = counts[result];
counts[result] = counts[result]+1;
if (oldCount != 0) {
dups++;

An analysis can be done regarding the dispersion of these constants as compared to
`0x01000193`, using the following snippet.

``` c
// http://eips.ethereum.org/EIPS/eip-969

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
u_int32_t candidate = 0;
u_int32_t dups = 0;
u_int32_t fnv_candidate = 0x10001a7; // MODIFY!
u_int8_t *counts = malloc(0xFFFFFFFF);

memset(counts, '\0', 0xFFFFFFFF);

for (candidate = 0; candidate < 0xFFFFFFFF; candidate++) {
u_int32_t result = (u_int32_t)(candidate * fnv_candidate);
u_int8_t oldCount = counts[result];

counts[result] = counts[result]+1;
if (oldCount != 0) {
dups++;
}

//// progress display: remove comment to speed down
//if ((candidate & 0xFFFFF) == 0xFFFFF) printf("0x%08x\n", candidate);
}
printf("\nFNV candidate 0x%08x : %i dups\n", fnv_candidate, dups);

return 0;
}
printf("Candidate 0x%08x : %i dups", dups);
```

It can be empirically confirmed that no more than 1 duplicates occur in the 32 bit word space with these constants.
It can be empirically confirmed that no more than 1 duplicate occurs in the
32-bit word space with these constants.

It is worth noting that FNV is not a cryptographic hash, and it is not used as
such in ethash. That said, a more invasive hash algorithm change could be considered.

It is worth noting that FNV is not a cryptographic hash, and it is not used as such in ethash. With
that said, a more invasive hash algorithm change could consider other options. One suggestion has been
[MurmorHash3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp).
One suggestion has been [MurmurHash3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp).

[Other suggestions have been made](https://twitter.com/el33th4xor/status/981292363627810818). [Argon2](https://github.com/P-H-C/phc-winner-argon2), [Equihash](https://blog.z.cash/why-equihash/) of Zcash fame, and [Balloon Hashing](https://crypto.stanford.edu/balloon/).
[Other suggestions have been made](https://twitter.com/el33th4xor/status/981292363627810818):
[Argon2](https://github.com/P-H-C/phc-winner-argon2),
[Equihash](https://blog.z.cash/why-equihash/) of Zcash fame, and
[Balloon Hashing](https://crypto.stanford.edu/balloon/).

Another possible candidate is [Cuckoo Cycle](https://github.com/tromp/cuckoo), although there are some concerns regarding unaddressed optimization vulnerabilities. One review is found [here](https://da-data.blogspot.com/2014/03/a-public-review-of-cuckoo-cycle.html)
Another possible candidate is [Cuckoo Cycle](https://github.com/tromp/cuckoo),
although there are some concerns regarding unaddressed optimization
vulnerabilities. One review can be found
[here](https://da-data.blogspot.com/2014/03/a-public-review-of-cuckoo-cycle.html).

This may be considered once the exact mechanism of the released ASICs is known and
their effectiveness against its optimisations can be fully evaluated.


## Backwards Compatibility

This change implements a backwards incompatible change to proof of work based
Expand All @@ -190,7 +222,7 @@ solutions from the new proof of work algorithm.

## Test Cases

TODO: will need to generate test cases for `ethereum/tests` repository corresponding to the consensus
TODO: will need to generate test cases for `ethereum/tests` repository corresponding to the consensus
changes.

## Implementation
Expand Down