Add Proof of Work articles and CryptoNight article

This commit is contained in:
Piotr Włodarek 2018-11-04 00:42:01 +01:00
parent 0fdc79245f
commit 61b938d197
7 changed files with 248 additions and 12 deletions

View file

@ -1,8 +0,0 @@
---
title: CryptoNight Proof of Work | Monero Documentation
---
# CryptoNight Proof of Work
Possibly the most controversial aspect of Monero (and other CryptoNote coins) is the CryptoNight Proof of Work,
composed of 7 functions. Fortunately, the difficulty would auto-adjust should any major PoW "shortcuts" be discovered.
Still, it poses theoretical centralization risk, if the attacker manages to keep PoW exploit secret.

View file

@ -164,7 +164,7 @@ These are advanced options that allow you to optimize performance of your `moner
| `--max-concurrency` | Max number of threads to use for a parallel jobs. The default value `0` uses the number of CPU threads.
| `--prep-blocks-threads` | Max number of threads to use when computing block hashes (PoW) in groups. Defaults to 4. Decrease this if you don't want `monerod` hog your computer when syncing.
| `--fast-block-sync` | Sync up most of the way by using embedded, "known" block hashes. Pass `1` to turn on and `0` to turn off. This is on (`1`) by default. Normally, for every block the full node must calculate the block hash to verify miner's proof of work. Because the CryptoNight PoW used in Monero is very expensive (even for verification), `monerod` offers skipping these calculations for old blocks. In other words, it's a mechanism to trust `monerod` binary regarding old blocks' PoW validity, to sync up faster.
| `--block-sync-size` | How many blocks are processed in a single batch during chaing synchronization. By default this is 20 blocks for newer history and 100 blocks for older history ("pre v4"). Default behavior is represented by value `0`. Intuitively, the more resources you have, the bigger batch size you may want to try out. Example:<br />`./monerod --block-sync-size=500`
| `--block-sync-size` | How many blocks are processed in a single batch during chain synchronization. By default this is 20 blocks for newer history and 100 blocks for older history ("pre v4"). Default behavior is represented by value `0`. Intuitively, the more resources you have, the bigger batch size you may want to try out. Example:<br />`./monerod --block-sync-size=500`
| `--bootstrap-daemon-address` | The host:port of a "bootstrap" remote open node that the connected wallets can use while this node is still not fully synced. Example:<br/>`./monerod --bootstrap-daemon-address=opennode.xmr-tw.org:18089`. The node will forward selected RPC calls to the bootstrap node. The wallet will handle this automatically and transparently. Obviously, such bootstraping phase has privacy implications similar to directly using a remote node.
| `--bootstrap-daemon-login` | Specify username:password for the bootstrap daemon login (if required). This considers the RPC interface used by the wallet. Normally, open nodes do not require any credentials.
@ -183,7 +183,7 @@ Be advised though that real mining happens **in pools** and with high-end **GPU-
| `--start-mining` | Specify wallet address to mining for. **This must be a [main address](/public-address/main-address)!** It can be neither a subaddres nor integrated address.
| `--mining-threads` | Specify mining threads count. By default ony one thread will be used. For best results, set it to number of your physical cores.
| `--extra-messages-file` | Specify file for extra messages to include into coinbase transactions.
| `--bg-mining-enable` | Enable unobtrusive mining. In this mode mininig will use a small percentage of your system resources to never noticeably slow down your computer. This is intended to encourage people to mine to improve decentralization. That being said chances of finding a block are diminishingly small with solo CPU mining, and even lesser with its unobtrusive version. You can tweak the unobtrusivness / power trade-offs with the further `--bg-*` options below.
| `--bg-mining-enable` | Enable unobtrusive mining. In this mode mining will use a small percentage of your system resources to never noticeably slow down your computer. This is intended to encourage people to mine to improve decentralization. That being said chances of finding a block are diminishingly small with solo CPU mining, and even lesser with its unobtrusive version. You can tweak the unobtrusivness / power trade-offs with the further `--bg-*` options below.
| `--bg-mining-ignore-battery` | If true, assumes plugged in when unable to query system power status.
| `--bg-mining-min-idle-interval` | Specify min lookback interval in seconds for determining idle state.
| `--bg-mining-idle-threshold` | Specify minimum avg idle percentage over lookback interval.
@ -200,7 +200,7 @@ These options are useful for Monero project developers and testers. Normal users
| `--regtest` | Run in a regression testing mode.
| `--fixed-difficulty` | Fixed difficulty used for testing. By default `0`.
| `--test-dbg-lock-sleep` | Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests.
| `--save-graph` | Save data for dr monero.
| `--save-graph` | Save data for dr Monero.
#### Legacy

View file

@ -0,0 +1,157 @@
---
title: CryptoNight | Monero Documentation
---
# CryptoNight
> CryptoNight is a memory hard hash function
## Background
CryptoNight was originally designed around 2013 as part of the CryptoNote suite.
One design goal was to make it very friendly for the off-the-shelf CPU-s, by employing:
* native AES encryption
* fast 64 bit multipliers
* scratchpad fitting exactly the size of the per-core L3 cache on Intel CPUs (about 2MB)
More ambitious design goal was to make it inefficiently computable on ASIC-s.
This goal has since failed, as it inevitably happens with "ASIC hard" algorithms.
Efficient CryptoNight ASIC was developed in 2017 by Bitmain.
Monero inherited CryptoNight as its proof of work in 2014.
Since then Monero slightly evolved the algorithm to intentionally break compatibility with released ASIC-s.
Currently Monero implements CryptoNight v2, a third iteration of original CryptoNight.
## The goal is to find small-enough hash
In hashing based PoW algorithms the goal is to find small-enough hash.
Hash is simply an integer (normally, a very large integer).
Most hashing functions result in 256-bit hashes (integers between 0 and 2^256).
This includes Bitcoin's double-SHA-256 and Monero's CryptoNight.
Miner randomly tweaks input data until the hash fits under specified threshold.
The threshold (also a large integer) is established collectively by the network as part of the consensus mechanism.
The PoW is only considered valid (solved) if hash fits under the threshold.
Because hash functions are one-way, it is not possible to analytically calculate input data that would result in a small-enough hash.
The solution must be brute-forced by tweaking the input data and recalculating the hash over and over again.
Miners have a few areas of flexibility regarding input data - most importantly they can iterate with the nonce value.
They also have a power over which transactions are included in the block and how they are put together in a merkle tree.
## Cryptographic primitives
CryptoNight is based on:
* AES encryption
* 5 hashing functions, all of which were finalist in NIST SHA-3 competition:
* Keccak (the primary one)
* BLAKE
* Groestl
* JH
* Skein
## Input data
In Monero the input to hashing function is concatenation of:
* serialized block header (around 46 bytes; subject to varint representation)
* merkle tree root (32 bytes)
* number of transactions included in the block (around 1-2 bytes; subject to varint representation)
See [get_block_hashing_blob()](https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_format_utils.cpp#L1078) function to dig further.
## Algorithm
!!! warning
The article attempts to give reader a high-level understanding of the CryptoNight algorithm.
For implementation details refer to CryptoNote Standard and Monero source code.
See references at the bottom.
### Overview
CryptoNight attempts to make memory access a bottleneck for performance ("memory hardness"). It has three steps:
1. Initialize large area of memory with pseudo-random data. This memory is known as the scratchpad.
2. Perform numerous read/write operations at pseudo-random addresses on the scratchpad.
3. Hash the entire scratchpad to produce the resulting value.
### Step 1: scratchpad initialization
Firstly, the input data is hashed with Keccak-1600. This results in 200 bytes of pseudorandom data (1600 bits == 200 bytes).
These 200 bytes become a seed to generate a larger, 2MB-wide buffer of pseudorandom data,
by applying AES-256 encryption.
The first 0..31 bytes of Keccak-1600 hash are used as AES key.
The encryption is performed on 128 bytes-long payloads until 2MB is ready.
The first payload are Keccak-1600 bytes 66..191.
The next payload is encryption result of the previous payload.
Each 128-byte payload is actually encrypted 10 times.
The details are a bit more nuanced, see "Scratchpad Initialization" on [CryptoNote Standard](https://cryptonote.org/cns/cns008.txt).
### Step 2: memory-hard loop
The second step is basically 524288 iterations of a simple stateful algorithm.
Each algorithm iteration reads from and writes back to the scratchpad,
at pseudorandom-but-deterministic locations.
Critically, next iteration depends on the state prepared by previous iterations.
It is not possible to directly calculate state of future iterations.
The specific operations include AES, XOR, 8byte_mul, 8byte_add - operations that are CPU-friendly (highly optimized on modern CPU-s).
The goal here is to make memory latency the bottleneck in attempt to close the gap between potential ASIC-s and general purpose CPU-s.
### Step 3: hashing
The final step (simplifying) is to:
* combine original Keccak-1600 output with the whole scratchpad
* pick the hashing algorithm based on 2 low-order bits of the result
* 0=BLAKE-256
* 1=Groestl-256
* 2=JH-256
* 3=Skein-256
* hash the result with selected function
The resulting 256-bit hash is the final output of CryptoNight algorithm.
## Monero specific modifications
### CryptoNight v0
This is how Monero refers to original implementation of CryptoNight.
### CryptoNight v1
See the [source code diff](https://github.com/monero-project/monero/pull/3253/files) for CryptoNight v1 modifications.
### CryptoNight v2
The v2 changes were more involved.
See the [rationale](https://github.com/SChernykh/xmr-stak-cpu/blob/master/README.md) and the [source code diff](https://github.com/monero-project/monero/commit/5fd83c13fbf8dc304909345e60a853c15b0de1e5#diff-7000dc02c792439471da62856f839d62).
## Critique
* CryptoNight hash is relatively expensive to verify. This poses a risk of DoS-ing nodes with incorrect proofs to process. See [strong asymmetry](/proof-of-work/what-is-pow/#strong-asymmetry) requirement.
* The hash function was designed from scratch with limited peer review. While CryptoNight is composed of proven and peer-reviewed primitives, combining secure primitives doesn't necessarily result in a secure cryptosystem.
* CryptoNight ultimately failed to prevent ASIC-s.
* Complexity of CryptoNight kills competition in ASIC manufacturing.
CryptoNight proof of work remains one of the most controversial aspect of Monero.
## Reference
* [CryptoNight hash function](https://cryptonote.org/cns/cns008.txt) description in the CryptoNote Standard
* [CryptoNight v2 source code](https://github.com/monero-project/monero/blob/master/src/crypto/slow-hash.c)
* The entry point is `cn_slow_hash()` function. Manually removing support and optimizations for multiple architectures should help you understand the actual code.
* "Egalitarian Proof of Work" chapter in [CryptoNote whitepaper](https://downloads.getmonero.org/whitepaper_annotated.pdf)
* [First days of Monero mining](https://da-data.blogspot.com/2014/08/minting-money-with-monero-and-cpu.html) by dr David Andersen
* Some [test vectors](https://github.com/monero-project/monero/tree/master/tests/hash) in Monero source code

View file

@ -0,0 +1,40 @@
---
title: Proof of Work in Cryptocurrencies | Monero Documentation
---
# Proof of Work in Cryptocurrencies
> Proof of work is a Sybil protection mechanism
## PoW protects against Sybil attack
In decentralized cryptocurrencies **untrusted** actors sign (blocks of) transactions.
If threshold voting was employed then the scheme would break immediately.
This is because nothing prevents a single actor from creating arbitrary number of pseudonyms and take over the voting.
In distributed systems this is known as Sybil attack.
Instead, cryptocurrencies employ proof of work. In the proof of work scheme,
it is not the number of actors that counts. It is the amount of committed
computational resources.
This, of course, is much harder to game.
To endanger the scheme, an attacker would have to actually control majority (>50%) of computational resources.
In practice, attacker would need this control over significant period of time.
## PoW is a leader election mechanism
In distributed systems "leader election" is a process of establishing which node is responsible for (temporarily) coordinating the system.
In cryptocurrencies PoW is used to elect the node that "wins" the next block.
Using PoW for leader election was one of the key inventions introduced by Bitcoin.
Competing nodes (known as "miners") work on a solution to artificial problem.
Every now and then, someone randomly finds the solution.
Chances are linearly proportional to committed computing power.
The winner uses its solution to "underwrite" the block it assembled. Only blocks with valid solutions are accepted by the network.
The winner also gets a reward for its work. The reward is a specific amount of cryptocurrency created "out of thin air" and assigned to self. The winner also gets all fees coming from transactions included in the block.
The difficulty of the PoW problem is dynamically adjusted by the network, with the goal of finding blocks with a roughly constant rate (typically, every couple of minutes).

View file

@ -0,0 +1,39 @@
---
title: Proof of Work | Monero Documentation
---
# Proof of Work
> Proof of work is a way to legitimize untrusted party
### What exactly is proof of work?
Proof of work is a cryptographic proof that untrusted party committed significant computational resources to solve artificial problem.
Technically, the "proof" is simply a solution to the problem at hand.
### It's all about legitimizing untrusted party
How an untrusted party on the Internet could earn any level of your trust?
It can prove its commitment by solving agreed computationally hard problem.
For example, by requiring untrusted party to perform a hard computation before you accept their connection, you limit connections only to "committed" parties.
In another example, you could require PoW to be attached to incoming e-mails to make spam prohibitively expensive.
### Work must be otherwise useless
The work on and solution to "computationally hard problem" cannot be useful in any other way than to prove the commitment.
If the work is useful elsewhere then it doesn't prove commitment to you.
The problem must be artificial. Otherwise incentives are skewed and the whole scheme breaks.
### Strong asymmetry
The requirement for proof of work scheme is strong asymmetry for work vs verification resources.
The work must be arbitrarily hard. At the same time proof verification must remain dirt cheap (in terms of computational resources).
Cheap verification is critical because at this stage we are dealing with potentially huge number of untrusted parties,
who could DoS the verifier by submitting invalid proofs. Such proofs should be trivial to discard.

View file

@ -61,6 +61,11 @@ title: Monero Technical Specification | Monero Documentation
* ~18.132 million XMR + 0.6 XMR per 2 minutes
* technically infinite but practicaly deflationary if accounted for lost coins
## Divisibility
* Monero is divisible up to 12 digits
* The smallest unit is called piconero and equals 1e-12 XMR, or 0.000000000001 XMR
## Sender privacy
* ring signatures

View file

@ -26,12 +26,15 @@ nav:
- Public keys: 'cryptography/asymmetric/public-key.md'
- Edwards25519 curve: 'cryptography/asymmetric/edwards25519.md'
- Key image: 'cryptography/asymmetric/key-image.md'
# - CryptoNight PoW: 'cryptography/cryptonight.md'
- Base58: 'cryptography/base58.md'
- Address:
- Main: 'public-address/main-address.md'
- Subaddress: 'public-address/subaddress.md'
- Integrated: 'public-address/integrated-address.md'
- Proof of Work:
- What is PoW?: 'proof-of-work/what-is-pow.md'
- PoW in Cryptocurrencies: 'proof-of-work/pow-in-cryptocurrencies.md'
- CryptoNight: 'proof-of-work/cryptonight.md'
- Multisignature: 'multisignature.md'
- Infrastructure:
- Mainnet, stagenet, testnet: 'infrastructure/networks.md'