mirror of
https://github.com/monero-project/monero-docs.git
synced 2024-12-23 03:59:23 +00:00
Add Proof of Work articles and CryptoNight article
This commit is contained in:
parent
0fdc79245f
commit
61b938d197
7 changed files with 248 additions and 12 deletions
|
@ -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.
|
|
|
@ -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.
|
| `--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.
|
| `--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.
|
| `--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-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.
|
| `--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.
|
| `--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.
|
| `--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.
|
| `--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-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-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.
|
| `--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.
|
| `--regtest` | Run in a regression testing mode.
|
||||||
| `--fixed-difficulty` | Fixed difficulty used for testing. By default `0`.
|
| `--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.
|
| `--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
|
#### Legacy
|
||||||
|
|
||||||
|
|
157
docs/proof-of-work/cryptonight.md
Normal file
157
docs/proof-of-work/cryptonight.md
Normal 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
|
40
docs/proof-of-work/pow-in-cryptocurrencies.md
Normal file
40
docs/proof-of-work/pow-in-cryptocurrencies.md
Normal 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).
|
39
docs/proof-of-work/what-is-pow.md
Normal file
39
docs/proof-of-work/what-is-pow.md
Normal 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.
|
|
@ -61,6 +61,11 @@ title: Monero Technical Specification | Monero Documentation
|
||||||
* ~18.132 million XMR + 0.6 XMR per 2 minutes
|
* ~18.132 million XMR + 0.6 XMR per 2 minutes
|
||||||
* technically infinite but practicaly deflationary if accounted for lost coins
|
* 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
|
## Sender privacy
|
||||||
|
|
||||||
* ring signatures
|
* ring signatures
|
||||||
|
|
|
@ -26,12 +26,15 @@ nav:
|
||||||
- Public keys: 'cryptography/asymmetric/public-key.md'
|
- Public keys: 'cryptography/asymmetric/public-key.md'
|
||||||
- Edwards25519 curve: 'cryptography/asymmetric/edwards25519.md'
|
- Edwards25519 curve: 'cryptography/asymmetric/edwards25519.md'
|
||||||
- Key image: 'cryptography/asymmetric/key-image.md'
|
- Key image: 'cryptography/asymmetric/key-image.md'
|
||||||
# - CryptoNight PoW: 'cryptography/cryptonight.md'
|
|
||||||
- Base58: 'cryptography/base58.md'
|
- Base58: 'cryptography/base58.md'
|
||||||
- Address:
|
- Address:
|
||||||
- Main: 'public-address/main-address.md'
|
- Main: 'public-address/main-address.md'
|
||||||
- Subaddress: 'public-address/subaddress.md'
|
- Subaddress: 'public-address/subaddress.md'
|
||||||
- Integrated: 'public-address/integrated-address.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'
|
- Multisignature: 'multisignature.md'
|
||||||
- Infrastructure:
|
- Infrastructure:
|
||||||
- Mainnet, stagenet, testnet: 'infrastructure/networks.md'
|
- Mainnet, stagenet, testnet: 'infrastructure/networks.md'
|
||||||
|
|
Loading…
Reference in a new issue