## 1. Project Overview & Quickstart (monero-project/monero)

## File: README.md

# Monero

Copyright (c) 2014-2026, The Monero Project  
Portions Copyright (c) 2012-2013 The Cryptonote developers.

## Table of Contents

  - [Development resources](#development-resources)
  - [Vulnerability response](#vulnerability-response)
  - [Research](#research)
  - [Announcements](#announcements)
  - [Introduction](#introduction)
  - [About this project](#about-this-project)
  - [Supporting the project](#supporting-the-project)
  - [License](#license)
  - [Contributing](#contributing)
  - [Scheduled software/network upgrades](#scheduled-softwarenetwork-upgrades)
  - [Release staging schedule and protocol](#release-staging-schedule-and-protocol)
  - [Compiling Monero from source](#compiling-monero-from-source)
    - [Dependencies](#dependencies)
    - [Guix builds](#guix-builds)
  - [Installing Monero from a package](#installing-monero-from-a-package)
  - [Running monerod](#running-monerod)
  - [Using Tor](#using-tor)
  - [Pruning](#pruning)
  - [Debugging](#debugging)
  - [Known issues](#known-issues)

## Development resources

- Web: [getmonero.org](https://getmonero.org)
- Mail: [dev@getmonero.org](mailto:dev@getmonero.org)
- GitHub: [https://github.com/monero-project/monero](https://github.com/monero-project/monero)
- IRC: [#monero-dev on Libera](https://web.libera.chat/#monero-dev)
- It is HIGHLY recommended that you join the #monero-dev IRC channel if you are developing software that uses Monero. Due to the nature of this open source software project, joining this channel and idling is the best way to stay updated on best practices and new developments in the Monero ecosystem. All you need to do is join the IRC channel and idle to stay updated with the latest in Monero development. If you do not, you risk wasting resources on developing integrations that are not compatible with the Monero network. The Monero core team and community continuously make efforts to communicate updates, developments, and documentation via other platforms – but for the best information, you need to talk to other Monero developers, and they are on IRC. #monero-dev is about Monero development, not getting help about using Monero, or help about development of other software, including yours, unless it also pertains to Monero code itself. For these cases, checkout #monero.

## Vulnerability response

- Our [Vulnerability Response Process](https://github.com/monero-project/meta/blob/master/VULNERABILITY_RESPONSE_PROCESS.md) encourages responsible disclosure
- We are also available via [HackerOne](https://hackerone.com/monero)
- Monero is continuously fuzzed by [OSS-Fuzz](https://introspector.oss-fuzz.com/project-profile?project=monero)

## Research

The [Monero Research Lab](https://www.getmonero.org/resources/research-lab/) is an open forum where the community coordinates research into Monero cryptography, protocols, fungibility, analysis, and more. We welcome collaboration and contributions from outside researchers! Because not all Lab work and publications are distributed as traditional preprints or articles, they may be easy to miss if you are conducting literature reviews for your own Monero research. You are encouraged to get in touch with the Monero research community if you have questions, wish to collaborate, or would like guidance to help avoid unnecessarily duplicating earlier or known work.

The Monero research community is available on IRC in [#monero-research-lab on Libera](https://web.libera.chat/#monero-research-lab), which is also accessible via Matrix.

## Announcements

- You can subscribe to an [announcement listserv](https://lists.getmonero.org) to get critical announcements from the Monero core team. The announcement list can be very helpful for knowing when software updates are needed.

## Introduction

Monero is a private, secure, untraceable, decentralised digital currency. You are your bank, you control your funds, and nobody can trace your transfers unless you allow them to do so.

**Privacy:** Monero uses a cryptographically sound system to allow you to send and receive funds without your transactions being easily revealed on the blockchain (the ledger of transactions that everyone has). This ensures that your purchases, receipts, and all transfers remain private by default.

**Security:** Using the power of a distributed peer-to-peer consensus network, every transaction on the network is cryptographically secured. Individual wallets have a 25-word mnemonic seed that is only displayed once and can be written down to backup the wallet. Wallet files should be encrypted with a strong passphrase to ensure they are useless if ever stolen.

**Untraceability:** By taking advantage of ring signatures, a special property of a certain type of cryptography, Monero is able to ensure that transactions are not only untraceable but have an optional measure of ambiguity that ensures that transactions cannot easily be tied back to an individual user or computer.

**Decentralization:** The utility of Monero depends on its decentralised peer-to-peer consensus network - anyone should be able to run the monero software, validate the integrity of the blockchain, and participate in all aspects of the monero network using consumer-grade commodity hardware. Decentralization of the monero network is maintained by software development that minimizes the costs of running the monero software and inhibits the proliferation of specialized, non-commodity hardware.

## About this project

This is the core implementation of Monero. It is open source and completely free to use without restrictions, except for those specified in the license agreement below. There are no restrictions on anyone creating an alternative implementation of Monero that uses the protocol and network in a compatible manner.

As with many development projects, the repository on GitHub is considered to be the "staging" area for the latest changes. Before changes are merged into that branch on the main repository, they are tested by individual developers in their own branches, submitted as a pull request, and then subsequently tested by contributors who focus on testing and code reviews. That having been said, the repository should be carefully considered before using it in a production environment, unless there is a patch in the repository for a particular show-stopping issue you are experiencing. It is generally a better idea to use a tagged release for stability.

**Anyone is welcome to contribute to Monero's codebase!** If you have a fix or code change, feel free to submit it as a pull request directly to the "master" branch. In cases where the change is relatively small or does not affect other parts of the codebase, it may be merged in immediately by any one of the collaborators. On the other hand, if the change is particularly large or complex, it is expected that it will be discussed at length either well in advance of the pull request being submitted, or even directly on the pull request.

## Supporting the project

Monero is a 100% community-sponsored endeavor. If you want to join our efforts, the easiest thing you can do is support the project financially. Both Monero and Bitcoin donations can be made to **donate.getmonero.org** if using a client that supports the [OpenAlias](https://openalias.org) standard. Alternatively, you can send XMR to the Monero donation address via the `donate` command (type `help` in the command-line wallet for details).

The Monero donation address is:  
`888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H`  
Viewkey:  
`f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`  
Base address for restoring with address and viewkey:  
`44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A`

The Bitcoin donation address is:  
`1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H`

Core development funding and/or some supporting services are also graciously provided by [sponsors](https://www.getmonero.org/community/sponsorships/):

[](https://tarilabs.com/)
[](https://www.macstadium.com/)
[](https://cakewallet.com/)
[](https://symas.com/)
[](https://cypherstack.com/)

## License

See [LICENSE](LICENSE).

## Contributing

If you want to help out, see [CONTRIBUTING](docs/CONTRIBUTING.md) for a set of guidelines.

## Scheduled software/network upgrades

Monero uses a scheduled software/network upgrade (hard fork) mechanism to implement new features into the Monero software and network. This means that users of Monero (end users and service providers) should run current versions and upgrade their software when new releases are available. Software upgrades occur when new features are developed and implemented in the codebase. Network upgrades occur in tandem with software upgrades that modify the consensus rules of the Monero network. The required software for network upgrades will be available prior to the scheduled network upgrade date. Please check the repository prior to this date for the proper Monero software version. Below is the historical schedule and the projected schedule for the next upgrade.

Dates are provided in the format YYYY-MM-DD. The "Minimum" is the software version that follows the new consensus rules. The "Recommended" version may include bug fixes and other new features that do not affect the consensus rules.

| Software upgrade block height  | Date       | Fork version      | Minimum Monero version | Recommended Monero version | Details                                                                            |
| ------------------------------ | -----------| ----------------- | ---------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
| 1009827                        | 2016-03-22 | v2                | v0.9.4                 | v0.9.4                     | Allow only >= ringsize 3, blocktime = 120 seconds, fee-free blocksize 60 kb       |
| 1141317                        | 2016-09-21 | v3                | v0.9.4                 | v0.10.0                    | Splits coinbase into denominations  |
| 1220516                        | 2017-01-05 | v4                | v0.10.1                | v0.10.2.1                  | Allow normal and RingCT transactions |
| 1288616                        | 2017-04-15 | v5                | v0.10.3.0              | v0.10.3.1                  | Adjusted minimum blocksize and fee algorithm      |
| 1400000                        | 2017-09-16 | v6                | v0.11.0.0              | v0.11.0.0                  | Allow only RingCT transactions, allow only >= ringsize 5      |
| 1546000                        | 2018-04-06 | v7                | v0.12.0.0              | v0.12.3.0                  | Cryptonight variant 1, ringsize >= 7, sorted inputs
| 1685555                        | 2018-10-18 | v8                | v0.13.0.0              | v0.13.0.4                  | max transaction size at half the penalty free block size, bulletproofs enabled, cryptonight variant 2, fixed ringsize [11](https://youtu.be/KOO5S4vxi0o)
| 1686275                        | 2018-10-19 | v9                | v0.13.0.0              | v0.13.0.4                  | bulletproofs required
| 1788000                        | 2019-03-09 | v10               | v0.14.0.0              | v0.14.1.2                  | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
| 1788720                        | 2019-03-10 | v11               | v0.14.0.0              | v0.14.1.2                  | forbid old RingCT transaction format
| 1978433                        | 2019-11-30 | v12               | v0.15.0.0              | v0.16.0.0                  | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
| 2210000                        | 2020-10-17 | v13               | v0.17.0.0              | v0.17.3.2                  | New CLSAG transaction format
| 2210720                        | 2020-10-18 | v14               | v0.17.1.1              | v0.17.3.2                  | forbid old MLSAG transaction format
| 2688888                        | 2022-08-13 | v15               | v0.18.0.0              | v0.18.5.1                  | ringsize = 16, bulletproofs+, view tags, adjusted dynamic block weight algorithm
| 2689608                        | 2022-08-14 | v16               | v0.18.0.0              | v0.18.5.1                  | forbid old v14 transaction format
| XXXXXXX                        | XXX-XX-XX | XXX                | vX.XX.X.X              | vX.XX.X.X                  | XXX |

X's indicate that these details have not been determined as of commit date.

## Release staging schedule and protocol

Approximately three months prior to a scheduled software upgrade, a branch from master will be created with the new release version tag. Pull requests that address bugs should then be made to both master and the new release branch. Pull requests that require extensive review and testing (generally, optimizations and new features) should *not* be made to the release branch.

## Compiling Monero from source

### Dependencies

The following table summarizes the tools and libraries required to build. A few of the libraries are also included in this repository (marked as "Vendored"). By default, the build uses the library installed on the system and ignores the vendored sources. However, if no library is found installed on the system, then the vendored source will be built and used. The vendored sources are also used for statically-linked builds because distribution packages often include only shared library binaries (`.so`) but not static library archives (`.a`).

| Dep          | Min. version  | Vendored | Debian/Ubuntu pkg    | Arch pkg     | Void pkg           | Fedora pkg          | Optional | Purpose         |
| ------------ | ------------- | -------- | -------------------- | ------------ | ------------------ | ------------------- | -------- | --------------- |
| GCC          | 7             | NO       | `build-essential`    | `base-devel` | `base-devel`       | `gcc`               | NO       |                 |
| CMake        | 3.10          | NO       | `cmake`              | `cmake`      | `cmake`            | `cmake`             | NO       |                 |
| pkg-config   | any           | NO       | `pkg-config`         | `base-devel` | `base-devel`       | `pkgconf`           | NO       |                 |
| Boost        | 1.69          | NO       | `libboost-all-dev`   | `boost`      | `boost-devel`      | `boost-devel`       | NO       | C++ libraries   |
| OpenSSL      | 1.1.1         | NO       | `libssl-dev`         | `openssl`    | `openssl-devel`    | `openssl-devel`     | NO       | cryptography    |
| libzmq       | 4.2.0         | NO       | `libzmq3-dev`        | `zeromq`     | `zeromq-devel`     | `zeromq-devel`      | NO       | ZeroMQ library  |
| libunbound   | 1.4.16        | NO       | `libunbound-dev`     | `unbound`    | `unbound-devel`    | `unbound-devel`     | NO       | DNS resolver    |
| libsodium    | ?             | NO       | `libsodium-dev`      | `libsodium`  | `libsodium-devel`  | `libsodium-devel`   | NO       | cryptography    |
| libunwind    | any           | NO       | `libunwind-dev`      | `libunwind`  | `libunwind-devel`  | `libunwind-devel`   | YES      | Stack traces    |
| libreadline  | 6.3.0         | NO       | `libreadline-dev`    | `readline`   | `readline-devel`   | `readline-devel`    | YES      | Input editing   |
| GTest        | 1.5           | YES      | `libgtest-dev`       | `gtest`      | `gtest-devel`      | `gtest-devel`       | YES      | Test suite      |
| ccache       | any           | NO       | `ccache`             | `ccache`     | `ccache`           | `ccache`            | YES      | Compil. cache   |
| Doxygen      | any           | NO       | `doxygen`            | `doxygen`    | `doxygen`          | `doxygen`           | YES      | Documentation   |
| Graphviz     | any           | NO       | `graphviz`           | `graphviz`   | `graphviz`         | `graphviz`          | YES      | Documentation   |
| libhidapi    | ?             | NO       | `libhidapi-dev`      | `hidapi`     | `hidapi-devel`     | `hidapi-devel`      | YES      | Hardware wallet |
| libusb       | ?             | NO       | `libusb-1.0-0-dev`   | `libusb`     | `libusb-devel`     | `libusb1-devel`     | YES      | Hardware wallet |
| libprotobuf  | ?             | NO       | `libprotobuf-dev`    | `protobuf`   | `protobuf-devel`   | `protobuf-devel`    | YES      | Hardware wallet |
| protoc       | ?             | NO       | `protobuf-compiler`  | `protobuf`   | `protobuf`         | `protobuf-compiler` | YES      | Hardware wallet |

Install all dependencies at once on Debian/Ubuntu:

```
sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind-dev libreadline-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache doxygen graphviz git curl
```

Install all dependencies at once on Arch:
```
sudo pacman -Syu --needed base-devel cmake boost boost-libs openssl zeromq unbound libsodium libunwind readline python ccache doxygen graphviz hidapi libusb protobuf
```

Install all dependencies at once on Fedora:
```
sudo dnf install gcc gcc-c++ cmake pkgconf boost-devel openssl-devel zeromq-devel unbound-devel libsodium-devel libunwind-devel readline-devel ccache doxygen graphviz hidapi-devel libusb1-devel protobuf-devel protobuf-compiler
```

Install all dependencies at once on openSUSE:

```
sudo zypper ref && sudo zypper in cppzmq-devel libboost_chrono-devel libboost_date_time-devel libboost_filesystem-devel libboost_locale-devel libboost_program_options-devel libboost_regex-devel libboost_serialization-devel libboost_system-devel libboost_thread-devel libsodium-devel libunwind-devel unbound-devel cmake doxygen ccache fdupes gcc-c++ libevent-devel libopenssl-devel pkgconf-pkg-config readline-devel patterns-devel-C-C++-devel_C_C++
```

Install all dependencies at once on macOS with the provided Brewfile:

```
brew update && brew bundle --file=contrib/brew/Brewfile
```

FreeBSD one-liner required to build dependencies:

```
pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium unbound
```

### Cloning the repository

Clone recursively to pull-in needed submodule(s):

```
git clone --recursive https://github.com/monero-project/monero
```

If you already have a repo cloned, initialize and update:

```
cd monero && git submodule init && git submodule update
```

*Note*: If there are submodule differences between branches, you may need to use `git submodule sync && git submodule update --init` after changing branches to build successfully.

### Build instructions

Monero uses the CMake build system and a top-level [Makefile](Makefile) that invokes cmake commands as needed.

#### On Linux and macOS

* Install the dependencies
* Change to the root of the source code directory, change to the most recent release branch, and build:

    ```bash
    cd monero
    git checkout release-v0.18
    make
    ```

    *Optional*: If your machine has several cores and enough memory, enable parallel build by running `make -j<number of threads>` instead of `make`. For this to be worthwhile, allow one core and about 2GB of RAM per thread.

    *Note*: The instructions above will compile the most stable release of the Monero software. If you would like to use and test the most recent software, use `git checkout master`. The master branch may contain updates that are both unstable and incompatible with release software, though testing is always encouraged.

* The resulting executables can be found in `build/release/bin`

* Add `PATH="$PATH:$HOME/monero/build/release/bin"` to `.profile`

* Run Monero with `monerod --detach`

* **Optional**: build and run the test suite to verify the binaries:

    ```bash
    make release-test
    ```

    *NOTE*: `core_tests` test may take a few hours to complete.

* **Optional**: to build binaries suitable for debugging:

    ```bash
    make debug
    ```

* **Optional**: build documentation in `doc/html` (omit `HAVE_DOT=YES` if `graphviz` is not installed):

    ```bash
    HAVE_DOT=YES doxygen Doxyfile
    ```

* **Optional**: use ccache not to rebuild translation units, that haven't really changed. Monero's CMakeLists.txt file automatically handles it

    ```bash
    sudo apt install ccache
    ```

#### On the Raspberry Pi

Tested on a Raspberry Pi 5B with a clean installation of Raspberry Pi OS (64-bit) with Debian 12 from https://www.raspberrypi.com/software/operating-systems/.

* `apt-get update && apt-get upgrade` to install the latest software

* Install the dependencies for Monero from the 'Debian' column in the table above.

* **Optional**: increase the system swap size:

    ```bash
    sudo /etc/init.d/dphys-swapfile stop
    sudo nano /etc/dphys-swapfile
    CONF_SWAPSIZE=2048
    sudo /etc/init.d/dphys-swapfile start
    ```

* If using an external hard disk without an external power supply, ensure it gets enough power to avoid hardware issues when syncing, by adding the line "usb_max_current_enable=1" to /boot/firmware/config.txt

* Clone Monero and checkout the most recent release version:

    ```bash
    git clone --recursive https://github.com/monero-project/monero.git
    cd monero
    git checkout v0.18.5.1
    ```

* Build:

    ```bash
    USE_SINGLE_BUILDDIR=1 make release
    ```

* Wait a few hours

* The resulting executables can be found in `build/release/bin`

* Add `export PATH="$PATH:$HOME/monero/build/release/bin"` to `$HOME/.profile`

* Run `source $HOME/.profile`

* Run Monero with `monerod --detach`

* You may wish to reduce the size of the swap file after the build has finished, and delete the boost directory from your home directory

#### On Windows:

Binaries for Windows can be built on Windows using the MinGW toolchain within [MSYS2 environment](https://www.msys2.org). The MSYS2 environment emulates a POSIX system. The toolchain runs within the environment and *cross-compiles* binaries that can run outside of the environment as a regular Windows application.

**Preparing the build environment**

* Download and install the [MSYS2 installer](https://www.msys2.org). Installing MSYS2 requires 64-bit Windows 10 or newer.
* Open the MSYS shell via the `MSYS2 MSYS` shortcut
* Update packages using pacman:

    ```bash
    pacman -Syu
    ```

* Install dependencies:

    ```bash
    pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-unbound
    ```

* Open the MingW shell via `MSYS2 MINGW64` shortcut.

**Cloning**

* To git clone, run:

    ```bash
    git clone --recursive https://github.com/monero-project/monero.git
    ```

**Building**

* Change to the cloned directory, run:

    ```bash
    cd monero
    ```

* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.18.5.1'. If you don't care about the version and just want binaries from master, skip this step:

    ```bash
    git checkout v0.18.5.1
    ```

* To build Monero, run:

    ```bash
    make release-static -j $(nproc)
    ```

   The resulting executables can be found in `build/release/bin`

* **Optional**: to build Windows binaries suitable for debugging, run:

    ```bash
    make debug -j $(nproc)
    ```

   The resulting executables can be found in `build/debug/bin`

### On FreeBSD:

The project can be built from scratch by following instructions for Linux above (but use `gmake` instead of `make`). If you are running Monero in a jail, you need to add `sysvsem="new"` to your jail configuration, otherwise lmdb will throw the error message: `Failed to open lmdb environment: Function not implemented`.

Monero is also available as a port or package as `monero-cli`.

### On OpenBSD:

You will need to add a few packages to your system. `pkg_add cmake gmake zeromq libiconv boost libunbound`.

The `doxygen` and `graphviz` packages are optional and require the xbase set. Running the test suite also requires `py3-requests` package.

Build monero: `gmake`

Note: you may encounter the following error when compiling the latest version of Monero as a normal user:

```
LLVM ERROR: out of memory
c++: error: unable to execute command: Abort trap (core dumped)
```

Then you need to increase the data ulimit size to 2GB and try again: `ulimit -d 2000000`

### On NetBSD:

Check that the dependencies are present: `pkg_info -c libexecinfo boost-headers boost-libs protobuf readline libusb1 zeromq git-base pkgconf gmake cmake | more`, and install any that are reported missing, using `pkg_add` or from your pkgsrc tree. Readline is optional but worth having.

Third-party dependencies are usually under `/usr/pkg/`, but if you have a custom setup, adjust the "/usr/pkg" (below) accordingly.

Clone the monero repository recursively and checkout the most recent release as described above. Then build monero: `gmake BOOST_ROOT=/usr/pkg LDFLAGS="-Wl,-R/usr/pkg/lib" release`. The resulting executables can be found in `build/NetBSD/[Release version]/Release/bin/`.

### On Solaris:

The default Solaris linker can't be used, you have to install GNU ld, then run cmake manually with the path to your copy of GNU ld:

```bash
mkdir -p build/release
cd build/release
cmake -DCMAKE_LINKER=/path/to/ld -D CMAKE_BUILD_TYPE=Release ../..
cd ../..
```

Then you can run make as usual.

### Cross Compiling

You can also cross-compile static binaries on Linux for Windows and macOS with the `depends` system.

* `make depends target=x86_64-linux-gnu` for 64-bit linux binaries.
* `make depends target=x86_64-w64-mingw32` for 64-bit windows binaries.
  * Requires: `g++-mingw-w64-x86-64`
  * You also need to run:
    ```shell
    update-alternatives --set x86_64-w64-mingw32-g++ $(which x86_64-w64-mingw32-g++-posix) && \
    update-alternatives --set x86_64-w64-mingw32-gcc $(which x86_64-w64-mingw32-gcc-posix)
    ```
* `make depends target=x86_64-apple-darwin` for Intel macOS binaries.
  * Requires: `clang-19 lld-19`
* `make depends target=arm64-apple-darwin` for Apple Silicon macOS binaries.
  * Requires: `clang-19 lld-19`
  * You also need to run:
    ```shell
    export PATH="/usr/lib/llvm-19/bin/:$PATH"
    ```
* `make depends target=i686-linux-gnu` for 32-bit linux binaries.
  * Requires: `g++-multilib bc`
* `make depends target=i686-w64-mingw32` for 32-bit windows binaries.
  * Requires: `python3 g++-mingw-w64-i686`
* `make depends target=arm-linux-gnueabihf` for armv7 binaries.
  * Requires: `g++-arm-linux-gnueabihf`
* `make depends target=aarch64-linux-gnu` for armv8 binaries.
  * Requires: `g++-aarch64-linux-gnu`
* `make depends target=riscv64-linux-gnu` for RISC V 64 bit binaries.
  * Requires: `g++-riscv64-linux-gnu`
* `make depends target=x86_64-unknown-freebsd` for freebsd binaries.
  * Requires: `clang`
* `make depends target=arm-linux-android` for 32bit android binaries
* `make depends target=aarch64-linux-android` for 64bit android binaries

The required packages are the names for each toolchain on apt. Depending on your distro, they may have different names.

Using `depends` might also be easier to compile Monero on Windows than using MSYS. Activate Windows Subsystem for Linux (WSL) with a distro (for example Ubuntu), install the apt build-essentials and follow the `depends` steps as depicted above.

The produced binaries still link libc dynamically. If the binary is compiled on a current distribution, it might not run on an older distribution with an older installation of libc.

### Trezor hardware wallet support

If you have an issue with building Monero with Trezor support, you can disable it by setting `USE_DEVICE_TREZOR=OFF`

```bash
USE_DEVICE_TREZOR=OFF make release
```

For more information, please check out Trezor [src/device_trezor/README.md](src/device_trezor/README.md).

### Guix builds

See [contrib/guix/README.md](contrib/guix/README.md).

### Building and running monerod with Docker

```bash
# Build image
docker build -t monerod .

# Create a directory on the host for the blockchain
mkdir -p /path/to/bitmonero

# Run it
docker run -d --user $(id -u):$(id -g) -v /path/to/bitmonero:/.bitmonero -p 127.0.0.1:18080:18080 -p 127.0.0.1:18081:18081 monerod
```

## Installing Monero from a package

**DISCLAIMER: These packages are not part of this repository or maintained by this project's contributors, and as such, do not go through the same review process to ensure their trustworthiness and security.**

Packages are available for

* Debian 12 (Bookworm) or later

    ```bash
    sudo apt install monero
    ```
  More info and versions in the [Debian package tracker](https://tracker.debian.org/pkg/monero).

* Arch Linux:

    ```bash
    sudo pacman -S monero
    ```

* NixOS:

    ```bash
    nix-shell -p monero-cli
    ```

* Guix:

    ```bash
    guix package -i monero
    ```

* Alpine Linux:

    ```bash
    apk add monero
    ```

* macOS [(homebrew)](https://brew.sh/)
    ```bash
    brew install monero
    ```

Packaging for your favorite distribution would be a welcome contribution!

## Running monerod

The build places the binary in `bin/` sub-directory within the build directory from which cmake was invoked (repository root by default). To run in the foreground:

```bash
./bin/monerod
```

To list all available options, run `./bin/monerod --help`. Options can be specified either on the command line or in a configuration file passed by the `--config-file` argument. To specify an option in the configuration file, add a line with the syntax `argumentname=value`, where `argumentname` is the name of the argument without the leading dashes, for example, `log-level=1`.

To run in background:

```bash
./bin/monerod --log-file monerod.log --detach
```

To run as a systemd service, copy [monerod.service](utils/systemd/monerod.service) to `/etc/systemd/system/` and [monerod.conf](utils/conf/monerod.conf) to `/etc/`. The [example service](utils/systemd/monerod.service) assumes that the user `monero` exists and its home is the data directory specified in the [example config](utils/conf/monerod.conf).

If you're on Mac, you may need to add the `--max-concurrency 1` option to monero-wallet-cli, and possibly monerod, if you get crashes refreshing.

## Using Tor

> There is a new, still experimental, [integration with Tor](docs/ANONYMITY_NETWORKS.md). The feature allows connecting over IPv4 and Tor simultaneously - IPv4 is used for relaying blocks and relaying transactions received by peers whereas Tor is used solely for relaying transactions received over local RPC. This provides privacy and better protection against surrounding node (sybil) attacks.

While Monero isn't made to integrate with Tor, it can be used wrapped with torsocks, by setting the following configuration parameters and environment variables:

* `--p2p-bind-ip 127.0.0.1` on the command line or `p2p-bind-ip=127.0.0.1` in monerod.conf to disable listening for connections on external interfaces.
* If you use the wallet with a Tor daemon via the loopback IP (eg, 127.0.0.1:9050), then use `--untrusted-daemon` unless it is your own hidden service.

Example command line to start monerod through Tor:

```bash
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1
```

A helper script is in contrib/tor/monero-over-tor.sh. It assumes Tor is installed already, and runs Tor and Monero with the right configuration.

### Using Tor on Tails

TAILS ships with a very restrictive set of firewall rules. Therefore, you need to add a rule to allow this connection too, in addition to telling torsocks to allow inbound connections. Full example:

```bash
sudo iptables -I OUTPUT 2 -p tcp -d 127.0.0.1 -m tcp --dport 18081 -j ACCEPT
DNS_PUBLIC=tcp torsocks ./monerod --p2p-bind-ip 127.0.0.1 --rpc-bind-ip 127.0.0.1 \
    --data-dir /home/amnesia/Persistent/your/directory/to/the/blockchain
```

## Pruning

As of June 2026, the full Monero blockchain file is about 280 GB. One can store a pruned blockchain, which is about 95 GB. A pruned blockchain can only serve part of the historical chain data to other peers, but is otherwise identical in functionality to the full blockchain. To use a pruned blockchain, it is best to start the initial sync with `--prune-blockchain`. However, it is also possible to prune an existing blockchain using the `monero-blockchain-prune` tool or using the `--prune-blockchain` `monerod` option with an existing chain. If an existing chain exists, pruning will temporarily require disk space to store both the full and pruned blockchains.

For more detailed information see the ['Pruning' entry in the Moneropedia](https://www.getmonero.org/resources/moneropedia/pruning.html)

## Debugging

This section contains general instructions for debugging failed installs or problems encountered with Monero. First, ensure you are running the latest version built from the GitHub repo.

### Obtaining stack traces and core dumps on Unix systems

We generally use the tool `gdb` (GNU debugger) to provide stack trace functionality, and `ulimit` to provide core dumps in builds which crash or segfault.

* To use `gdb` in order to obtain a stack trace for a build that has stalled:

Run the build.

Once it stalls, enter the following command:

```bash
gdb /path/to/monerod `pidof monerod`
```

Type `thread apply all bt` within gdb in order to obtain the stack trace

* If however the core dumps or segfaults:

Enter `ulimit -c unlimited` on the command line to enable unlimited filesizes for core dumps

Enter `echo core | sudo tee /proc/sys/kernel/core_pattern` to stop cores from being hijacked by other tools

Run the build.

When it terminates with an output along the lines of "Segmentation fault (core dumped)", there should be a core dump file in the same directory as monerod. It may be named just `core`, or `core.xxxx` with numbers appended.

You can now analyse this core dump with `gdb` as follows:

```bash
gdb /path/to/monerod /path/to/dumpfile
```

Print the stack trace with `bt`

 * If a program crashed and cores are managed by systemd, the following can also get a stack trace for that crash:

```bash
coredumpctl -1 gdb
```

#### To run Monero within gdb:

Type `gdb /path/to/monerod`

Pass command-line options with `--args` followed by the relevant arguments

Type `run` to run monerod

### Analysing memory corruption

There are two tools available:

#### ASAN

Configure Monero with the -D SANITIZE=ON cmake flag, eg:

```bash
cd build/debug && cmake -D SANITIZE=ON -D CMAKE_BUILD_TYPE=Debug ../..
```

You can then run the monero tools normally. Performance will typically halve.

#### valgrind

Install valgrind and run as `valgrind /path/to/monerod`. It will be very slow.

### LMDB

Instructions for debugging suspected blockchain corruption as per @HYC

There is an `mdb_stat` command in the LMDB source that can print statistics about the database but it's not routinely built. This can be built with the following command:

```bash
cd ~/monero/external/db_drivers/liblmdb && make
```

The output of `mdb_stat -ea ` will indicate inconsistencies in the blocks, block_heights and block_info table.

The output of `mdb_dump -s blocks ` and `mdb_dump -s block_info ` is useful for indicating whether blocks and block_info contain the same keys.

These records are dumped as hex data, where the first line is the key and the second line is the data.

## Known Issues

### Protocols

#### Socket-based

Because of the nature of the socket-based protocols that drive monero, certain protocol weaknesses are somewhat unavoidable at this time. While these weaknesses can theoretically be fully mitigated, the effort required (the means) may not justify the ends. As such, please consider taking the following precautions if you are a monero node operator:

- Run `monerod` on a "secured" machine. If operational security is not your forte, at a very minimum, have a dedicated computer running `monerod` and **do not** browse the web, use email clients, or use any other potentially harmful apps on your `monerod` machine. **Do not click links or load URL/MUA content on the same machine**. Doing so may potentially exploit weaknesses in commands which accept "localhost" and "127.0.0.1".
- If you plan on hosting a public "remote" node, start `monerod` with `--restricted-rpc`. This is a must.

#### Blockchain-based

Certain blockchain "features" can be considered "bugs" if misused. Consequently, please consider the following:

- When receiving monero, be aware that it may be locked for an arbitrary time if the sender elected to, preventing you from spending that monero until the lock time expires. You may want to hold off acting upon such a transaction until the unlock time lapses. To get a sense of that time, you can consider the remaining blocktime until unlock as seen in the `show_transfers` command.

---

## File: contrib/depends/README.md

### Usage

To build dependencies for the current arch+OS, from this working directory:

```bash
make
```

To build for another arch/OS:

```bash
make HOST=host-platform-triplet
```

For example:

```bash
make HOST=x86_64-w64-mingw32 -j4
```

A toolchain will be generated that's suitable for plugging into Monero's
cmake. In the above example, a dir named x86_64-w64-mingw32 will be
created. To use it for Monero, from the top of the Monero source tree:

```bash
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$PWD/../contrib/depends/x86_64-w64-mingw32/share/toolchain.cmake ..
```

Common `host-platform-triplets` for cross compilation are:

- `i686-w64-mingw32` for Win32
- `x86_64-w64-mingw32` for Win64
- `x86_64-apple-darwin` for MacOSX x86_64
- `arm-linux-gnueabihf` for Linux ARM 32 bit
- `aarch64-linux-gnu` for Linux ARM 64 bit
- `riscv64-linux-gnu` for Linux RISCV 64 bit

No other options are needed, the paths are automatically configured.

Dependency Options:
The following can be set when running make: make FOO=bar

```
SOURCES_PATH: downloaded sources will be placed here
BASE_CACHE: built packages will be placed here
FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
DEBUG: disable some optimizations and enable more runtime checking
HOST_ID_SALT: Optional salt to use when generating host package ids
BUILD_ID_SALT: Optional salt to use when generating build package ids
```

Additional targets:

```
download: run 'make download' to fetch all sources without building them
download-osx: run 'make download-osx' to fetch all sources needed for osx builds
download-win: run 'make download-win' to fetch all sources needed for win builds
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
```

#Mingw builds

Building for 32/64bit mingw requires switching alternatives to a posix mode

```bash
update-alternatives --set x86_64-w64-mingw32-g++ x86_64-w64-mingw32-g++-posix
update-alternatives --set x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gcc-posix
```

### Other documentation

- [description.md](description.md): General description of the depends system
- [packages.md](packages.md): Steps for adding packages

---

## File: contrib/epee/README.md

epee -  is a small library of helpers, wrappers, tools and so on, used to make my life easier.

---

## File: contrib/guix/README.md

# Bootstrappable Monero Builds

This directory contains the files necessary to perform bootstrappable Monero 
builds.

[Bootstrappability][b17e] furthers our binary security guarantees by allowing us
to _audit and reproduce_ our toolchain instead of blindly _trusting_ binary
downloads.

We achieve bootstrappability by using Guix as a functional package manager.

# Requirements

Conservatively, you will need an x86_64 machine with:

- 16GB of free disk space on the partition that /gnu/store will reside in
- 8GB of free disk space **per platform triple** you're planning on building
  (see the `HOSTS` [environment variable description][env-vars-list])

# Installation and Setup

If you don't have Guix installed and set up, please follow the instructions in
[INSTALL.md](./INSTALL.md)

# Usage

If you haven't considered your security model yet, please read [the relevant
section](#choosing-your-security-model) before proceeding to perform a build.

## Building

*The author highly recommends at least reading over the [common usage patterns
and examples](#common-guix-build-invocation-patterns-and-examples) section below
before starting a build. For a full list of customization options, see the
[recognized environment variables][env-vars-list] section.*

To build Monero reproducibly with all default options, invoke the
following from the top of a clean repository:

```sh
./contrib/guix/guix-build
```

## Cleaning intermediate work directories

By default, `guix-build` leaves all intermediate files or "work directories"
(e.g. `depends/work`, `guix-build-*/distsrc-*`) intact at the end of a build so
that they are available to the user (to aid in debugging, etc.). However, these
directories usually take up a large amount of disk space. Therefore, a
`guix-clean` convenience script is provided which cleans the current `git`
worktree to save disk space:

```
./contrib/guix/guix-clean
```

## Attesting to build outputs

Much like how Gitian build outputs are attested to in a `gitian.sigs`
repository, Guix build outputs are attested to in the [`guix.sigs`
repository](https://github.com/monero-project/guix.sigs).

After you've cloned the `guix.sigs` repository, to attest to the current
worktree's commit/tag:

```
env GUIX_SIGS_REPO= SIGNER=<gpg-key-name> ./contrib/guix/guix-attest
```

See `./contrib/guix/guix-attest --help` for more information on the various ways
`guix-attest` can be invoked.

## Verifying build output attestations

After at least one other signer has uploaded their signatures to the `guix.sigs`
```
git -C  pull
env GUIX_SIGS_REPO= ./contrib/guix/guix-verify
```

## Common `guix-build` invocation patterns and examples

### Keeping caches outside of the worktree

If you perform a lot of builds and have a bunch of worktrees, you may find it
more efficient to keep the depends tree's download cache and build cache
outside of the worktrees to avoid duplicate downloads and unnecessary builds. To
help with this situation, the `guix-build` script honours the `SOURCES_PATH`,
`BASE_CACHE` environment variables and will pass them on to the
depends tree so that you can do something like:

```sh
env SOURCES_PATH="$HOME/depends-SOURCES_PATH" BASE_CACHE="$HOME/depends-BASE_CACHE" ./contrib/guix/guix-build
```

Note that the paths that these environment variables point to **must be
directories**, and **NOT symlinks to directories**.

See the [recognized environment variables][env-vars-list] section for more
details.

### Building a subset of platform triples

Sometimes you only want to build a subset of the supported platform triples, in
which case you can override the default list by setting the space-separated
`HOSTS` environment variable:

```sh
env HOSTS='x86_64-w64-mingw32 x86_64-apple-darwin' ./contrib/guix/guix-build
```

See the [recognized environment variables][env-vars-list] section for more
details.

### Controlling the number of threads used by `guix` build commands

Depending on your system's RAM capacity, you may want to decrease the number of
threads used to decrease RAM usage or vice versa.

By default, the scripts under `./contrib/guix` will invoke all `guix` build
commands with `--cores="$JOBS"`. Note that `$JOBS` defaults to `$(nproc)` if not
specified. However, astute manual readers will also notice that `guix` build
commands also accept a `--max-jobs=` flag (which defaults to 1 if unspecified).

Here is the difference between `--cores=` and `--max-jobs=`:

> Note: When I say "derivation," think "package"

`--cores=`

- controls the number of CPU cores to build each derivation. This is the value
  passed to `make`'s `--jobs=` flag.

`--max-jobs=`

- controls how many derivations can be built in parallel
- defaults to 1

Therefore, the default is for `guix` build commands to build one derivation at a
time, utilizing `$JOBS` threads.

Specifying the `$JOBS` environment variable will only modify `--cores=`, but you
can also modify the value for `--max-jobs=` by specifying
`$ADDITIONAL_GUIX_COMMON_FLAGS`. For example, if you have a LOT of memory, you
may want to set:

```sh
export ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'
```

Which allows for a maximum of 8 derivations to be built at the same time, each
utilizing `$JOBS` threads.

Or, if you'd like to avoid spurious build failures caused by issues with
parallelism within a single package, but would still like to build multiple
packages when the dependency graph allows for it, you may want to try:

```sh
export JOBS=1 ADDITIONAL_GUIX_COMMON_FLAGS='--max-jobs=8'
```

See the [recognized environment variables][env-vars-list] section for more
details.

## Recognized environment variables

* _**HOSTS**_

  Override the space-separated list of platform triples for which to perform a
  bootstrappable build.

  _(defaults to "x86\_64-linux-gnu aarch64-linux-gnu
  riscv64-linux-gnu x86\_64-w64-mingw32 x86\_64-unknown-freebsd
  x86\_64-apple-darwin arm64-apple-darwin aarch64-linux-android")_

* _**SOURCES_PATH**_

  Set the depends tree download cache for sources. This is passed through to the
  depends tree. Setting this to the same directory across multiple builds of the
  depends tree can eliminate unnecessary redownloading of package sources.

  The path that this environment variable points to **must be a directory**, and
  **NOT a symlink to a directory**.

* _**BASE_CACHE**_

  Set the depends tree cache for built packages. This is passed through to the
  depends tree. Setting this to the same directory across multiple builds of the
  depends tree can eliminate unnecessary building of packages.

  The path that this environment variable points to **must be a directory**, and
  **NOT a symlink to a directory**.

* _**JOBS**_

  Override the number of jobs to run simultaneously, you might want to do so on
  a memory-limited machine. This may be passed to:

    - `guix` build commands as in `guix shell --cores="$JOBS"`
    - `make` as in `make --jobs="$JOBS"`
    - `xargs` as in `xargs -P"$JOBS"`

  See [here](#controlling-the-number-of-threads-used-by-guix-build-commands) for
  more details.

  _(defaults to the value of `nproc` outside the container)_

* _**SOURCE_DATE_EPOCH**_

  Override the reference UNIX timestamp used for bit-for-bit reproducibility,
  the variable name conforms to [standard][r12e/source-date-epoch].

  _(defaults to the output of `git -c log.showSignature=false log --format=%at -1`)_

* _**V**_

  If non-empty, will pass `V=1` to all `make` invocations, making `make` output
  verbose.

  Note that any given value is ignored. The variable is only checked for
  emptiness. More concretely, this means that `V=` (setting `V` to the empty
  string) is interpreted the same way as not setting `V` at all, and that `V=0`
  has the same effect as `V=1`.

* _**SUBSTITUTE_URLS**_

  A whitespace-delimited list of URLs from which to download pre-built packages.
  A URL is only used if its signing key is authorized (refer to the [substitute
  servers section](#option-1-building-with-substitutes) for more details).

* _**ADDITIONAL_GUIX_COMMON_FLAGS**_

  Additional flags to be passed to all `guix` commands.

* _**ADDITIONAL_GUIX_TIMEMACHINE_FLAGS**_

  Additional flags to be passed to `guix time-machine`.

* _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_

  Additional flags to be passed to the invocation of `guix shell` inside
  `guix time-machine`.

# Choosing your security model

No matter how you installed Guix, you need to decide on your security model for
building packages with Guix.

Guix allows us to achieve better binary security by using our CPU time to build
everything from scratch. However, it doesn't sacrifice user choice in pursuit of
this: users can decide whether or not to use **substitutes** (pre-built
packages).

## Option 1: Building with substitutes

### Step 1: Authorize the signing keys

Depending on the installation procedure you followed, you may have already
authorized the Guix build farm key. In particular, the official shell installer
script asks you if you want the key installed, and the debian distribution
package authorized the key during installation.

You can check the current list of authorized keys at `/etc/guix/acl`.

At the time of writing, a `/etc/guix/acl` with just the Guix build farm key
authorized looks something like:

```lisp
(acl
 (entry
  (public-key
   (ecc
    (curve Ed25519)
    (q #8D156F295D24B0D9A86FA5741A840FF2D24F60F7B6C4134814AD55625971B394#)
    )
   )
  (tag
   (guix import)
   )
  )
 )
```

If you've determined that the official Guix build farm key hasn't been
authorized, and you would like to authorize it, run the following as root:

```
guix archive --authorize < /var/guix/profiles/per-user/root/current-guix/share/guix/ci.guix.gnu.org.pub
```

If
`/var/guix/profiles/per-user/root/current-guix/share/guix/ci.guix.gnu.org.pub`
doesn't exist, try:

```sh
guix archive --authorize < /share/guix/ci.guix.gnu.org.pub
```

Where `` is likely:
- `/usr` if you installed from a distribution package
- `/usr/local` if you installed Guix from source and didn't supply any
  prefix-modifying flags to Guix's `./configure`

#### Removing authorized keys

To remove previously authorized keys, simply edit `/etc/guix/acl` and remove the
`(entry (public-key ...))` entry.

### Step 2: Specify the substitute servers

Once its key is authorized, the official Guix build farm at
https://ci.guix.gnu.org is automatically used unless the `--no-substitutes` flag
is supplied. This default list of substitute servers is overridable both on a
`guix-daemon` level and when you invoke `guix` commands.

## Option 2: Disabling substitutes on an ad-hoc basis

If you prefer not to use any substitutes, make sure to supply `--no-substitutes`
like in the following snippet. The first build will take a while, but the
resulting packages will be cached for future builds.

For direct invocations of `guix`:
```sh
guix <cmd> --no-substitutes
```

For the scripts under `./contrib/guix/`:
```sh
export ADDITIONAL_GUIX_COMMON_FLAGS='--no-substitutes'
```

## Option 3: Disabling substitutes by default

`guix-daemon` accepts a `--no-substitutes` flag, which will make sure that,
unless otherwise overridden by a command line invocation, no substitutes will be
used.

If you start `guix-daemon` using an init script, you can edit said script to
supply this flag.

[b17e]: https://bootstrappable.org/
[r12e/source-date-epoch]: https://reproducible-builds.org/docs/source-date-epoch/
[env-vars-list]: #recognized-environment-variables

---

## File: docs/ANONYMITY_NETWORKS.md

# Anonymity Networks with Monero

Currently only Tor and I2P have been integrated into Monero. The usage of
these networks is still considered experimental - there are a few pessimistic
cases where privacy is leaked. The design is intended to maximize privacy of
the source of a transaction by broadcasting it over an anonymity network, while
relying on IPv4 for the remainder of messages to make surrounding node attacks
(via sybil) more difficult.


## Behavior

When the `--proxy` flag is used, `monerod` sends all external traffic via the
proxy. This includes blockchain syncing, connections to other peers, and update
checks. However, it treats the proxy as the clearnet zone. It does not connect
to hidden services over the proxy.

The `--tx-proxy` flag is used specifically for anonymity networks and
enables anonymity network mode. If _any_ anonymity network is enabled,
transactions being broadcast that lack
a valid "context" (i.e. the transaction did not come from a P2P connection),
will only be sent to peers on anonymity networks. If an anonymity network is
enabled but no peers over an anonymity network are available, an error is
logged and the transaction is kept for future broadcasting over an anonymity
network. The transaction will not be broadcast unless an anonymity connection
is made or until `monerod` is shutdown and restarted with only public
connections enabled.

Anonymity networks can also be used with `monero-wallet-cli` and
`monero-wallet-rpc` - the wallets will connect to a daemon through a proxy. The
daemon must provide a hidden service for the RPC itself, which is separate from
the hidden service for P2P connections.

## P2P Commands

Only handshakes, peer timed syncs and transaction broadcast messages are
supported over anonymity networks. If one `--add-exclusive-node` P2P address
is specified, then no syncing will take place and only transaction broadcasting
can occur. It is therefore recommended that `--add-exclusive-node` be combined
with additional exclusive IPv4 address(es).


## Usage

### Blockchain sync

Monerod does not support synchronizing the blockchain over onion or I2P hidden services.
You may sync the blockchain using a SOCKS4 proxy. Monerod will connect to IPv4
nodes using this proxy to sync the blockchain.

```bash
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1
```

You can also combine `--proxy` with `--tx-proxy` (see below).

### Hidden Services

Hidden services - onion and I2P domains - are available to use for transaction broadcasts.
You may use the below options with or without `--proxy`.

#### Outbound Connections

Connecting to an anonymous address requires the command line option
`--tx-proxy` which tells `monerod` the ip/port of a socks proxy provided by a
separate process. On most systems the configuration will look like:

```bash
monerod \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447
```

which tells `monerod` to connect to ".onion" P2P addresses using a socks
proxy at IP 127.0.0.1 port 9050 with a max of 10 outgoing connections and
".b32.i2p" P2P addresses using a socks proxy at IP 127.0.0.1 port 4447
with the default max outgoing connections.

If desired, peers can be manually specified:

```bash
--add-exclusive-node 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084
--add-priority-node 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084
--add-peer 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084
```

Either option can be listed multiple times, and can specify any mix of Tor,
I2P, and IPv4 addresses. Using `--add-exclusive-node` will prevent the usage of
seed nodes on ALL networks, which will typically be undesirable.  
If you specify `add-exclusive-node` for onion or I2P, make sure to do so for clearnet nodes as well, otherwise you will be unable to sync.

#### Inbound Connections

Receiving anonymity connections is done through the option
`--anonymous-inbound`. This option tells `monerod` the inbound address, network
type, and max connections:

```bash
--anonymous-inbound 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084,127.0.0.1:18084,25 \
--anonymous-inbound cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p,127.0.0.1:18085
```

which tells `monerod` that a max of 25 inbound Tor connections are being
received at address "5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18084" and forwarded to `monerod`
localhost port 18084, and a default max I2P connections are being received at
address "cmeua5767mz2q5jsaelk2rxhf67agrwuetaso5dzbenyzwlbkg2q.b32.i2p" and
forwarded to `monerod` localhost port 18085. Using `tx-proxy`(required), these
addresses will be shared with peers over the same network type, otherwise your
peers will not be notified of your onion or I2P address.

**_Note: The specified port for `anonymous-inbound` must be unique (not 18080 etc). `anonymous-inbound` is not for blockchain sync!_**
Peers will use their own `tx-proxy` to relay transactions, which originate on their node,
to your `anonymous-inbound`.

#### Wallet RPC

An anonymity network can be configured to forward incoming connections to a
`monerod` RPC port - which is independent from the configuration for incoming
P2P anonymity connections. The anonymity network (Tor/I2P) is
configured in the same manner as [below](#configuration), except this excludes P2P.

```text
HiddenServiceDir /var/lib/tor/data/monero-rpc
HiddenServicePort 18089 127.0.0.1:18089
```

Then the wallet will be configured to use a Tor/I2P address:
```bash
monero-wallet-cli \
    --proxy 127.0.0.1:9050 \
    --daemon-address 5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion:18089
```

The proxy must match the address type - a Tor proxy will not work properly with
I2P addresses, etc.

I2P hidden service (b32.i2p) and Tor Hidden service (.onion) addresses provide the information necessary to authenticate and
encrypt the connection from end-to-end. If desired, SSL can also be applied to
the connection with `--daemon-address https://5tymba6faziy36md5ffy42vatbjzlye4vyr3gyz6lcvdfximnvwpmwqd.onion` which
requires a server certificate that is signed by a "root" certificate on the
machine running the wallet. Alternatively, `--daemon-ssl-certificate` can be used to
specify a certificate to authenticate the server.

Proxies can also be used to connect to "clearnet" (IPv4 addresses or ICANN
domains), but `--daemon-ssl-certificate` _must_ be used for authentication and
encryption, or bypassed with `--daemon-ssl-allow-any-cert`.

### Network Types

#### Tor & I2P

Options `--add-exclusive-node`, `--add-priority-node`, and `--add-peer` recognize ".onion" and
".b32.i2p" addresses, and will properly forward those addresses to the proxy
provided with `--tx-proxy tor,...` or `--tx-proxy i2p,...`.

Option `--anonymous-inbound` also recognizes ".onion" and ".b32.i2p" addresses,
and will automatically be sent out to outgoing Tor/I2P connections so the peer
can distribute the address to its other peers.

#### Configuration

Tor must be configured for hidden services. An example configuration ("torrc")
might look like:

```text
# P2P Hidden service
HiddenServiceDir /var/lib/tor/data/monero
HiddenServicePort 18084 127.0.0.1:18084  # anonymous-inbound

# RPC Hidden service
HiddenServiceDir /var/lib/tor/data/monero-rpc
HiddenServicePort 18089 127.0.0.1:18089  # rpc-restricted-bind-port
```

This will store key information in `/var/lib/tor/data/monero` and `/var/lib/tor/data/monero-rpc`
and will forward "Tor port" 18084 and 18089 to ports 18084 and 18089 of ip 127.0.0.1, respectively. The file
`/usr/lib/tor/data/monero/hostname` will contain the ".onion" address for use with `--anonymous-inbound`, and
`/var/lib/tor/data/monero-rpc/hostname` will contain the ".onion" address for use with RPC.

I2P must be configured with a standard server tunnel. Configuration differs by
I2P implementation.  
You can find guides for i2pd [here](https://docs.getmonero.org/running-node/monerod-tori2p/#__tabbed_1_2).

## Example Node Configurations

Please check the [`monerod` reference](https://docs.getmonero.org/interacting/monerod-reference/#tori2p-and-proxies) for more information about these flags.

### Clearnet Only

Allows incoming connections and attempts to port forward with UPnP.

```bash
monerod
```

### Connect to IPv4 Nodes Over Clearnet and Relay Transactions via Tor

Monerod will connect to IPv4 nodes via clearnet, revealing to your ISP
that you are running a Monero node, but your transactions will be relayed over
Tor.

```bash
sudo apt install tor # Or install Tor some other way
systemctl start tor # Or start Tor manually
monerod --tx-proxy tor,127.0.0.1:9050,10
```

### Connect To IPv4 Nodes Over Tor Only

This configuration does not connect to hidden services or accept incoming
connections. Your ISP will see that you are running Tor, but not Monerod.

```bash
sudo apt install tor # Or install Tor some other way
systemctl start tor # Or start Tor manually
monerod --proxy 127.0.0.1:9050 --p2p-bind-ip 127.0.0.1
```

### Connect to IPv4 Nodes Over Tor and Connect to Hidden Services

Your ISP will see that you are running Tor and I2P, but not Monerod. Transactions
will be relayed to hidden services. Your node will not accept any incoming
connections (including from Tor and I2P).

```bash
monerod --proxy 127.0.0.1:9050 \
    --p2p-bind-ip 127.0.0.1 \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447,10
```

### Connect to IPv4 over Tor and Publish Hidden Services

You will need to configure [hidden services manually for Tor and I2P](https://docs.getmonero.org/running-node/monerod-tori2p/#node-configuration).

```bash
monerod --proxy 127.0.0.1:9050 \
    --p2p-bind-ip 127.0.0.1 \
    --tx-proxy tor,127.0.0.1:9050,10 \
    --tx-proxy i2p,127.0.0.1:4447,10 \
    --anonymous-inbound=yourlongv3onionaddress.onion:18084,127.0.0.1:18084 \
    --anonymous-inbound=yourlongb32i2paddress.b32.i2p,127.0.0.1:18085
```

### Connect Exclusively to Hidden Services (avoid IPv4 entirely)

This configuration is not currently supported. Monerod relies on IPv4 to sync
the blockchain to make Sybil attacks more difficult.

## Privacy Limitations

There are currently some techniques that could be used to _possibly_ identify
the machine that broadcast a transaction over an anonymity network.

### Timestamps

The peer timed sync command sends the current time in the message. This value
can be used to link an onion address to an IPv4/IPv6 address. If a peer first
sees a transaction over Tor, it could _assume_ (possibly incorrectly) that the
transaction originated from the peer. If both the Tor connection and an
IPv4/IPv6 connection have timestamps that are approximately close in value they
could be used to link the two connections. This is less likely to happen if the
system clock is fairly accurate - many peers on the Monero network should have
similar timestamps.

#### Mitigation

Keep the system clock accurate so that fingerprinting is more difficult. In
the future a random offset might be applied to anonymity networks so that if
the system clock is noticeably off (and therefore more fingerprintable),
linking the public IPv4/IPv6 connections with the anonymity networks will be
more difficult.

### Intermittent Monero Syncing

If a user only runs `monerod` to send a transaction then quit, this can also
be used by an ISP to link a user to a transaction.

#### Mitigation

Run `monerod` as often as possible to conceal when transactions are being sent.
Future versions will also have peers that first receive a transaction over an
anonymity network delay the broadcast to public peers by a randomized amount.
This will not completely mitigate a user who syncs up sends then quits, in
part because this rule is not enforceable, so this mitigation strategy is
simply a best effort attempt.

### Active Bandwidth Shaping

An attacker could attempt to bandwidth shape traffic in an attempt to determine
the source of a Tor/I2P connection. There isn't great mitigation against
this, but I2P should provide better protection against this attack since
the connections are not circuit based.

#### Mitigation

The best mitigation is to use I2P instead of Tor. However, I2P
has a smaller set of users (less cover traffic) and academic reviews, so there
is a trade off in potential issues. Also, anyone attempting this strategy really
wants to uncover a user, it seems unlikely that this would be performed against
every Tor/I2P user.

### I2P/Tor Stream Used Twice

If a single I2P/Tor stream is used 2+ times for transmitting a transaction, the
operator of the hidden service can conclude that both transactions came from the
same source. If the subsequent transactions spend a change output from the
earlier transactions, this will also reveal the "real" spend in the ring
signature. This issue was (primarily) raised by @secparam on [Twitter](https://twitter.com/secparam/status/1153411657214910469).

#### Mitigation

`monerod` currently selects two outgoing connections every 5 minutes for
transmitting transactions over I2P/Tor. Using outgoing connections prevents an
adversary from making many incoming connections to obtain information (this
technique was taken from Dandelion). Outgoing connections also do not have a
persistent public key identity - the creation of a new circuit will generate
a new public key identity. The lock time on a change address is ~20 minutes, so
`monerod` will have rotated its selected outgoing connections several times in
most cases. However, the number of outgoing connections is typically a small
fixed number, so there is a decent probability of reuse with the same public
key identity.

@secparam ([Twitter](https://twitter.com/secparam/status/1153411968147042304)) recommended changing circuits (Tor) as an additional
precaution. This is likely not a good idea - forcibly requesting Tor to change
circuits is observable by the ISP. Instead, `monerod` should likely disconnect
from peers occasionally. Tor will rotate circuits every ~10 minutes, so
establishing new connections will use a new public key identity and make it
more difficult for the hidden service to link information. This process will
have to be done carefully because closing/reconnecting connections can also
leak information to hidden services if done improperly.

At the current time, if users need to frequently make transactions, I2P/Tor
will improve privacy from ISPs and other common adversaries, but still have
some metadata leakages to unknown hidden service operators.

---

## File: docs/COMPILING_DEBUGGING_TESTING.md

# Compiling, debugging and testing efficiently

This document describes ways of compiling, debugging and testing efficiently for various use cases.
The intended audience are developers, who want to leverage newly added tricks to Monero via `CMake`. The document will lower the entry point for these developers.
Before reading this document, please consult section "Build instructions" in the main README.md. 
Some information from README.md will be repeated here, but the aim is to go beyond it.

## Basic compilation

Monero can be compiled via the main `Makefile`, using one of several targets listed there.
The targets are actually presets for `CMake` calls with various options, plus `make` commands for building or in some cases `make test` for testing.
It is possible to extract these `CMake` calls and modify them for your specific needs. For example, a minimal external cmake command to compile Monero, executed from within a newly created build directory could look like:

`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release && make`

where the variable `DIR_SRC` is expected to store the path to the Monero source code.

## Use cases

### Test Driven Development (TDD) - shared libraries for release builds

Building shared libraries spares a lot of disk space and linkage time. By default only the debug builds produce shared libraries. If you'd like to produce dynamic libraries for the release build for the same reasons as it's being done for the debug version, then you need to add the `BUILD_SHARED_LIBS=ON` flag to the `CMake` call, like the following:

`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && make`

A perfect use case for the above call is following the Test Driven Development (TDD) principles. In a nutshell, you'd first write a couple of tests, which describe the (new) requirements of the class/method that you're about to write or modify. The tests will typically compile for quite a long time, so ideally write them once. After you're done with the tests, the only thing left to do is to keep modifying the implementation for as long as the tests are failing. If the implementation is contained properly within a .cpp file, then the only time cost to be paid will be compiling the single source file and generating the implementation's shared library. The test itself will not have to be touched and will pick up the new version of the implementation (via the shared library) upon the next execution of the test.

### Project generation for IDEs

CMake allows to generate project files for many IDEs. The list of supported project files can be obtained by writing in the console:

`cmake -G`

For instance, in order to generate Makefiles and project files for the Code::Blocks IDE, this part of the call would look like the following:

`cmake -G "CodeBlocks - Unix Makefiles" (...)`

The additional artifact of the above call is the `monero.cbp` Code::Blocks project file in the build directory.

### Debugging in Code::Blocks (CB)

First prepare the build directory for debugging using the following example command, assuming, that the path to the source dir is being held in the DIR_SRC variable, and using 2 cores:

`cmake -S "$DIR_SRC" -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON && make -j 2`

After a successful build, open the `monero.cbp` with CB. From the CB's menu bar select the target, that you want debug. Assuming these are unit tests:

`Build -> Select target -> Select target -> unit_tests`

In order to lower the turnaround times, we will run a specific portion of code of interest, without having to go through all the time costly initialization and execution of unrelated parts. For this we'll use GTest's capabilities of test filtering. From the build directory run the following command to learn all the registered tests:

`tests/unit_tests/unit_tests --gtest_list_tests`

For example, if you're only interested in logging, you'd find in the list the label `logging.` and its subtests. To execute all the logging tests, you'd write in the console:

`tests/unit_tests/unit_tests --gtest_filter="logging.*"`

This parameter is what we need to transfer to CB, in order to reflect the same behaviour in the CB's debugger. From the main menu select:

`Project -> Set program's arguments...`

Then in the `Program's arguments` textbox you'd write in this case: 

`--gtest_filter="logging.*"`

Verify if the expected UTs are being properly executed with `F9` or select:

`Build -> Build and run`

If everything looks fine, then after setting some breakpoints of your choice, the target is ready for debugging in CB via:

`Debug -> Start/Continue`

## To be done (and merged):
### Multihost parallel compilation
https://github.com/monero-project/monero/pull/7160

### Unity builds
https://github.com/monero-project/monero/pull/7217

---

## File: docs/CONTRIBUTING.md

# Contributing to Monero

A good way to help is to test, and report bugs. See
[How to Report Bugs Effectively (by Simon Tatham)](https://www.chiark.greenend.org.uk/~sgtatham/bugs.html)
if you want to help that way. Testing is invaluable in making a piece
of software solid and usable.


## General guidelines

* Comments are encouraged.
* If modifying code for which Doxygen headers exist, that header must be modified to match.
* Tests would be nice to have if you're adding functionality.

Patches are preferably to be sent via a GitHub pull request. If that
can't be done, patches in "git format-patch" format can be sent
(eg, posted to [paste.debian.net](https://paste.debian.net/) with a long enough timeout and a link
posted to #monero-dev on irc.libera.chat).

Patches should be self contained. A good rule of thumb is to have
one patch per separate issue, feature, or logical change. Also, no
other changes, such as random whitespace changes, reindentation,
or fixing typos, spelling, or wording, unless user visible.
Following the code style of the particular chunk of code you're
modifying is encouraged. Proper squashing should be done (eg, if
you're making a buggy patch, then a later patch to fix the bug,
both patches should be merged).

If you've made random unrelated changes (either because your editor
is annoying or you made them for other reasons), you can select
what changes go into the coming commit using git add -p, which
walks you through all the changes and asks whether or not to
include this particular change. This helps create clean patches
without any irrelevant changes. git diff will show you the changes
in your tree. git diff --cached will show what is currently staged
for commit. As you add hunks with git add -p, those hunks will
"move" from the git diff output to the git diff --cached output,
so you can see clearly what your commit is going to look like.

## Commits and pull requests

Commit messages should be sensible. That means a subject line that
describes the patch, with an optional longer body that gives details,
documentation, etc.

Please reference the current merged PR list for a general subject line
format of the current contributors. As of 2024 the subject line uses the
following format:

subdirectory under src where changes were made: description of change

For example (PR #9189):
cryptonote_core: early out on out of bounds scaling parameter

When submitting a pull request on GitHub, make sure your branch is
rebased. No merge commits nor stray commits from other people in
your submitted branch, please. You may be asked to rebase if there
are conflicts (even trivially resolvable ones).

PGP signing commits is strongly encouraged. That should explain why
the previous paragraph is here.

# [Code of Conduct (22/C4.1)](http://rfc.zeromq.org/spec:22)

## License

Copyright (c) 2009-2015 Pieter Hintjens.
Copyright (c) 2017-2024, The Monero Project

This Specification is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This Specification is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses>.

## Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

## Design

### Preliminaries

- The project MUST use the git distributed revision control system.
- The project MUST be hosted on github.com or equivalent, herein called the "Platform".
- The project MUST use the Platform issue tracker.
  - Non-GitHub example:
    - "Platform" could be a vanilla git repo and Trac hosted on the same machine/network.
    - The Platform issue tracker would be Trac.
- The project SHOULD have clearly documented guidelines for code style.
- A "Contributor" is a person who wishes to provide a patch, being a set of commits that solve some clearly identified problem.
- A "Maintainer" is a person who merges patches to the project. Maintainers are not developers; their job is to enforce process.
- Contributors MUST NOT have commit access to the repository unless they are also Maintainers.
- Maintainers MUST have commit access to the repository.
- Everyone, without distinction or discrimination, MUST have an equal right to become a Contributor under the terms of this contract.

### Licensing and ownership

- The project MUST use a share-alike license, such as BSD-3, the GPLv3 or a variant thereof (LGPL, AGPL), or the MPLv2.
- All contributions to the project source code ("patches") MUST use the same license as the project.
- All patches are owned by their authors. There MUST NOT be any copyright assignment process.

### Patch requirements

- Maintainers MUST have a Platform account.
- Contributors SHOULD have a Platform account.
- A patch SHOULD be a minimal and accurate answer to exactly one identified and agreed problem.
- A patch MUST adhere to the code style guidelines of the project if these are defined.
- A patch MUST adhere to the "Evolution of Public Contracts" guidelines defined below.
- A patch MUST NOT include non-trivial code from other projects unless the Contributor is the original author of that code.
- A patch MUST compile cleanly and pass project self-tests on at least the principal target platform.
- A patch commit message SHOULD consist of a single short (less than 50 character) line summarizing the change, optionally followed by a blank line and then a more thorough description.
- A "Correct Patch" is one that satisfies the above requirements.

### Development process

- Change on the project MUST be governed by the pattern of accurately identifying problems and applying minimal, accurate solutions to these problems.
- To request changes, a user SHOULD open an issue on the project Platform issue tracker.
- The user or Contributor SHOULD write the issue by describing the problem they face or observe.
- The user or Contributor SHOULD seek consensus on the accuracy of their observation, and the value of solving the problem.
- Users MUST NOT log feature requests, ideas, or suggestions unrelated to Monero code or Monero's dependency code or Monero's potential/future dependency code or research which successfully implements Monero.
- Users MUST NOT log any solutions to problems (verifiable or hypothetical) of which are not explicitly documented and/or not provable and/or cannot be reasonably proven.
- To submit a patch, a Contributor MUST create a Platform pull request back to the project.
- Patches MUST NOT be committed directly to the project.
- To discuss a patch, people MAY comment on the Platform pull request, on the commit, or elsewhere.
- To approve or reject a patch, Contributors MUST use the Platform interface.
- Maintainers SHOULD NOT merge their own patches unless they were added to the merge queue on irc and have at least 2 approvals from contributors OR unless urgent as defined by the Monero Maintainers Team.
- Maintainers MUST NOT make value judgments on correct patches unless the Maintainer (as may happen in rare circumstances) is a core code developer.
- Maintainers MUST NOT merge pull requests in less than 168 hours (1 week) unless deemed urgent by at least 2 Maintainers.
- The user who created an issue SHOULD close the issue after checking the patch is successful.
- Maintainers SHOULD ask for improvements to incorrect patches and SHOULD reject incorrect patches if the Contributor does not respond constructively.
- Any Contributor who has value judgments on a correct patch SHOULD express these via their own patches.
- Maintainers SHOULD NOT merge patches that have unaddressed comments.

### Evolution of public contracts

- All Public Contracts (APIs or protocols) MUST be documented.
- All Public Contracts SHOULD have space for extensibility and experimentation.
- A patch that modifies a stable Public Contract SHOULD not break existing applications unless there is overriding consensus on the value of doing this.
- A patch that introduces new features to a Public Contract SHOULD do so using new names.
- Old names SHOULD be deprecated in a systematic fashion by marking new names as "experimental" until they are stable, then marking the old names as "deprecated".
- When sufficient time has passed, old deprecated names SHOULD be marked "legacy" and eventually removed.
- Old names MUST NOT be reused by new features.
- When old names are removed, their implementations MUST provoke an exception (assertion) if used by applications.

### Project administration

- The Monero Core Team MUST act as Administrators to manage the set of project Maintainers.
- The Administrators MUST ensure their own succession over time by promoting the most effective Maintainers.
- Administrators MAY remove Maintainers who are inactive for an extended period of time, or who repeatedly fail to apply this process accurately.
- Administrators SHOULD block or ban "bad actors" who cause stress and pain to others in the project. This should be done after public discussion, with a chance for all parties to speak. A bad actor is someone who repeatedly ignores the rules and culture of the project, who is needlessly argumentative or hostile, or who is offensive, and who is unable to self-correct their behavior when asked to do so by others.
- Maintainers MUST NOT merge changes to this specification unless they are also Administrators.

---

## File: docs/LEVIN_PROTOCOL.md

# Levin Protocol
This is a document explaining the current design of the Levin protocol, as
used by Monero. The protocol is largely inherited from cryptonote, but has
undergone some changes.

This document also may differ from the `struct bucket_head2` in Monero's
code slightly - the spec here is slightly more strict to allow for
extensibility.

One of the goals of this document is to clearly indicate what is being sent
"on the wire" to identify metadata that could de-anonymize users over I2P/Tor.
These issues will be addressed as they are found. See `ANONYMITY_NETWORKS.md` in
the `docs` folder for any outstanding issues.

> This document does not currently list all data being sent by the monero
> protocol, that portion is a work-in-progress. Please take the time to do it
> if interested in learning about Monero p2p traffic!


## Header
This header is sent for every Monero p2p message.

```
 0               1               2               3
 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x01     |      0x21     |      0x01     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      0x01     |      0x01     |      0x01     |      0x01     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Length                            |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  E. Response  |                   Command
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |                 Return Code
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |Q|S|B|E|               Reserved
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |      0x01     |      0x00     |      0x00     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     0x00      |
+-+-+-+-+-+-+-+-+
```

### Signature
The first 8 bytes are the "signature" which helps identify the protocol (in
case someone connected to the wrong port, etc). The comments indicate that byte
sequence is from "benders nightmare".

This also can be used by deep packet inspection (DPI) engines to identify
Monero when the link is not encrypted. SSL has been proposed as a means to
mitigate this issue, but BIP-151 or the Noise protocol should also be considered.

### Length
The length is an unsigned 64-bit little endian integer. The length does _not_
include the header.

The implementation currently rejects received messages that exceed 100 MB
(base 10) by default.

### Expect Response
A zero-byte if no response is expected from the peer, and a non-zero byte if a
response is expected from the peer. Peers must respond to requests with this
flag in the same order that they were received, however, other messages can be
sent between responses.

There are some commands in the
[cryptonote protocol](#cryptonote-protocol-commands) where a response is
expected from the peer, but this flag is not set. Those responses are returned
as notify messages and can be sent in any order by the peer.

### Command
An unsigned 32-bit little endian integer representing the Monero specific
command being invoked.

### Return Code
A signed 32-bit little endian integer representing the response from the peer
from the last command that was invoked. This is `0` for request messages.

### Flags
 * `Q` - Bit is set if the message is a request.
 * `S` - Bit is set if the message is a response.
 * `B` - Bit is set if this is a the beginning of a [fragmented message](#fragmented-messages).
 * `E` - Bit is set if this is the end of a [fragmented message](#fragmented-messages).

### Version
A fixed value of `1` as an unsigned 32-bit little endian integer.


## Message Flow
The protocol can be subdivided into: (1) notifications, (2) requests,
(3) responses, (4) fragmented messages, and (5) dummy messages. Response
messages must be sent in the same order that a peer issued a request message.
A peer does not have to send a response immediately following a request - any
other message type can be sent instead.

### Notifications
Notifications are one-way messages that can be sent at any time without
an expectation of a response from the peer. The `Q` bit must be set, the `S`,
`B` and `E` bits must be unset, and the `Expect Response` field must be zeroed.

Some notifications must be in response to other notifications. This is not
part of the levin messaging layer, and is described in the
[commands](#commands) section.

### Requests
Requests are the basis of the admin protocol for Monero. The `Q` bit must be
set, the `S`, `B` and `E` bits must be unset, and the `Expect Response` field
must be non-zero. The peer is expected to send a response message with the same
`command` number.

### Responses
Response message can only be sent after a peer first issues a request message.
Responses must have the `S` bit set, the `Q`, `B` and `E` bits unset, and have
a zeroed `Expect Response` field. The `Command` field must be the same value
that was sent in the request message. The `Return Code` is specific to the
`Command` being issued (see [commands])(#commands)).

### Fragmented
Fragmented messages were introduced for the "white noise" feature for i2p/tor.
A transaction can be sent in fragments to conceal when "real" data is being
sent instead of dummy messages. Only one fragmented message can be sent at a
time, and bits `B` and `E` are never set at the same time
(see [dummy messages](#dummy)). The re-constructed message must contain a
levin header for a different (non-fragment) message type.

The `Q` and `S` bits are never set and the `Expect Response` field must always
be zero. The first fragment has the `B` bit set, neither `B` nor `E` is set for
"middle" fragments, and `E` is set for the last fragment.

### Dummy
Dummy messages have the `B` and `E` bits set, the `Q` and `S` bits unset, and
the `Expect Response` field zeroed. When a message of this type is received, the
contents can be safely ignored.


## Commands
### P2P (Admin) Commands

#### (`1001` Request) Handshake
#### (`1001` Response) Handshake
#### (`1002` Request) Timed Sync
#### (`1002` Response) Timed Sync
#### (`1003` Request) Ping
#### (`1003` Response) Ping
#### (`1004` Request) Stat Info
#### (`1004` Response) Stat Info
#### (`1005` Request) Network State
#### (`1005` Response) Network State
#### (`1006` Request) Peer ID
#### (`1006` Response) Peer ID
#### (`1007` Request) Support Flags
#### (`1007` Response) Support Flags

### Cryptonote Protocol Commands

#### (`2001` Notification) New Block
#### (`2002` Notification) New Transactions
#### (`2003` Notification) Request Get Objects
#### (`2004` Notification) Response Get Objects
#### (`2006` Notification) Request Chain
#### (`2007` Notification) Response Chain Entry
#### (`2008` Notification) New Fluffy Block
#### (`2009` Notification) Request Fluffy Missing TX

---

## File: docs/PORTABLE_STORAGE.md

# Portable Storage Format

## Background

Monero makes use of a set of helper classes from a small library named
[epee](https://github.com/monero-project/monero/tree/master/contrib/epee). Part
of this library implements a networking protocol called
[Levin](https://github.com/monero-project/monero/blob/master/contrib/epee/include/net/levin_base.h),
which internally uses a storage format called [Portable
Storage](https://github.com/monero-project/monero/tree/master/contrib/epee/include/storages).
This format (amongst the rest of the
[epee](https://github.com/monero-project/monero/tree/master/contrib/epee)
library), is undocumented - or rather relies on the code itself to serve as the
documentation. Unfortunately, whilst the rest of the library is fairly
straightforward to decipher, the Portable Storage is less-so.  Hence this
document.

## String and Integer Encoding

### Integers

With few exceptions, integers serialized in epee portable storage format are serialized
as little-endian.

### Varints

Varints are used to pack integers in an portable and space optimized way. Varints are stored as little-endian integers, with the lowest 2 bits storing the amount of bytes required, which means the largest value integer that can be packed into 1 byte is 63
(6 bits).

#### Byte Sizes

| Lowest 2 bits | Size value    | Value range                       |
|---------------|---------------|-----------------------------------|
| b00           | 1 byte        | 0 to 63                           |
| b01           | 2 bytes       | 64 to 16383                       |
| b10           | 4 bytes       | 16384 to 1073741823               |
| b11           | 8 bytes       | 1073741824 to 4611686018427387903 |

#### Representations of Example Values
|        Value         | Byte Representation (hex) |
|----------------------|---------------------------|
|                    0 | 00                        |
|                    7 | 1c                        |
|                  101 | 95 01                     |
|               17,000 | A2 09 01 00               |
|        7,942,319,744 | 03 BA 98 65 07 00 00 00   |

### Strings

These are simply length (varint) prefixed char strings without a null
terminator (though one can always add one if desired). There is no
specific encoding enforced, and in fact, many times binary blobs are
stored as these strings. This type should not be confused with the keys
in sections, as those are restricted to a maximum length of 255 and
do not use varints to encode the length.

    "Howdy" => 14 48 6F 77 64 79

### Section Keys

These are similar to strings except that they are length limited to 255
bytes, and use a single byte at the front of the string to describe the
length (as opposed to a varint).

    "Howdy" => 05 48 6F 77 64 79

## Binary Format Specification

### Header

The format must always start with the following header:

| Field            | Type     | Value      |
|------------------|----------|------------|
| Signature Part A | UInt32   | 0x01011101 |
| Signature Part B | UInt32   | 0x01020101 |
| Version          | UInt8    | 0x01       |

In total, the 9 byte header will look like this (in hex): `01 11 01 01 01 01 02 01 01`

### Section

Next we have a root object (or section as the library calls it). This is a map
of name-value pairs called [entries](#Entry). It starts with a count:

| Section       | Type      |
|---------------|-----------|
| Entry count   | varint    |


Which is followed by the section's name-value [entries](#Entry) sequentially:

### Entry

| Entry             | Type                  |
|-------------------|-----------------------|
| Name              | section key           |
| Type              | byte                  |
| Count<sup>1</sup> | varint                |
| Value(s)          | (type-dependent data) |

<sup>1</sup> Note, this is only present if the entry type has the array flag
(see below).

#### Entry types

The types defined are:

```cpp
#define SERIALIZE_TYPE_INT64                1
#define SERIALIZE_TYPE_INT32                2
#define SERIALIZE_TYPE_INT16                3
#define SERIALIZE_TYPE_INT8                 4
#define SERIALIZE_TYPE_UINT64               5
#define SERIALIZE_TYPE_UINT32               6
#define SERIALIZE_TYPE_UINT16               7
#define SERIALIZE_TYPE_UINT8                8
#define SERIALIZE_TYPE_DOUBLE               9
#define SERIALIZE_TYPE_STRING               10
#define SERIALIZE_TYPE_BOOL                 11
#define SERIALIZE_TYPE_OBJECT               12
#define SERIALIZE_TYPE_ARRAY                13
```

The entry type can be bitwise OR'ed with a flag:

```cpp
#define SERIALIZE_FLAG_ARRAY              0x80
```

This signals there are multiple *values* for the entry. Since only one bit is
reserved for specifying an array, we can not directly represent nested arrays.
However, you can place each of the inner arrays inside of a section, and make
the outer array type `SERIALIZE_TYPE_OBJECT | SERIALIZE_FLAG_ARRAY`. Immediately following the type code byte is a varint specifying the length of the array.
Finally, the all the elements are serialized in sequence with no padding and
without any type information. For example:

type, count,
value<sub>1</sub>, value<sub>2</sub>,..., value<sub>n</sub>

#### Entry values

It's important to understand that entry *values* can be encoded any way in which
an implementation chooses. For example, the integers can be in either big or
little endian byte order.

Entry values which are objects (i.e. `SERIALIZE_TYPE_OBJECT`), are stored as
[sections](#Section).

Note, I have not yet seen the type `SERIALIZE_TYPE_ARRAY` in use. My assumption
is this would be used for *untyped* arrays and so subsequent entries could be of
any type.

### Overall example

Let's put it all together and see what an entire object would look like serialized. To represent our data, let's create a JSON object (since it's a format
that most will be familiar with):

```json
{
  "short_quote": "Give me liberty or give me death",
  "long_quote": "Monero is more than just a technology. It's also what the technology stands for.",
  "signed_32bit_int": 20140418,
  "array_of_bools": [true, false, true, true],
  "nested_section": {
    "double": -6.9,
    "unsigned_64bit_int": 11111111111111111111
  }
}
```

This object would translate into the following bytes when serialized into epee portable storage format. The bytes are represented in hex, with comments and whitespace added for readability.

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Monero specifics

### Entry values

#### Hashes, Keys, Blobs

These are stored as strings, `SERIALIZE_TYPE_STRING`.

#### STL containers (vector, list)

These can be arrays of standard integer types, strings or
`SERIALIZE_TYPE_OBJECT`'s for structs.

#### Links to some Monero struct definitions

- [Core RPC
  definitions](https://github.com/monero-project/monero/blob/master/src/rpc/core_rpc_server_commands_defs.h)
- [CryptoNote protocol
  definitions](https://github.com/monero-project/monero/blob/master/src/cryptonote_protocol/cryptonote_protocol_defs.h)



[//]: # ( vim: set tw=80: )

## 2. Official Technical Reference & Guides (monero-project/monero-docs)

## File: README.md

# Monero Docs

This repository contains the source files to Monero Community documentation hosted at [docs.getmonero.org](https://docs.getmonero.org)

- [About](#about)
- [Contributing](#contributing)
- [Local Deployment](#run-the-documentation-server-locally)
- [License](#license)

## About

Monero Docs intends to be a Knowledge Base and User Guide for interacting with Monero.

## Contributing

Contributions are both encouraged and greatly appreciated.

To contribute content, fork this repo and make a pull request to the **`master`** branch including your changes.

1. On GitHub, fork the [monero-docs](https://github.com/monero-project/monero-docs) repo
2. Clone your newly created repo. (Note: replace `your-username` with your GitHub username)

via ssh:
```bash
git clone git@github.com:your-username/monero-docs
```
via https:
```bash
git clone https://github.com/your-username/monero-docs
```
3. Navigate to the repo and create a new topic branch
```bash
cd monero-docs
git checkout -b foobar
```
4. After making modifications, commit and push your changes to your topic branch
5. Open a PR against the monero-docs **`master`** branch

# Run the documentation server locally

- The build process for mkdocs utilizes Python
- It is recommended to install python pip dependencies inside of a Virtual Environment [(venv)](https://squidfunk.github.io/mkdocs-material/guides/creating-a-reproduction/#environment)

Note: You may need to first install `python3-venv` or the equivalent for your distribution
1. Navigate to your `monero-docs` repo
2. Create the python virtual environment
```bash
python3 -m venv .monero-docs-venv
source .monero-docs-venv/bin/activate
```
3. Install mkdocs dependencies to the venv
```bash
pip install --require-hashes -r requirements.txt
```
4. Run the documentation server locally
```bash
python3 -m mkdocs serve
```
5. View your changes at [http://localhost:8000](http://localhost:8000)

## License

The documentation is provided under the [MIT License](LICENSE).

---

## File: docs/en/cryptography/asymmetric/edwards25519.md

---
title: Edwards25519 Elliptic Curve
---
# Edwards25519 Elliptic Curve

!!! note
    Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

!!! note
    This article is only about the underlying curve. Public key derivation and signing algorithm will be treated separately. 

Monero employs edwards25519 elliptic curve as a basis for its key pair generation.

The curve comes from the Ed25519 signature scheme. While Monero takes the curve unchanged, it does not exactly follow rest of the Ed25519.

The edwards25519 curve is [birationally equivalent to Curve25519](https://tools.ietf.org/html/rfc7748#section-4.1).

## Definition

This is the standard edwards25519 curve definition, no Monero specific stuff here,
except the naming convention. The convention comes from the CryptoNote
whitepaper and is widely used in Monero literature.

### Curve equation

    −x^2 + y^2 = 1 − (121665/121666) * x^2 * y^2

Note:

* curve is in two dimensions (nothing fancy, like all the curves is high school)
* curve is mirrored below y axis due to `y^2` part of the equation (not a polynomial)

### Base point: `G`
 
The base point is a specific point on the curve. It is used
as a basis for further calculations. It is an arbitrary choice
by the curve authors, just to standardize the scheme.
 
Note that it is enough to specify the y value and the sign of the x value.
That's because the specific x can be calculated from the curve equation.
    
    G = (x, 4/5)  # take the point with the positive x
    
    # The hex representation of the base point
    5866666666666666666666666666666666666666666666666666666666666666    

### Prime order of the base point: `l`

In laymen terms, the "canvas" where the curve is drawn is assumed
to have a finite "resolution", so point coordinates must "wrap around"
at some point. This is achieved by modulo the `l` value (lowercase L).
In other words, the `l` defines the maximum scalar we can use.

    l = 2^252 + 27742317777372353535851937790883648493
    # => 7237005577332262213973186563042994240857116359379907606001950938285454250989

The `l` is a prime number specified by the curve authors.

In practice this is the private key's strength.

### Total number of points on the curve

The total number of points on the curve is also a prime number:

    q = 2^255 - 19

In practice not all points are "useful" and so the private key strength is limited to `l` describe above.

## Implementation

Monero uses (apparently modified) Ref10 implementation by Daniel J. Bernstein.

## Reference

* [A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/)
* [RFC 8032 defining EdDSA](https://tools.ietf.org/html/rfc8032)
* [Understanding Monero Cryptography](https://steemit.com/monero/@luigi1111/understanding-monero-cryptography-privacy-introduction) - excellent writeup by Luigi
* [StackOverflow answer](https://monero.stackexchange.com/questions/2290/why-how-does-monero-generate-public-ed25519-keys-without-using-the-standard-publ)
* [Python implementation](https://github.com/monero-project/mininero/blob/master/ed25519.py) - not the reference one but easier to understand
* [Encoding point to hex](https://monero.stackexchange.com/questions/6050/what-is-the-base-point-g-from-the-whitepaper-and-how-is-it-represented-as-a)
* [EdDSA on Wikipedia](https://en.wikipedia.org/wiki/EdDSA)

---

## File: docs/en/cryptography/asymmetric/introduction.md

---
title: Asymmetric Cryptography in Monero
---
# Asymmetric Cryptography in Monero

!!! note
    Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Before we get to Monero specific stuff, a little bit of context. We are talking asymmetric cryptography here.
The "asymmetric" simply means the are two keys:

* the private key (used primarily for signing data and for decrypting data)
* the public key (used primarily for signature verification and encrypting data)

This is in contrast to symmetric cryptography which uses a single key. This key is a secret shared among the parties.

Historically, asymmetric cryptography was based on the problem of factorization of a very large integers
back into prime numbers (which is practically impossible for large enough integers).

Recently, asymmetric cryptography is based on a mathematical notion of elliptic curves.
Edwards25519 is a specific, well researched and standardized elliptic curve used in Monero.

---

## File: docs/en/cryptography/asymmetric/key-image.md

---
title: Monero Private Key Image
---
# Monero Private Key Image

!!! note
    Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Private key image serves to detect double spending attempts.

In Monero funds are always sent to a one-time public key `P`.
Related one-time private key `x` is specific to unspent output.

As output can be spent only once (in whole), the related private key can be used only once as well.

Thus, specific private key image `I` being present on the blockchain means
that related output was already spent, and subsequent attempts must not be allowed.

This whole scheme is necessary because Monero uses Ring Signatures
which make it impossible to know whom exactly signed the transaction.
This is why a simple Bitcoin-like double spending check wouldn't work here. 

## Definition

    I = x*Hp(P)

Where:

* `I` - private key image (or "key image" for short)
* `x` - one-time private key used to unlock an unspent output
* `P` - one-time public key of an unspent output
* `Hp()` - hash function accepting an EC point as an argument 

The `P` comes from this:

    P = xG

Where `G` is the [edwards25519](../../cryptography/asymmetric/edwards25519.md) base point. 

Substitute `P` with `xG` and we get:

    I = x*Hp(xG)
    
The key image `I` is a one-way function of the private key `x`.

## Reference

* [StackExchange answer](https://monero.stackexchange.com/questions/2883/what-is-a-key-image)
* [Another SE answer](https://monero.stackexchange.com/questions/2158/what-is-moneros-mechanism-for-defending-against-a-double-spend-attack)
* [Critical bug](https://getmonero.org/2017/05/17/disclosure-of-a-major-bug-in-cryptonote-based-currencies.html) regarding key image verification that was once present in Monero

---

## File: docs/en/cryptography/asymmetric/private-key.md

---
title: Private Keys in Monero
---
# Private Keys in Monero

!!! note
    Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

In Monero, the root private key is generated [randomly](../../cryptography/prng.md). Other private keys are derived deterministically from the root private key.

Private key must be kept secret.

Private key is a **large integer** impossible to guess, like:
`108555083659983933209597798445644913612440610624038028786991485007418559037440`

Private key is 256 bits long. 

Private key is a **scalar**, meaning it is a single value.

In equations scalars are represented by **lowercase letters**. 

## Relation to Ed25519

Being simply a random integer, private key is not specific to any particular asymmetric cryptography scheme.

In context of Monero EC cryptography the private key is a number the base point `G` is multiplied by.
The result of the multiplication is the public key `P` (another point on the curve).
Multiplication of a point by a number has a very special definition in EC cryptography.
See this [this guide](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/) for details.

### Key strength

Before deriving the public key, private key is subject to modulo `l`,
where `l` is the maximum scalar allowed by the [edwards25519 curve](../../cryptography/asymmetric/edwards25519.md).

The `l` is on the order of 2^252, so the effective key strength is technically 252 bits, not 256 bits.
This is standard for EC cryptography and is more of a cosmetic nuance than any concern.

## Encoding

In user-facing contexts, the private key integer is:
 
1. Taken modulo `l` to avoid malleability
2. Put as array of 32 bytes in a [little-endian](https://en.wikipedia.org/wiki/Endianness#Little) direction (the first byte is the least significant)
3. Converted to hexadecimal form, like: `b3588a87056fb21dc4d052d59e83b54293882e646b543c29478e4cf45c28a402`

## Private spend key

Private spend key is used to spend moneros.
 
More specifically, it is used to build one-time private keys which allow to spend related outputs.

## Private view key

Private view key is used to recognize your incoming transactions on the otherwise opaque blockchain.

## One-time private keys

One-time private key like construct is used in [stealth addresses](https://monero.stackexchange.com/questions/1409/constructing-a-stealth-monero-address).

---

## File: docs/en/cryptography/asymmetric/public-key.md

---
title: Public Keys in Monero
---
# Public Keys in Monero

!!! note
    Author is nowhere close to being a cryptographer. Be sceptical on accuracy.

Public key is deterministically derived from private key based on [edwards25519 curve](../../cryptography/asymmetric/edwards25519.md) with a little Monero-specific twist.

Public key is meant to be shared. Assuming correct implementation, it is not practically possible to recover private key from public key. 

Public key is a **point (x,y)** on the elliptic curve.

In equations points are represented by **uppercase letters**.

In user-facing contexts, public key is encoded in a [little-endian](https://en.wikipedia.org/wiki/Endianness#Little) hexadecimal form, like:
`016a941812293cf9a86071060fb090ab38d67945e659968cb8cf30e1bc725683` 

## Deriving public key

Say:

* P is a public key
* x is a private key
* G is a "base point"; this is simply a constant specific to [edwards25519](../../cryptography/asymmetric/edwards25519.md); this point lies on the elliptic curve
 
Then:

    P = xG

The public key is simply the base point (G) multiplied by the private key (x).
Multiplying the point is adding the point to itself a number of times.

However, the addition is **not** a simple vector addition. It has a very specific
definition nicely described in [this article](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/).
What is important is that result of addition is always a point on the curve.
For example, G + G is another point on the curve.

## Use cases

[Monero address](../../public-address/standard-address.md) is composed of public spend key and public view key.
These keys are used to build stealth addresses to receive payments.

---

## File: docs/en/cryptography/base58.md

---
title: Base58
---
# Base58

Base58 is a binary-to-text encoding scheme. It is similar to Base64 but has been modified to avoid both non-alphanumeric characters and letters which might look ambiguous when printed. The characters excluded in relation to Base64 are: `IOl0+/`

Base58 does not strictly specify the format. This results in some implementations being incompatible with others, for example with regard to alphabet order.

For details, see [Wikipedia](https://en.wikipedia.org/wiki/Base58).

## Base58 in Monero

Monero has its own variant of Base58.

In Monero the Base58 encoding is performed in 8-byte blocks, except the last block which is the remaining (8 or less) bytes.

The 8-byte block converts to 11 or less Base58 characters. If the block converted to less than 11 characters, the output is padded with "1"s (0 in Base58). The final block is padded as well to whatever would be the maximum size of this number of bytes encoded in Base58.

The advantage of Monero implementation is that output is of a fixed size which is not the case with plain Base58. The disadvantage is that default libraries won't work.

For details, see the [reference C++ Base58](https://github.com/monero-project/monero/blob/master/src/common/base58.cpp) implementation and the unofficial [Python](https://github.com/bigreddmachine/MoneroPy/blob/master/moneropy/base58.py) and [Rust](https://github.com/monero-oxide/monero-oxide/blob/main/monero-oxide/wallet/base58/src/lib.rs) implementations.

---

## File: docs/en/cryptography/index.md

---
title: Cryptography in Monero
---
# Cryptography in Monero 

Monero uses a wide variety of cryptographic primitives for various use cases.

Comparing to altcoins, Monero cryptography is considered conservative, sound and robust.

Comparing to Bitcoin, Monero uses much more primitives, and some of them are more advanced, especially those related to privacy and Proof of Work.
Some choices are deliberately non-standard (for better or worse) - oftentimes a legacy of the CryptoNote protocol.

---

## File: docs/en/cryptography/keccak-256.md

---
title: Keccak-256 Hash Function
---
# Keccak-256 Hash Function

Monero employs Keccak as a hashing function. In most context specifically Keccak-256 is used,
providing 32-byte hashes.

Keccak is the leading hashing function, designed by non-NSA designers.
Keccak won [NIST competition](https://en.wikipedia.org/wiki/NIST_hash_function_competition) to become the official SHA3.

## Use Cases

Monero does **not** employ Keccak for Proof-of-Work. Instead, Keccak is used for:
   
* random number generator
* block hashing
* transaction hashing
* stealth address private key image (for double spend protection)
* public address checksum
* RingCT
* multisig
* bulletproofs

...and likely a few other things.

## Keccak-256 vs SHA3-256

SHA3-256 is Keccak-256, except that NIST changed the padding.
For this reason, the original Keccak-256 gives a different hash value than NIST SHA3-256.  

Monero uses original Keccak-256.
The NIST standard was only published on August 2015, while Monero went live on 18 April 2014.  

## Reference

* [Keccak source code used in Monero](https://github.com/monero-project/monero/blob/5c2dfe157b48a486eb2b92dcf8789b3b1eb20f60/src/crypto/keccak.c)
* [SHA3 on Wikipedia](https://en.wikipedia.org/wiki/SHA-3)
* [Keccak-256 vs SHA3-256](https://ethereum.stackexchange.com/questions/550/which-cryptographic-hash-function-does-ethereum-use) explained on Ethereum stackexchange
* [Online tool to calculate Keccak-256 and SHA3-256](https://emn178.github.io/online-tools/keccak_256.html)