Skip to content

Commit

Permalink
ProgPoW Review (ethereum#2894)
Browse files Browse the repository at this point in the history
* clear more TBDs and merge Andrea's 0.9.4 spec

* fix broken links

* fix another broken link

* fix yet another broken link

* hope for the last broken link

* force bot

* please be the last broken links

* broken test vector label

* another broken link and test vector label

* all links now work in browser

* ?

* ??

* ready for review

* stop bot

* ready for review

* Michah's review

* more of Michah's review

* a little more of Michah's review

* move Kik fix from Specification to Security Considerations

* move Kik fix from Specification to Security Considerations

* incorporate Andreas Kik changes

* fix up tables

* security section

* security section 2

* reflect decisions in ACD 96
  • Loading branch information
gcolvin authored and Arachnid committed Mar 6, 2021
1 parent 6bf474b commit a11ee71
Showing 1 changed file with 33 additions and 136 deletions.
169 changes: 33 additions & 136 deletions EIPS/eip-1057.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ created: 2018-05-02

A new Proof-of-Work algorithm to replace Ethash that utilizes almost all parts of commodity GPUs.

We **Do Not** recommend that this Proposal be deployed at this time. Rather it is being offered in the spirit of [Ben DiFrancesco's compromise](https://ethereum-magicians.org/t/a-progpow-compromise-pre-proposal/4057) which for our purposes we state simply as,
* This Proposal **is not** being proposed for deployment in any planned hardfork.
* This Proposal should be fully implemented and tested across major clients.
* Clients implementing this Proposal should be deployed and maintained on a testnet.

This leaves open the possibility and threat of future deployment.

## Abstract

ProgPoW is a proof-of-work algorithm designed to close the efficiency gap available to specialized ASICs. It utilizes almost all parts of commodity hardware (GPUs), and comes pre-tuned for the most common hardware utilized in the Ethereum network.
Expand All @@ -38,8 +31,7 @@ Ethereum's approach is to incentivize a geographically-distributed community of
> Secondly, it should not be possible to make super-linear profits, and especially not so with a high initial barrier. Such a mechanism allows a well-funded adversary to gain a troublesome amount of the network’s total mining power and as such gives them a super-linear reward (thus skewing distribution in their favour) as well as reducing the network security...
> ... While ASICs exist for a proof-of-work function, both goals are
placed in jeopardy.
> ... While ASICs exist for a proof-of-work function, both goals are placed in jeopardy. Because of this, a proof-of-work function that is ASIC-resistant (i.e. difficult or economically inefficient to implement in specialised compute hardware) has been identified as the proverbial silver bullet.
It is from these premises that Ethash was designed as an ASIC-resistant proof-of-work:

Expand Down Expand Up @@ -133,27 +125,6 @@ Ethash requires external memory due to the large size of the DAG. However that

## Specification

Up to release 0.9.3 the DAG is generated exactly as in Ethash. All the parameters (epoch length, DAG size, etc) are unchanged. See the original [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) spec for details on generating the DAG.

Release 0.9.3 has been software and hardware audited:
* [Least Authority — ProgPoW Software Audit PDF](https://leastauthority.com/static/publications/Least%20Authority%20-%20ProgPow%20Algorithm%20Final%20Audit%20Report.pdf)
* [Bob Rao - ProgPoW Hardware Audit PDF](https://github.com/ethereum-cat-herders/progpow-audit/raw/master/Bob%20Rao%20-%20ProgPOW%20Hardware%20Audit%20Report%20Final.pdf)

Following the suggestion expressed by Least Authority in their findings, new proposed release 0.9.4 introduces a tweak in DAG generation in order to mitigate the possibility of a "Light Evaluation" attack.
This change implies the modification of `ETHASH_DATASET_PARENTS` from a value of 256 to the new value of 512. Due to this the DAG memory file used by ProgPoW is no longer compatible with the one used by Ethash (epoch length and size increase ratio remain the same though).

After the completion of the audits a clever finding by [Kik](https://github.com/kik/) disclosed an exploitable condition to [bypass ProgPoW memory hardness](https://github.com/kik/progpow-exploit). The condition is present in Ethash but near-impossible to exploit, and requires the availability of a customized node able to accept modified block headers by the miner. To prevent this exploit this release changes the condition modifying the input state of the last keccak pass from
* header (256 bits) +
* seed for mix initiator (64 bits) +
* mix from main loop (256 bits)
* no padding

to
* digest from initial keccak (256 bits) +
* mix from main loop (256 bits) +
* padding
thus widening the constraint to target in keccak [brute force keccak linear searches](https://github.com/kik/progpow-exploit) from 64 to 256 bits.

ProgPoW can be tuned using the following parameters. The proposed settings have been tuned for a range of existing, commodity GPUs:

* `PROGPOW_PERIOD`: Number of blocks before changing the random program
Expand All @@ -165,23 +136,22 @@ ProgPoW can be tuned using the following parameters. The proposed settings have
* `PROGPOW_CNT_CACHE`: The number of cache accesses per loop
* `PROGPOW_CNT_MATH`: The number of math operations per loop

The values of these parameters have been tweaked between version 0.9.2 (live on the Gangnam testnet) and 0.9.3 (proposed for [Ethereum adoption](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1057.md)). See [this medium post](https://medium.com/@ifdefelse/progpow-progress-da5bb31a651b) for details.
Release 0.9.4 keeps the same tunables of 0.9.3 and includes the tweak for DAG generation.
The values of these parameters have been tweaked between the original version and the version proposed here for Ethereum adoption. See [this medium post](https://medium.com/@ifdefelse/progpow-progress-da5bb31a651b) for details.

| Parameter | 0.9.2 | 0.9.3 | 0.9.4 |
|-----------------------|-------|-------|-------|
| `PROGPOW_PERIOD` | `50` | `10` | `10` |
| `PROGPOW_LANES` | `16` | `16` | `16` |
| `PROGPOW_REGS` | `32` | `32` | `32` |
| `PROGPOW_DAG_LOADS` | `4` | `4` | `4` |
| `PROGPOW_CACHE_BYTES` | `16x1024` | `16x1024` | `16x1024` |
| Parameter | 0.9.2 | 0.9.3 |
|-----------------------|-------|-------|
| `PROGPOW_PERIOD` | `50` | `10` |
| `PROGPOW_LANES` | `16` | `16` |
| `PROGPOW_REGS` | `32` | `32` |
| `PROGPOW_DAG_LOADS` | `4` | `4` |
| `PROGPOW_CACHE_BYTES` | `16x1024` | `16x1024` |
| `PROGPOW_CNT_DAG` | `64` | `64` | `64` |
| `PROGPOW_CNT_CACHE` | `12` | `11` | `11` |
| `PROGPOW_CNT_MATH` | `20` | `18` | `18` |

| DAG Parameter | 0.9.2 | 0.9.3 | 0.9.4 |
|--------------------------|-------|-------|-------|
| `ETHASH_DATASET_PARENTS` | `256` | `256` | `512` |
| DAG Parameter | 0.9.2 | 0.9.3 |
|--------------------------|-------|-------|
| `ETHASH_DATASET_PARENTS` | `256` | `256` |


The random program changes every `PROGPOW_PERIOD` blocks (default `10`, roughly 2 minutes) to ensure the hardware executing the algorithm is fully programmable. If the program only changed every DAG epoch (roughly 5 days) certain miners could have time to develop hand-optimized versions of the random sequence, giving them an undue advantage.
Expand Down Expand Up @@ -354,7 +324,6 @@ uint32_t math(uint32_t a, uint32_t b, uint32_t r)
}
```


The flow of the inner loop is:
* Lane `(loop % LANES)` is chosen as the leader for that loop iteration
* The leader's `mix[0]` value modulo the number of 256-byte DAG entries is is used to select where to read from the full DAG
Expand Down Expand Up @@ -547,41 +516,36 @@ hash32_t progPowHash(
}
```

## Example / Testcase

ProgPoW utilizes almost all parts of a commodity GPU, excluding:

* The graphics pipeline (displays, geometry engines, texturing, etc);
* Floating point math.
## Security Considerations

Making use of either of these would have significant portability issues between commodity hardware vendors, and across programming languages.

Since the GPU is almost fully utilized, there’s little opportunity for specialized ASICs to gain efficiency. Removing both the graphics pipeline and floating point math could provide up to 1.2x gains in efficiency, compared to the 2x gains possible in Ethash, and 50x gains possible for CryptoNight.
This proposal has been software and hardware audited:
* [Least Authority — ProgPoW Software Audit PDF](https://leastauthority.com/static/publications/LeastAuthority-ProgPow-Algorithm-Final-Audit-Report.pdf)
* [Bob Rao - ProgPoW Hardware Audit PDF](https://github.com/ethereum-cat-herders/progpow-audit/raw/master/Bob%20Rao%20-%20ProgPOW%20Hardware%20Audit%20Report%20Final.pdf)

## Backwards Compatibility
Least Authority in their findings suggest a change to DAG generation -- modification of `ETHASH_DATASET_PARENTS` from a value of 256 to the new value of 512 -- in order to mitigate vulnerability to a "Light Evaluation" attack. Due to this the DAG memory file used by ProgPoW is would no longer compatible with the one used by Ethash (epoch length and size increase ratio remain the same though).

This algorithm is not backwards compatible with the existing Ethash, and will require a fork for adoption. Furthermore, the network hashrate will halve since twice as much memory is loaded per hash.
We do not recommend implementing this fix at this time. Ethash will not be exploitable for years, and it's not clear ProgPoW will ever be exploitable. It's better to deploy the audited code.

## Test Cases
After the completion of the audits a clever finding by [Kik](https://github.com/kik/) disclosed a vulnerability to [bypassing ProgPoW memory hardness](https://github.com/kik/progpow-exploit). The vulnerability is present in Ethash as well but is near-impossible to exploit. In progPoW it is not possible to exploit -- it assumes the ability to create variants of the candidate block's header hash in a fashion similar to bitcoin, which is actually not possible in Ethereum. An attacker would need modified block headers, would need customized nodes able to accept the modified block headers, and uses extraNonce/extraData as entropy -- which isn’t the standard. And the required brute-force search would be difficult to accomplish in one blocktime. And even if supported by a customized node the block propagation of such mined blocks would be immediately blocked by other peers as the header hash is invalid.

### progpow 0.9.2
The algorithm run on block 30,000 produces the following digest and result:
```
header ffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff
nonce 123456789abcdef0
The author's have since found another vulnerability similar to Kik's, but it adds too much overhead to be ASIC-friendly. See Lanfranchi's full explanation [here](https://github.com/ifdefelse/ProgPOW/issues/51#issuecomment-690155355). To completely prevent such exploits we could change the condition modifying the input state of the last keccak pass from
* header (256 bits) +
* seed for mix initiator (64 bits) +
* mix from main loop (256 bits)
* no padding

digest: 11f19805c58ab46610ff9c719dcf0a5f18fa2f1605798eef770c47219274767d
result: 5b7ccd472dbefdd95b895cac8ece67ff0deb5a6bd2ecc6e162383d00c3728ece
```
to
* digest from initial keccak (256 bits) +
* mix from main loop (256 bits) +
* padding

Additional test vectors can be found [in the test vectors file](../assets/eip-1057/test-vectors.md#progpowhash).
thus widening the constraint to target in keccak [brute force keccak linear searches](https://github.com/kik/progpow-exploit) from 64 to 256 bits.

### progpow 0.9.3
[Machine-readable test vectors](https://github.com/ethereum/EIPs/blob/ad4e73f239d53d72a21cfd8fdc89dc81eb9d2688/assets/eip-1057/test-vectors-0.9.3.json)
This fix is available as a PR to the reference implementation. Again, we do not recommend implementing this fix at this time. Kik's vulnerability and others like it cannot be exploited now and likely never will be. It's better to deploy the audited code.

Additional test vectors can be found [in the test vectors file](../assets/eip-1057/test-vectors.md#progpowhash).
Note that these vulnerabilities cannot be exploited to deny service, double spend, or otherwise damage the network. They could at worst give their deployer an efficiency advantage over other miners.

### progpow 0.9.4
## Test Cases

The random sequence generated for block 30,000 (prog_seed 3,000) can been seen in [kernel.cu](https://github.com/ifdefelse/ProgPOW/blob/824cd791634204c4cc7e31f84bb76c0c84895bd3/test/kernel.cu).

Expand All @@ -602,74 +566,7 @@ Machine-readable test vectors (T.B.D)

## Implementation

We **Do Not** recommend that this Proposal be deployed at this time. Rather it is being offered in the spirit of [Ben DiFrancesco's compromise](https://ethereum-magicians.org/t/a-progpow-compromise-pre-proposal/4057) which for our purposes we state simply as,
* This Proposal **is not** being proposed for deployment in any planned hardfork.
* This Proposal should be fully implemented and tested across major clients.
* Clients implementing this Proposal should be deployed and maintained on a testnet.

This leaves open the possibility and threat of future deployment.

Note that DAG-size growth will defeat the Antminer E3 (and some Innosilicon ASICs) in October or November of 2020 [at about block 11,400,000](https://blog.bitmain.com/en/bitmains-antminer-e3-firmware-update/).

### Clients

| | Languages | 0.9.3 | 0.9.4
--- | --- | --- | ---
Aleth | C++ | |
Besu | Java | Ready |
EthereumJ | Java | Ready | Developing
EthereumJS | Javascript | Ready | Developing
Etherwall | C++ | |
Geth | Go | Ready | Developing
_IfThenElse_ | C++ | Ready | Ready
Mana | Elixer | |
Nethermind | C# | Ready |
OpenEtheum | Rust | Ready |
Trinity | Python | Ready | Developing

### Exchanges

| | Support | 0.9.3 | 0.9.4
--- | --- | --- | ---
Biki | Yes | Ready |
Bilaxi | Yes | Ready |
Binance | Yes | Ready |
BitMart | Yes | Ready |
BitZ | Yes | Ready |
Coinbase | Yes | Ready |
DCcoin | Yes | Ready |
Digfinex | Yes | Ready |
Etherflyer | Yes | Ready |
Flatbtc | Yes | Ready |
Folgory | Yes | Ready |
HitBTC | Yes | Ready |
Hotbit | Yes | Ready |
Lbank | Yes | Ready |
MXC | Yes | Ready |
Nobi | Yes | Ready |

### Pools

| | Support | 0.9.3 | 0.9.4
--- | --- | --- | ---
2Miners | Yes | Ready |
antpool | Yes | Ready |
beepool | Yes | Ready |
Ethermine | Yes | Ready |
F2Pool | Yes | Ready |
firepool | Yes | Ready |
gpumine | Yes | Ready |
hiveon | Yes | Ready |
huobipool | Yes | Ready |
matppool | Yes | Ready |
miningpoolhub | Yes | Ready |
Noanopool | Yes | Ready |
pool.btc.com | Yes | Ready |
poolin | Yes | Ready |
Sparkpool | Yes | Ready |
Spiderpool | Yes | Ready |
xnpopol | Yes | Ready |

The reference ProgPoW mining implementation is located at [the @ifdefelse ProgPOW repository](https://github.com/ifdefelse/ProgPOW).

## License and Copyright

Expand Down

0 comments on commit a11ee71

Please sign in to comment.