{"id":18714808,"url":"https://github.com/ph4r05/monero-agent","last_synced_at":"2025-04-12T13:06:15.376Z","repository":{"id":57442873,"uuid":"126215119","full_name":"ph4r05/monero-agent","owner":"ph4r05","description":"Monero hardware wallet protocol implementation for Trezor, agent","archived":false,"fork":false,"pushed_at":"2022-09-23T22:53:44.000Z","size":16225,"stargazers_count":24,"open_issues_count":1,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-06T18:16:13.540Z","etag":null,"topics":["borromean","bulletproofs","cryptonote","ed25519","hardware-wallet","key-image-sync","monero","monero-agent","offloading","protocol","python","ringct","transaction-signer","trezor","trezor-crypto","trezor-monero"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ph4r05.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-21T17:18:21.000Z","updated_at":"2024-11-03T01:07:25.000Z","dependencies_parsed_at":"2022-09-04T23:00:36.794Z","dependency_job_id":null,"html_url":"https://github.com/ph4r05/monero-agent","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph4r05%2Fmonero-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph4r05%2Fmonero-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph4r05%2Fmonero-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ph4r05%2Fmonero-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ph4r05","download_url":"https://codeload.github.com/ph4r05/monero-agent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223518559,"owners_count":17158689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["borromean","bulletproofs","cryptonote","ed25519","hardware-wallet","key-image-sync","monero","monero-agent","offloading","protocol","python","ringct","transaction-signer","trezor","trezor-crypto","trezor-monero"],"created_at":"2024-11-07T13:06:23.909Z","updated_at":"2024-11-07T13:06:24.634Z","avatar_url":"https://github.com/ph4r05.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Monero Wallet Python implementation\n\n[![Build Status](https://travis-ci.org/ph4r05/monero-agent.svg?branch=master)](https://travis-ci.org/ph4r05/monero-agent)\n\nPure-python Monero Wallet implementation in Python3.\n\nImplements transaction signing protocol designed for Trezor hardware wallet as described in [monero-trezor-doc].\n\nThe main purpose of this repo is to provide host side (agent) for the transaction signing with the Trezor hardware wallet.\nThe repo also contains the initial implementation for the Trezor side. The Trezor protocol side underwent heavy refactoring\nand is about to be merged to the [trezor-core] repository.\n\nThe repo provides integration tests for Trezor wallet transaction signing.\n\n- PR adding Monero support to the Trezor hardware wallet (client side of the signing protocol): https://github.com/trezor/trezor-core/pull/293\n- PR adding Trezor hardware support to official Monero codebase: https://github.com/monero-project/monero/pull/4241\n\n\n## Supported features\n\n - Full RingCT (one UTXO)\n - Simple RingCT (more than 1 UTXOs)\n - Sub-addresses\n - Key image sync\n - Bulletproofs (batch verification, signing, ready for v9 fork)\n - Ledger protocol implementation, HW wallet side\n\n## Roadmap\n\n - Spend proof\n - Reserver proof\n - Multisig\n - Wallet implementation (funds receiving, UTXO mixing)\n - Ledger protocol implementation, host side\n\n## Protocol\n\nIn order to support RingCT on hardware wallet with limited resources a subdivided protocol had to be implemented.\nIt is not feasible to process the signed transaction in one run on the hardware wallet with tens of UTXOs and multiple outputs.\n\nThe introduction to the topic is described here:\n\nhttps://github.com/ph4r05/monero-trezor-doc\n\nThe documentation can be out of sync from the code. Take this source code as a primary reference.\n\nIn the current protocol it is assumed there may be multiple input UTXO (tens to hundreds). So it is optimized\nto work incrementally, one UTXO at a time. This is reasonable to assume as your funds may be scattered over\nmany small transactions. On the other hand we assume the number of outputs is relatively small (small units) as\nit usually is in the Monero transactions.\n\nIt is quite easy to extend protocol to work with large amounts of outputs but due to the message structure\nwhich is later signed it will be needed to add two more roundrips with sending output related data one by one\nto the Trezor for incremental hashing.\n\nOutputs are pinned in the beginning of the protocol - number of outputs is fixed at this point in the Trezor\nand HMAC with unique key (index dependent) is generated for each output. So in further roundtrips it is assured only\npreviously pinned outputs in the exact given order are processed. The same principle is used for each data produced by\nthe Trezor which are later used as inputs.\n\n## Project structure\n\nAgent \u003c-\u003e Trezor\n\nAgent is an object supposed to run on the host PC where Trezor is the HW wallet implementation.\n`agent.py` and `trezor.py` are mainly ports of the C++ code to the Python for PoC, experimentation and testing.\nThese versions are not optimized for usage in HW environment.\n\nOptimized versions are `agent_lite.py` and `trezor_lite.py`.\n\nCurrently, the agent functionality is used just for testing and as a PoC. \nThe Trezor support has been integrated to the official \nMonero [CLI](https://github.com/monero-project/monero) and \n[GUI](https://github.com/monero-project/monero-gui) wallets.\n\n## Serialize lib\n\nThe project depends on my `monero-serialize` library.\nData objects used in the Monero are defined there, it supports serialization / deserialization to binary format.\nThe serialized binary messages are hashed during the transaction signature.\n\nhttps://github.com/ph4r05/monero-serialize\n\n## Crypto\n\nMonero uses Ed25519 elliptic curve. The pure-python implementation is not optimized to avoid side-channel leaks (e.g., timing)\nas it serves mainly as PoC.\n\nThe project uses Ed25519 implementation which\nworks in extended Edwards coordinates `(x, y, z, t)`.\n\nThe only code directly handling point representation is `crypto.py`. All other objects are using `crypto.py`\nto do the EC computation. Point representation is opaque to the other modules.\n\nThe opaque point representation can be converted to bytearray representation suitable for transport\n(compressed, y-coordinate + sign flag) using `crypto.encodepoint()` and `crypto.decodepoint()`.\n\nScalars are represented as integers (no encoding / decoding is needed). However, we are working in modular ring so\nfor scalar operations such as addition, division, comparison use the `crypto.sc_*` methods.\n\n## Trezor-crypto\n\nAdditionally to pure-python crypto backend, there is a production-ready `trezor-crypto` backend.\nI implemented required Monero-related cryptographic algorithms to the [trezor-crypto] (TCRY).\nTCRY implements constant-time curve operations, uses [libsodium] to generate random values.\nBorromean Range proof was reimplemented in C for CPU and memory efficiency.\n\nI created a python binding [py-trezor-crypto] which can be installed from pip. The pip builds [trezor-crypto]\nlibrary. Please refer to the readme of the [py-trezor-crypto] for installation details (dependencies).\n\nTo install python bindings with agent run:\n\n```bash\npip install -U --no-cache 'monero_agent[tcry]'\n\n# Or laternativelly\npip install -U --no-cache py_trezor_crypto_ph4 \n```\n\nDependencies:\n\n- libsodium\n- pkg-config\n- gcc\n- python-dev\n\n\nTravis tests with both crypto backends. In order to test with TCRY install all its dependencies. `libsodium` is the only one\ndependency for the shared lib. For more info take a look at `travis-install-libtrezor-crypto.sh`.\n\nCrypto dependency is selected based on the `EC_BACKEND` env var. `0` is for Python backend, `1` for TCRY.\nPath to the TCRY is specified via `LIBTREZOR_CRYPTO_PATH` env var. If the TCRY is not found or could not be loaded\nthe code fallbacks to python backend. This behaviour can be changed by setting `EC_BACKEND_FORCE` env var to `1`.\n\nTCRY is also 20 times faster (unit tests).\n\n```bash\n$\u003e EC_BACKEND_FORCE=1 EC_BACKEND=0  ./venv/bin/python -m unittest monero_glue_test/test_*.py\n...s................................................................\n----------------------------------------------------------------------\nRan 68 tests in 416.823s\n\nOK\n```\n\nTCRY backend:\n\n```bash\n$\u003e  EC_BACKEND_FORCE=1 EC_BACKEND=1  ./venv/bin/python -m unittest monero_glue_test/test_*.py\n....................................................................\n----------------------------------------------------------------------\nRan 68 tests in 84.057s\n\nOK\n```\n\n## Testing with Trezor\n\n```bash\npip3 install -U --no-cache monero-agent py_trezor_crypto_ph4 \npython3 -m unittest trezor_monero_test.test_trezor\n\n# To test only one transaction:\nTREZOR_TEST_ONLY_TX=1 TREZOR_TEST_NUM_TX=1 python3 -m unittest trezor_monero_test.test_trezor\n\n# To test with interactive Trezor prompts:\nTREZOR_TEST_INTERACTIVE=1 TREZOR_TEST_ONLY_TX=1 TREZOR_TEST_NUM_TX=1 python3 -m unittest trezor_monero_test.test_trezor\n\n# Note: if testing with local py files, use trezor_monero_test/test_trezor.py\n```\n\n## More on using the repo\n\nPlease refer to the [PoC.md](PoC.md) for more usage examples.\n\n### Memory considerations\n\nPython uses arbitrary precision integers with a memory overhead.\nThe following command shows the amount of memory required for certain data types and sizes:\n\n```python\n\u003e\u003e\u003e sys.getsizeof(0)\n24\n\u003e\u003e\u003e sys.getsizeof(2**32-1)  # 4B num\n32\n\u003e\u003e\u003e sys.getsizeof(2**64-1)  # 8B num\n36\n\u003e\u003e\u003e sys.getsizeof(2**256-1)  # 32B num\n60\n\u003e\u003e\u003e sys.getsizeof(b'\\x00'*32)  # 32B hex\n65\n\u003e\u003e\u003e sys.getsizeof(b'\\x00'*64)  # 64B hex\n97\n```\n\nMonero works in EC with 32 B numbers.\nTo store a 32 B number it takes 60 B in integer representation and 65 B in the byte string encoded\nrepresentation (some ed25519 libraries and mininero use this representation).\nFor scalars it is apparently more effective to store integers naturally, saving both memory and CPU cycles with recoding.\n\nEC point arithmetics can use classic point coordinates `(x, y)` or extended Edwards point coordinates `(x,y,z,t)`.\nIt takes 64 and 80 B to store tuple of 2 and 4 elements respectively.\nIt thus take 184 B and 320 B to store an EC point in the natural form compared to the 65 B byte representation.\n\n# Donations\nThanks for your support!\n\nMonero donation address:\n```\n88np3NiHwTVDZCNAZWth856ZwriMpp3iRBoAEy4yGWpR17eqqtQYs1RiwcWZexg8Wa8x143p2pu8LWJ7qYutJHjhTQB8gC1\n```\n\n# Internal notes\n\n- Signing client version 3 is not yet implemented. Subaddr index is needed for each UTXO. \n- CLSAG algorithm is implemented, but not yet used in the signing client\n\n# Related projects\n\n- [monero-trezor-doc] - Technical report describing the integration design\n- [monero-serialize] - Monero serialization library\n- [trezor-crypto] - Trezor crypto library, low-level crypto functions\n- [py-trezor-crypto] - Python binding for Trezor Crypto\n- [py-cryptonight] - Python binding for Cryptonight hash function\n- [trezor-firmware] - Trezor firmware monorepository, contains whole firmware, with Monero integration\n- [trezor-core] - Deprecated Trezor core repo (now included in monorepo)\n- [trezor-crypto] - Deprecated Trezor crypto repo with low-level crypto functions (now included in monorepo)\n- [trezor-common] - Deprecated Trezor common repo with protobuf messages and common artifacts (now included in monorepo)\n\n\n[trezor-firmware]: https://github.com/ph4r05/trezor-firmware\n[trezor-core]: https://github.com/ph4r05/trezor-core\n[trezor-crypto]: https://github.com/ph4r05/trezor-crypto\n[trezor-common]: https://github.com/ph4r05/trezor-common\n[libsodium]: https://github.com/jedisct1/libsodium\n[py-trezor-crypto]: https://github.com/ph4r05/py-trezor-crypto\n[py-cryptonight]: https://github.com/ph4r05/py-cryptonight\n[monero-serialize]: https://github.com/ph4r05/monero-serialize\n[monero-trezor-doc]: https://github.com/ph4r05/monero-trezor-doc\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fph4r05%2Fmonero-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fph4r05%2Fmonero-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fph4r05%2Fmonero-agent/lists"}