├── .gitignore ├── .travis.yml ├── JIT.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── pycryptonight ├── __init__.py └── tests │ ├── __init__.py │ ├── data │ ├── tests-fast.txt │ ├── tests-slow-1.txt │ ├── tests-slow-2.txt │ ├── tests-slow-4.txt │ └── tests-slow.txt │ └── test.py ├── setup.cfg ├── setup.py ├── src ├── cryptonight │ ├── CryptonightR_JIT.cpp │ ├── CryptonightR_JIT.h │ ├── CryptonightR_JIT_x86_64.c │ ├── CryptonightR_base.h │ ├── CryptonightR_template.S │ ├── CryptonightR_template.cpp │ ├── CryptonightR_template.h │ ├── aesb.cpp │ ├── blake256.cpp │ ├── blake256.h │ ├── c_threads.h │ ├── duration.h │ ├── ea_config.h │ ├── easylogging++.cc │ ├── easylogging++.h │ ├── epee_warnings.h │ ├── generic-ops.h │ ├── groestl.cpp │ ├── groestl.h │ ├── groestl_tables.h │ ├── hash-extra-blake.cpp │ ├── hash-extra-groestl.cpp │ ├── hash-extra-jh.cpp │ ├── hash-extra-skein.cpp │ ├── hash-ops.h │ ├── hash.cpp │ ├── hash.h │ ├── hmac-keccak.c │ ├── hmac-keccak.h │ ├── initializer.h │ ├── int-util.h │ ├── jh.cpp │ ├── jh.h │ ├── keccak.cpp │ ├── keccak.h │ ├── memwipe.cpp │ ├── memwipe.h │ ├── misc_log_ex.h │ ├── mlog.cpp │ ├── oaes_config.h │ ├── oaes_lib.cpp │ ├── oaes_lib.h │ ├── random.c │ ├── random.h │ ├── randomx.h │ ├── rx-slow-hash.cpp │ ├── skein.cpp │ ├── skein.h │ ├── skein_port.h │ ├── slow-hash.cpp │ ├── tree-hash.c │ ├── variant2_int_sqrt.h │ ├── variant4_random_math.h │ └── warnings.h ├── misc │ ├── getopt.h │ └── unistd.h ├── pycryptonight.cpp ├── pycryptonight.h └── randomx │ ├── aes_hash.cpp │ ├── aes_hash.hpp │ ├── allocator.cpp │ ├── allocator.hpp │ ├── argon2.h │ ├── argon2_avx2.cpp │ ├── argon2_core.cpp │ ├── argon2_core.h │ ├── argon2_ref.cpp │ ├── argon2_ssse3.cpp │ ├── asm │ ├── configuration.asm │ ├── program_epilogue_linux.inc │ ├── program_epilogue_store.inc │ ├── program_epilogue_win64.inc │ ├── program_loop_load.inc │ ├── program_loop_store.inc │ ├── program_prologue_linux.inc │ ├── program_prologue_win64.inc │ ├── program_read_dataset.inc │ ├── program_read_dataset_sshash_fin.inc │ ├── program_read_dataset_sshash_init.inc │ ├── program_sshash_constants.inc │ ├── program_sshash_load.inc │ ├── program_sshash_prefetch.inc │ ├── program_xmm_constants.inc │ └── randomx_reciprocal.inc │ ├── assembly_generator_x86.cpp │ ├── assembly_generator_x86.hpp │ ├── blake2 │ ├── blake2-impl.h │ ├── blake2.h │ ├── blake2b.cpp │ ├── blamka-round-avx2.h │ ├── blamka-round-ref.h │ ├── blamka-round-ssse3.h │ └── endian.h │ ├── blake2_generator.cpp │ ├── blake2_generator.hpp │ ├── bytecode_machine.cpp │ ├── bytecode_machine.hpp │ ├── common.hpp │ ├── configuration.h │ ├── cpu.cpp │ ├── cpu.hpp │ ├── dataset.cpp │ ├── dataset.hpp │ ├── instruction.cpp │ ├── instruction.hpp │ ├── instruction_weights.hpp │ ├── instructions_portable.cpp │ ├── intrin_portable.h │ ├── jit_compiler.hpp │ ├── jit_compiler_a64.cpp │ ├── jit_compiler_a64.hpp │ ├── jit_compiler_a64_static.S │ ├── jit_compiler_a64_static.hpp │ ├── jit_compiler_fallback.hpp │ ├── jit_compiler_x86.cpp │ ├── jit_compiler_x86.hpp │ ├── jit_compiler_x86_static.S │ ├── jit_compiler_x86_static.asm │ ├── jit_compiler_x86_static.hpp │ ├── program.hpp │ ├── randomx.cpp │ ├── randomx.h │ ├── reciprocal.cpp │ ├── reciprocal.h │ ├── soft_aes.cpp │ ├── soft_aes.h │ ├── superscalar.cpp │ ├── superscalar.hpp │ ├── superscalar_program.hpp │ ├── tests │ ├── affinity.cpp │ ├── affinity.hpp │ ├── api-example1.c │ ├── api-example2.cpp │ ├── benchmark.cpp │ └── code-generator.cpp │ ├── virtual_machine.cpp │ ├── virtual_machine.hpp │ ├── virtual_memory.cpp │ ├── virtual_memory.h │ ├── vm_compiled.cpp │ ├── vm_compiled.hpp │ ├── vm_compiled_light.cpp │ ├── vm_compiled_light.hpp │ ├── vm_interpreted.cpp │ ├── vm_interpreted.hpp │ ├── vm_interpreted_light.cpp │ └── vm_interpreted_light.hpp ├── test-travis.sh ├── test.sh └── tools └── convert_s_to_c.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | # Idea 92 | .idea 93 | 94 | alembic.ini 95 | *.o 96 | build/ 97 | venv2/ 98 | *.egg-info 99 | cmake-build-* 100 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.5" 5 | - "3.6" 6 | - "pypy" 7 | - "pypy3" 8 | install: 9 | - pip install . 10 | script: 11 | - PYTHONPATH=.:$PYTHONPATH ./test-travis.sh 12 | 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017, Dusan Klinec 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE 3 | include *.sh 4 | include *.md 5 | include src/* 6 | include src/cryptonight/* 7 | include src/misc/* 8 | include pycryptonight/tests/data/* 9 | graft src 10 | graft src/cryptonight 11 | graft src/misc 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python CryptoNight implementation 2 | 3 | [![Build Status](https://travis-ci.org/ph4r05/py-cryptonight.svg?branch=master)](https://travis-ci.org/ph4r05/py-cryptonight) 4 | 5 | Python binding for Monero hash functions `cn_fast_hash`, `cn_slow_hash`. 6 | 7 | - `cn_fast_hash` is used mainly for hashing to scalars / EC points. 8 | - `cn_slow_hash` is CryptoNight hash function used for mining and encryption key derivation for encrypted wallet 9 | files. 10 | - Supports CNv1, CNv2, CNv4 11 | - JIT tested on OSX + LLVM, experimental 12 | 13 | Py2, Py3 compatible + tests with Monero test vectors. 14 | 15 | ``` 16 | pip install py-cryptonight 17 | ``` 18 | 19 | ## Usage 20 | 21 | ```python 22 | import binascii 23 | import pycryptonight 24 | 25 | pycryptonight.cn_fast_hash(b'1') 26 | # hexcoded: b'c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6 27 | 28 | pycryptonight.cn_slow_hash(b'1') 29 | # hexcoded: b'cbdfba46388e040422b4a9daa471726be659ae184ee86420c2795647f0b301d5 30 | 31 | # variant 1: 32 | pycryptonight.cn_slow_hash(binascii.unhexlify(b'38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb'), 1) # variant 1 33 | # hexcoded: b'ed082e49dbd5bbe34a3726a0d1dad981146062b39d36d62c71eb1ed8ab49459b 34 | 35 | # variant 2: 36 | pycryptonight.cn_slow_hash(b'1', 2) # variant 2 37 | # hexcoded: b'44016d2376838d89b374e99a20118c0e8916e8c0a5b910744efc7d8f426509ca 38 | 39 | # variant 4: 40 | pycryptonight.cn_slow_hash(b'1', 4) # variant 4 41 | # hexcoded: b'97db7e03629f7c17e4d78b36a2d247d226b88a8df6cf69f2e4cdae1f1b706b4a 42 | 43 | # variant 4, height: 44 | pycryptonight.cn_slow_hash(b'1', 4, prehashed=0, height=1) # variant 4, height 1 45 | # hexcoded: b'09bcf4997132dc3d7980125620724acc9c90dc393cb6694097a7d745c57b6b5b 46 | ``` 47 | 48 | ## Build problems 49 | 50 | The extension builds with AES extension by default. To disable this, rebuild with: 51 | 52 | ```bash 53 | MONERO_NO_AES=1 python setup.py install 54 | ``` 55 | 56 | ### JIT 57 | 58 | The JIT optimization is disabled by default as the implementation was not properly tested. 59 | If you want to experiment with JIT you need to compile with: 60 | 61 | ```bash 62 | MONERO_NO_JIT=0 python setup.py install 63 | MONERO_USE_CNV4_JIT=1 ./test.sh 64 | ``` 65 | 66 | To rebuild locally and test: 67 | 68 | ```bash 69 | MONERO_NO_AES=0 MONERO_NO_JIT=0 python setup.py develop 70 | MONERO_USE_CNV4_JIT=0 ./test.sh # JIT disabled 71 | MONERO_USE_CNV4_JIT=1 ./test.sh # JIT enabled 72 | ``` 73 | 74 | For more info read [JIT.md](JIT.md) 75 | 76 | ## Donations 77 | Thanks for your support! 78 | 79 | ``` 80 | 86SgqL4YwtWBgq65CitxbPC5ChUJrDkTVWJgtenuf6S68GTLWqPh3zydYpoFhr8JyVdWEZmoMMnhjdvoKQ9urZFfCXKmD93 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /pycryptonight/__init__.py: -------------------------------------------------------------------------------- 1 | from _pycryptonight import cn_fast_hash, cn_slow_hash 2 | 3 | -------------------------------------------------------------------------------- /pycryptonight/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ph4r05/py-cryptonight/64debe709969b941b1a382439615e9e311ba12c7/pycryptonight/tests/__init__.py -------------------------------------------------------------------------------- /pycryptonight/tests/data/tests-slow-1.txt: -------------------------------------------------------------------------------- 1 | b5a7f63abb94d07d1a6445c36c07c7e8327fe61b1647e391b4c7edae5de57a3d 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 2 | 80563c40ed46575a9e44820d93ee095e2851aa22483fd67837118c6cd951ba61 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 3 | 5bb40c5880cef2f739bdb6aaaf16161eaae55530e7b10d7ea996b751a299e949 8519e039172b0d70e5ca7b3383d6b3167315a422747b73f019cf9528f0fde341fd0f2a63030ba6450525cf6de31837669af6f1df8131faf50aaab8d3a7405589 4 | 613e638505ba1fd05f428d5c9f8e08f8165614342dac419adc6a47dce257eb3e 37a636d7dafdf259b7287eddca2f58099e98619d2f99bdb8969d7b14498102cc065201c8be90bd777323f449848b215d2977c92c4c1c2da36ab46b2e389689ed97c18fec08cd3b03235c5e4c62a37ad88c7b67932495a71090e85dd4020a9300 5 | ed082e49dbd5bbe34a3726a0d1dad981146062b39d36d62c71eb1ed8ab49459b 38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb 6 | -------------------------------------------------------------------------------- /pycryptonight/tests/data/tests-slow-2.txt: -------------------------------------------------------------------------------- 1 | 353fdc068fd47b03c04b9431e005e00b68c2168a3cc7335c8b9b308156591a4f 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 2 | 72f134fc50880c330fe65a2cb7896d59b2e708a0221c6a9da3f69b3a702d8682 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 3 | 410919660ec540fc49d8695ff01f974226a2a28dbbac82949c12f541b9a62d2f 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 4 | 4472fecfeb371e8b7942ce0378c0ba5e6d0c6361b669c587807365c787ae652d 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 5 | 577568395203f1f1225f2982b637f7d5e61b47a0f546ba16d46020b471b74076 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 6 | f6fd7efe95a5c6c4bb46d9b429e3faf65b1ce439e116742d42b928e61de52385 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 7 | 422f8cfe8060cf6c3d9fd66f68e3c9977adb683aea2788029308bbe9bc50d728 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 8 | 512e62c8c8c833cfbd9d361442cb00d63c0a3fd8964cfd2fedc17c7c25ec2d4b 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 9 | 12a794c1aa13d561c9c6111cee631ca9d0a321718d67d3416add9de1693ba41e 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 10 | 2659ff95fc74b6215c1dc741e85b7a9710101b30620212f80eb59c3c55993f9d 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 11 | -------------------------------------------------------------------------------- /pycryptonight/tests/data/tests-slow-4.txt: -------------------------------------------------------------------------------- 1 | f759588ad57e758467295443a9bd71490abff8e9dad1b95b6bf2f5d0d78387bc 5468697320697320612074657374205468697320697320612074657374205468697320697320612074657374 1806260 2 | 5bb833deca2bdd7252a9ccd7b4ce0b6a4854515794b56c207262f7a5b9bdb566 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e67 1806261 3 | 1ee6728da60fbd8d7d55b2b1ade487a3cf52a2c3ac6f520db12c27d8921f6cab 656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f7265 1806262 4 | 6969fe2ddfb758438d48049f302fc2108a4fcc93e37669170e6db4b0b9b4c4cb 657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c 1806263 5 | 7f3048b4e90d0cbe7a57c0394f37338a01fae3adfdc0e5126d863a895eb04e02 71756973206e6f737472756420657865726369746174696f6e20756c6c616d636f206c61626f726973206e697369 1806264 6 | 1d290443a4b542af04a82f6b2494a6ee7f20f2754c58e0849032483a56e8e2ef 757420616c697175697020657820656120636f6d6d6f646f20636f6e7365717561742e20447569732061757465 1806265 7 | c43cc6567436a86afbd6aa9eaa7c276e9806830334b614b2bee23cc76634f6fd 697275726520646f6c6f7220696e20726570726568656e646572697420696e20766f6c7570746174652076656c6974 1806266 8 | 87be2479c0c4e8edfdfaa5603e93f4265b3f8224c1c5946feb424819d18990a4 657373652063696c6c756d20646f6c6f726520657520667567696174206e756c6c612070617269617475722e 1806267 9 | dd9d6a6d8e47465cceac0877ef889b93e7eba979557e3935d7f86dce11b070f3 4578636570746575722073696e74206f6363616563617420637570696461746174206e6f6e2070726f6964656e742c 1806268 10 | 75c6f2ae49a20521de97285b431e717125847fb8935ed84a61e7f8d36a2c3d8e 73756e7420696e2063756c706120717569206f666669636961206465736572756e74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e 1806269 11 | -------------------------------------------------------------------------------- /pycryptonight/tests/data/tests-slow.txt: -------------------------------------------------------------------------------- 1 | 2f8e3df40bd11f9ac90c743ca8e32bb391da4fb98612aa3b6cdc639ee00b31f5 6465206f6d6e69627573206475626974616e64756d 2 | 722fa8ccd594d40e4a41f3822734304c8d5eff7e1b528408e2229da38ba553c4 6162756e64616e732063617574656c61206e6f6e206e6f636574 3 | bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87 63617665617420656d70746f72 4 | b1257de4efc5ce28c6b40ceb1c6c8f812a64634eb3e81c5220bee9b2b76a6f05 6578206e6968696c6f206e6968696c20666974 5 | -------------------------------------------------------------------------------- /pycryptonight/tests/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import random 5 | import binascii 6 | import unittest 7 | import pkg_resources 8 | import pycryptonight 9 | 10 | __author__ = 'dusanklinec' 11 | 12 | 13 | class PyCryptoNightTest(unittest.TestCase): 14 | 15 | def test_fast(self): 16 | self.tst_method('tests-fast.txt', lambda x, y: pycryptonight.cn_fast_hash(x)) 17 | 18 | def test_slow(self): 19 | self.tst_method('tests-slow.txt', lambda x, y: pycryptonight.cn_slow_hash(x, 0, 0, 0)) 20 | 21 | def test_slow1(self): 22 | self.tst_method('tests-slow-1.txt', lambda x, y: pycryptonight.cn_slow_hash(x, 1, 0, 0)) 23 | 24 | def test_slow2(self): 25 | self.tst_method('tests-slow-2.txt', lambda x, y: pycryptonight.cn_slow_hash(x, 2, 0, 0)) 26 | 27 | def test_slow4(self): 28 | self.tst_method('tests-slow-4.txt', lambda x, y: pycryptonight.cn_slow_hash(x, 4, 0, y)) 29 | 30 | def tst_method(self, fname, fnc): 31 | with pkg_resources.resource_stream(__name__, os.path.join('data', fname)) as data_file: 32 | for idx, line in enumerate(data_file): 33 | line = line.strip() 34 | if not line: 35 | continue 36 | 37 | height = 0 38 | expected, inp = line[:64], line[65:] 39 | if b' ' in inp: 40 | inp, height = inp.split(b' ') 41 | height = int(height) 42 | 43 | res = fnc(binascii.unhexlify(inp), height) 44 | self.assertEqual(binascii.unhexlify(expected), res) 45 | 46 | 47 | if __name__ == "__main__": 48 | unittest.main() # pragma: no cover 49 | 50 | 51 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | 3 | -------------------------------------------------------------------------------- /src/cryptonight/CryptonightR_JIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #if !(defined(_MSC_VER) || defined(__MINGW32__)) 8 | #include 9 | #endif 10 | 11 | #if defined(__cplusplus) 12 | extern "C" 13 | { 14 | #endif 15 | 16 | #include "int-util.h" 17 | #include "hash-ops.h" 18 | #include "variant4_random_math.h" 19 | #include "CryptonightR_JIT.h" 20 | #include "CryptonightR_template.h" 21 | 22 | static const uint8_t prologue[] = { 23 | #if defined __i386 || defined __x86_64__ 24 | 0x4C, 0x8B, 0xD7, // mov r10, rdi 25 | 0x53, // push rbx 26 | 0x55, // push rbp 27 | 0x41, 0x57, // push r15 28 | 0x4C, 0x8B, 0xDC, // mov r11, rsp 29 | 0x41, 0x8B, 0x1A, // mov ebx, DWORD PTR [r10] 30 | 0x41, 0x8B, 0x72, 0x04, // mov esi, DWORD PTR [r10+4] 31 | 0x41, 0x8B, 0x7A, 0x08, // mov edi, DWORD PTR [r10+8] 32 | 0x41, 0x8B, 0x6A, 0x0C, // mov ebp, DWORD PTR [r10+12] 33 | 0x41, 0x8B, 0x62, 0x10, // mov esp, DWORD PTR [r10+16] 34 | 0x45, 0x8B, 0x7A, 0x14, // mov r15d, DWORD PTR [r10+20] 35 | 0x41, 0x8B, 0x42, 0x18, // mov eax, DWORD PTR [r10+24] 36 | 0x41, 0x8B, 0x52, 0x1C, // mov edx, DWORD PTR [r10+28] 37 | 0x45, 0x8B, 0x4A, 0x20, // mov r9d, DWORD PTR [r10+32] 38 | #endif 39 | }; 40 | 41 | static const uint8_t epilogue[] = { 42 | #if defined __i386 || defined __x86_64__ 43 | 0x49, 0x8B, 0xE3, // mov rsp, r11 44 | 0x41, 0x89, 0x1A, // mov DWORD PTR [r10], ebx 45 | 0x41, 0x89, 0x72, 0x04, // mov DWORD PTR [r10+4], esi 46 | 0x41, 0x89, 0x7A, 0x08, // mov DWORD PTR [r10+8], edi 47 | 0x41, 0x89, 0x6A, 0x0C, // mov DWORD PTR [r10+12], ebp 48 | 0x41, 0x5F, // pop r15 49 | 0x5D, // pop rbp 50 | 0x5B, // pop rbx 51 | 0xC3, // ret 52 | #endif 53 | }; 54 | 55 | #define APPEND_CODE(src, size) \ 56 | do { \ 57 | if (JIT_code + (size) > JIT_code_end) \ 58 | return -1; \ 59 | memcpy(JIT_code, (src), (size)); \ 60 | JIT_code += (size); \ 61 | } while (0) 62 | 63 | int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size) 64 | { 65 | #if defined __i386 || defined __x86_64__ 66 | uint8_t* JIT_code = (uint8_t*) buf; 67 | const uint8_t* JIT_code_end = JIT_code + buf_size; 68 | 69 | #if !(defined(_MSC_VER) || defined(__MINGW32__)) 70 | if (mprotect((void*)buf, buf_size, PROT_READ | PROT_WRITE)) 71 | return -1; 72 | #endif 73 | 74 | APPEND_CODE(prologue, sizeof(prologue)); 75 | 76 | uint32_t prev_rot_src = 0xFFFFFFFFU; 77 | 78 | for (int i = 0;; ++i) 79 | { 80 | const struct V4_Instruction inst = code[i]; 81 | if (inst.opcode == RET) 82 | break; 83 | 84 | const uint8_t opcode = (inst.opcode == MUL) ? inst.opcode : (inst.opcode + 2); 85 | 86 | const uint32_t a = inst.dst_index; 87 | const uint32_t b = inst.src_index; 88 | const uint8_t c = opcode | (inst.dst_index << V4_OPCODE_BITS) | (((inst.src_index == 8) ? inst.dst_index : inst.src_index) << (V4_OPCODE_BITS + V4_DST_INDEX_BITS)); 89 | 90 | switch (inst.opcode) 91 | { 92 | case ROR: 93 | case ROL: 94 | if (b != prev_rot_src) 95 | { 96 | prev_rot_src = b; 97 | const uint8_t* p1 = (const uint8_t*) instructions_mov[c]; 98 | const uint8_t* p2 = (const uint8_t*) instructions_mov[c + 1]; 99 | APPEND_CODE(p1, p2 - p1); 100 | } 101 | break; 102 | } 103 | 104 | if (a == prev_rot_src) 105 | prev_rot_src = 0xFFFFFFFFU; 106 | 107 | const uint8_t* p1 = (const uint8_t*) instructions[c]; 108 | const uint8_t* p2 = (const uint8_t*) instructions[c + 1]; 109 | APPEND_CODE(p1, p2 - p1); 110 | 111 | if (inst.opcode == ADD) 112 | *(uint32_t*)(JIT_code - 4) = inst.C; 113 | } 114 | 115 | APPEND_CODE(epilogue, sizeof(epilogue)); 116 | 117 | #if !(defined(_MSC_VER) || defined(__MINGW32__)) 118 | if (mprotect((void*)buf, buf_size, PROT_READ | PROT_EXEC)) 119 | return -1; 120 | #endif 121 | 122 | __builtin___clear_cache((char*)buf, (char*)JIT_code); 123 | 124 | return 0; 125 | #else 126 | return -1; 127 | #endif 128 | } 129 | 130 | #if defined(__cplusplus) 131 | } 132 | #endif 133 | -------------------------------------------------------------------------------- /src/cryptonight/CryptonightR_JIT.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTONIGHTR_JIT_H 2 | #define CRYPTONIGHTR_JIT_H 3 | 4 | // Minimalistic JIT code generator for random math sequence in CryptonightR 5 | // 6 | // Usage: 7 | // - Allocate writable and executable memory 8 | // - Call v4_generate_JIT_code with "buf" pointed to memory allocated on previous step 9 | // - Call the generated code instead of "v4_random_math(code, r)", omit the "code" parameter 10 | 11 | typedef void (*v4_random_math_JIT_func)(uint32_t* r) 12 | #if defined __i386 || defined __x86_64__ 13 | __attribute__((sysv_abi)) 14 | #endif 15 | ; 16 | 17 | // Given the random math sequence, generates machine code (x86-64) for it 18 | // Returns 0 if code was generated successfully 19 | // Returns -1 if provided buffer was too small 20 | int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_func buf, const size_t buf_size); 21 | 22 | #endif // CRYPTONIGHTR_JIT_H 23 | -------------------------------------------------------------------------------- /src/cryptonight/CryptonightR_base.h: -------------------------------------------------------------------------------- 1 | #if defined(STATIC_JIT) && (!defined(__x86_64__) || defined(NO_JIT)) 2 | #undef STATIC_JIT 3 | #endif 4 | -------------------------------------------------------------------------------- /src/cryptonight/blake256.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #ifndef _BLAKE256_H_ 32 | #define _BLAKE256_H_ 33 | 34 | #include 35 | 36 | typedef struct { 37 | uint32_t h[8], s[4], t[2]; 38 | int buflen, nullt; 39 | uint8_t buf[64]; 40 | } state; 41 | 42 | typedef struct { 43 | state inner; 44 | state outer; 45 | } hmac_state; 46 | 47 | void blake256_init(state *); 48 | void blake224_init(state *); 49 | 50 | void blake256_update(state *, const uint8_t *, uint64_t); 51 | void blake224_update(state *, const uint8_t *, uint64_t); 52 | 53 | void blake256_final(state *, uint8_t *); 54 | void blake224_final(state *, uint8_t *); 55 | 56 | void blake256_hash(uint8_t *, const uint8_t *, uint64_t); 57 | void blake224_hash(uint8_t *, const uint8_t *, uint64_t); 58 | 59 | /* HMAC functions: */ 60 | 61 | void hmac_blake256_init(hmac_state *, const uint8_t *, uint64_t); 62 | void hmac_blake224_init(hmac_state *, const uint8_t *, uint64_t); 63 | 64 | void hmac_blake256_update(hmac_state *, const uint8_t *, uint64_t); 65 | void hmac_blake224_update(hmac_state *, const uint8_t *, uint64_t); 66 | 67 | void hmac_blake256_final(hmac_state *, uint8_t *); 68 | void hmac_blake224_final(hmac_state *, uint8_t *); 69 | 70 | void hmac_blake256_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 71 | void hmac_blake224_hash(uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint64_t); 72 | 73 | #endif /* _BLAKE256_H_ */ 74 | -------------------------------------------------------------------------------- /src/cryptonight/c_threads.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | /* Brain-dead simple portability wrapper over thread APIs for C */ 30 | #pragma once 31 | 32 | #ifdef _WIN32 33 | #include 34 | #define CTHR_MUTEX_TYPE HANDLE 35 | #define CTHR_MUTEX_INIT NULL 36 | #define CTHR_MUTEX_LOCK(x) do { if (x == NULL) { \ 37 | HANDLE p = CreateMutex(NULL, FALSE, NULL); \ 38 | if (InterlockedCompareExchangePointer((PVOID*)&x, (PVOID)p, NULL) != NULL) \ 39 | CloseHandle(p); \ 40 | } WaitForSingleObject(x, INFINITE); } while(0) 41 | #define CTHR_MUTEX_UNLOCK(x) ReleaseMutex(x) 42 | #define CTHR_THREAD_TYPE HANDLE 43 | #define CTHR_THREAD_RTYPE void 44 | #define CTHR_THREAD_RETURN return 45 | #define CTHR_THREAD_CREATE(thr, func, arg) thr = (HANDLE)_beginthread(func, 0, arg) 46 | #define CTHR_THREAD_JOIN(thr) WaitForSingleObject(thr, INFINITE) 47 | #else 48 | #include 49 | #define CTHR_MUTEX_TYPE pthread_mutex_t 50 | #define CTHR_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER 51 | #define CTHR_MUTEX_LOCK(x) pthread_mutex_lock(&x) 52 | #define CTHR_MUTEX_UNLOCK(x) pthread_mutex_unlock(&x) 53 | #define CTHR_THREAD_TYPE pthread_t 54 | #define CTHR_THREAD_RTYPE void * 55 | #define CTHR_THREAD_RETURN return NULL 56 | #define CTHR_THREAD_CREATE(thr, func, arg) pthread_create(&thr, NULL, func, arg) 57 | #define CTHR_THREAD_JOIN(thr) pthread_join(thr, NULL) 58 | #endif 59 | -------------------------------------------------------------------------------- /src/cryptonight/duration.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2022, The Monero Project 2 | 3 | // 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are 7 | // permitted provided that the following conditions are met: 8 | // 9 | // 1. Redistributions of source code must retain the above copyright notice, this list of 10 | // conditions and the following disclaimer. 11 | // 12 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | // of conditions and the following disclaimer in the documentation and/or other 14 | // materials provided with the distribution. 15 | // 16 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 17 | // used to endorse or promote products derived from this software without specific 18 | // prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 21 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 23 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 28 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #pragma once 31 | 32 | #include 33 | #include "crypto/crypto.h" 34 | 35 | namespace crypto 36 | { 37 | //! Generate poisson distributed values in discrete `D` time units. 38 | template 39 | struct random_poisson_duration 40 | { 41 | using result_type = D; //!< std::chrono::duration time unit precision 42 | using rep = typename result_type::rep; //!< Type used to represent duration value 43 | 44 | //! \param average for generated durations 45 | explicit random_poisson_duration(result_type average) 46 | : dist(average.count() < 0 ? 0 : average.count()) 47 | {} 48 | 49 | //! Generate a crypto-secure random duration 50 | result_type operator()() 51 | { 52 | crypto::random_device rand{}; 53 | return result_type{dist(rand)}; 54 | } 55 | 56 | private: 57 | std::poisson_distribution dist; 58 | }; 59 | 60 | /* A custom duration is used for subsecond precision because of the 61 | variance. If 5000 milliseconds is given, 95% of the values fall between 62 | 4859ms-5141ms in 1ms increments (not enough time variance). Providing 1/4 63 | seconds would yield 95% of the values between 3s-7.25s in 1/4s 64 | increments. */ 65 | 66 | //! Generate random durations with 1 second precision 67 | using random_poisson_seconds = random_poisson_duration; 68 | //! Generate random duration with 1/4 second precision 69 | using random_poisson_subseconds = 70 | random_poisson_duration>>; 71 | } 72 | -------------------------------------------------------------------------------- /src/cryptonight/ea_config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define ELPP_THREAD_SAFE 6 | #define ELPP_DEFAULT_LOG_FILE "" 7 | #define ELPP_DISABLE_DEFAULT_CRASH_HANDLING 8 | #define ELPP_NO_CHECK_MACROS 9 | #define ELPP_WINSOCK2 10 | #define ELPP_NO_DEBUG_MACROS 11 | #define ELPP_UTC_DATETIME 12 | 13 | #ifdef EASYLOGGING_CC 14 | #if !(!defined __GLIBC__ || !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__ || defined __NetBSD__) 15 | #define ELPP_FEATURE_CRASH_LOG 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/cryptonight/epee_warnings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(_MSC_VER) 4 | 5 | #define PUSH_WARNINGS __pragma(warning(push)) 6 | #define POP_WARNINGS __pragma(warning(pop)) 7 | #define DISABLE_VS_WARNINGS(w) __pragma(warning(disable: w)) 8 | #define DISABLE_GCC_WARNING(w) 9 | #define DISABLE_CLANG_WARNING(w) 10 | #define DISABLE_GCC_AND_CLANG_WARNING(w) 11 | 12 | #else 13 | 14 | #define PUSH_WARNINGS _Pragma("GCC diagnostic push") 15 | #define POP_WARNINGS _Pragma("GCC diagnostic pop") 16 | #define DISABLE_VS_WARNINGS(w) 17 | 18 | #if defined(__clang__) 19 | #define DISABLE_GCC_WARNING(w) 20 | #define DISABLE_CLANG_WARNING DISABLE_GCC_AND_CLANG_WARNING 21 | #else 22 | #define DISABLE_GCC_WARNING DISABLE_GCC_AND_CLANG_WARNING 23 | #define DISABLE_CLANG_WARNING(w) 24 | #endif 25 | 26 | #define DISABLE_GCC_AND_CLANG_WARNING(w) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/cryptonight/generic-ops.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #define CRYPTO_MAKE_COMPARABLE(type) \ 39 | namespace crypto { \ 40 | inline bool operator==(const type &_v1, const type &_v2) { \ 41 | return !memcmp(&_v1, &_v2, sizeof(_v1)); \ 42 | } \ 43 | inline bool operator!=(const type &_v1, const type &_v2) { \ 44 | return !operator==(_v1, _v2); \ 45 | } \ 46 | } 47 | 48 | #define CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \ 49 | namespace crypto { \ 50 | inline bool operator==(const type &_v1, const type &_v2) { \ 51 | static_assert(sizeof(_v1) == 32, "constant time comparison is only implenmted for 32 bytes"); \ 52 | return crypto_verify_32((const unsigned char*)&_v1, (const unsigned char*)&_v2) == 0; \ 53 | } \ 54 | inline bool operator!=(const type &_v1, const type &_v2) { \ 55 | return !operator==(_v1, _v2); \ 56 | } \ 57 | } 58 | 59 | #define CRYPTO_DEFINE_HASH_FUNCTIONS(type) \ 60 | namespace crypto { \ 61 | static_assert(sizeof(std::size_t) <= sizeof(type), "Size of " #type " must be at least that of size_t"); \ 62 | inline std::size_t hash_value(const type &_v) { \ 63 | return reinterpret_cast(_v); \ 64 | } \ 65 | } \ 66 | namespace std { \ 67 | template<> \ 68 | struct hash { \ 69 | std::size_t operator()(const crypto::type &_v) const { \ 70 | return reinterpret_cast(_v); \ 71 | } \ 72 | }; \ 73 | } 74 | 75 | #define CRYPTO_MAKE_HASHABLE(type) \ 76 | CRYPTO_MAKE_COMPARABLE(type) \ 77 | CRYPTO_DEFINE_HASH_FUNCTIONS(type) 78 | 79 | #define CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(type) \ 80 | CRYPTO_MAKE_COMPARABLE_CONSTANT_TIME(type) \ 81 | CRYPTO_DEFINE_HASH_FUNCTIONS(type) 82 | 83 | -------------------------------------------------------------------------------- /src/cryptonight/groestl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef __hash_h 30 | #define __hash_h 31 | /* 32 | #include "crypto_uint8.h" 33 | #include "crypto_uint32.h" 34 | #include "crypto_uint64.h" 35 | #include "crypto_hash.h" 36 | 37 | typedef crypto_uint8 uint8_t; 38 | typedef crypto_uint32 uint32_t; 39 | typedef crypto_uint64 uint64_t; 40 | */ 41 | #include 42 | 43 | /* some sizes (number of bytes) */ 44 | #define ROWS 8 45 | #define LENGTHFIELDLEN ROWS 46 | #define COLS512 8 47 | 48 | #define SIZE512 (ROWS*COLS512) 49 | 50 | #define ROUNDS512 10 51 | #define HASH_BIT_LEN 256 52 | 53 | #define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff)) 54 | 55 | 56 | #define li_32(h) 0x##h##u 57 | #define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n))) 58 | #define u32BIG(a) \ 59 | ((ROTL32(a,8) & li_32(00FF00FF)) | \ 60 | (ROTL32(a,24) & li_32(FF00FF00))) 61 | 62 | 63 | /* NIST API begin */ 64 | typedef unsigned char BitSequence; 65 | typedef unsigned long long DataLength; 66 | typedef struct { 67 | uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */ 68 | uint32_t block_counter1, 69 | block_counter2; /* message block counter(s) */ 70 | BitSequence buffer[SIZE512]; /* data buffer */ 71 | int buf_ptr; /* data buffer pointer */ 72 | int bits_in_last_byte; /* no. of message bits in last byte of 73 | data buffer */ 74 | } hashState; 75 | 76 | /*void Init(hashState*); 77 | void Update(hashState*, const BitSequence*, DataLength); 78 | void Final(hashState*, BitSequence*); */ 79 | void groestl(const BitSequence*, DataLength, BitSequence*); 80 | /* NIST API end */ 81 | 82 | /* 83 | int crypto_hash(unsigned char *out, 84 | const unsigned char *in, 85 | unsigned long long len); 86 | */ 87 | 88 | #endif /* __hash_h */ 89 | -------------------------------------------------------------------------------- /src/cryptonight/hash-extra-blake.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" 36 | { 37 | #endif 38 | 39 | #include "blake256.h" 40 | 41 | void hash_extra_blake(const void *data, size_t length, char *hash) { 42 | blake256_hash((uint8_t*)hash, (uint8_t*)data, length); 43 | } 44 | 45 | #if defined(__cplusplus) 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /src/cryptonight/hash-extra-groestl.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" 36 | { 37 | #endif 38 | 39 | #include "groestl.h" 40 | 41 | void hash_extra_groestl(const void *data, size_t length, char *hash) { 42 | groestl((uint8_t*)data, length * 8, (uint8_t*)hash); 43 | } 44 | 45 | #if defined(__cplusplus) 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /src/cryptonight/hash-extra-jh.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #if defined(__cplusplus) 37 | extern "C" 38 | { 39 | #endif 40 | 41 | #include "jh.h" 42 | #include "hash-ops.h" 43 | 44 | #define JH_HASH_BITLEN HASH_SIZE * 8 45 | 46 | void hash_extra_jh(const void *data, size_t length, char *hash) { 47 | // No need to check for failure b/c jh_hash only fails for invalid hash size 48 | jh_hash(JH_HASH_BITLEN, (uint8_t*)data, 8 * length, (uint8_t*)hash); 49 | } 50 | 51 | #if defined(__cplusplus) 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /src/cryptonight/hash-extra-skein.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" 36 | { 37 | #endif 38 | 39 | #include "hash-ops.h" 40 | #include "skein.h" 41 | 42 | #define SKEIN_HASH_BITLEN HASH_SIZE * 8 43 | 44 | void hash_extra_skein(const void *data, size_t length, char *hash) { 45 | // No need to check for failure b/c skein_hash only fails for invalid hash size 46 | skein_hash(SKEIN_HASH_BITLEN, (uint8_t*)data, 8 * length, (uint8_t*)hash); 47 | } 48 | 49 | #if defined(__cplusplus) 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /src/cryptonight/hash-ops.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | //#if !defined(__cplusplus) 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "int-util.h" 41 | #include "warnings.h" 42 | 43 | static inline void *padd(void *p, size_t i) { 44 | return (char *) p + i; 45 | } 46 | 47 | static inline const void *cpadd(const void *p, size_t i) { 48 | return (const char *) p + i; 49 | } 50 | 51 | PUSH_WARNINGS 52 | DISABLE_VS_WARNINGS(4267) 53 | static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t must be 4 or 8 bytes long"); 54 | static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length) { 55 | if (sizeof(size_t) == 4) { 56 | *(uint32_t *) padd(buffer, bufsize - 4) = swap32be(length); 57 | } else { 58 | *(uint64_t *) padd(buffer, bufsize - 8) = swap64be(length); 59 | } 60 | } 61 | POP_WARNINGS 62 | 63 | #pragma pack(push, 1) 64 | union hash_state { 65 | uint8_t b[200]; 66 | uint64_t w[25]; 67 | }; 68 | #pragma pack(pop) 69 | static_assert(sizeof(union hash_state) == 200, "Invalid structure size"); 70 | 71 | void hash_permutation(union hash_state *state); 72 | void hash_process(union hash_state *state, const uint8_t *buf, size_t count); 73 | 74 | //#endif 75 | 76 | enum { 77 | HASH_SIZE = 32, 78 | HASH_DATA_AREA = 136 79 | }; 80 | 81 | void cn_fast_hash(const void *data, size_t length, char *hash); 82 | void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); 83 | 84 | void hash_extra_blake(const void *data, size_t length, char *hash); 85 | void hash_extra_groestl(const void *data, size_t length, char *hash); 86 | void hash_extra_jh(const void *data, size_t length, char *hash); 87 | void hash_extra_skein(const void *data, size_t length, char *hash); 88 | 89 | void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash); 90 | bool tree_path(size_t count, size_t idx, uint32_t *path); 91 | bool tree_branch(const char (*hashes)[HASH_SIZE], size_t count, const char *hash, char (*branch)[HASH_SIZE], size_t *depth, uint32_t *path); 92 | bool tree_branch_hash(const char hash[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path, char root[HASH_SIZE]); 93 | bool is_branch_in_tree(const char hash[HASH_SIZE], const char root[HASH_SIZE], const char (*branch)[HASH_SIZE], size_t depth, uint32_t path); 94 | 95 | #define RX_BLOCK_VERSION 12 96 | void rx_slow_hash_allocate_state(void); 97 | void rx_slow_hash_free_state(void); 98 | uint64_t rx_seedheight(const uint64_t height); 99 | void rx_seedheights(const uint64_t height, uint64_t *seed_height, uint64_t *next_height); 100 | void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length, char *hash, int miners, int is_alt); 101 | void rx_reorg(const uint64_t split_height); 102 | 103 | void slow_hash_allocate_state(void); 104 | void slow_hash_free_state(void); 105 | -------------------------------------------------------------------------------- /src/cryptonight/hash.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #if defined(__cplusplus) 36 | extern "C" 37 | { 38 | #endif 39 | 40 | #include "hash-ops.h" 41 | #include "keccak.h" 42 | 43 | void hash_permutation(union hash_state *state) { 44 | #if BYTE_ORDER == LITTLE_ENDIAN 45 | keccakf((uint64_t*)state, 24); 46 | #else 47 | uint64_t le_state[25]; 48 | memcpy_swap64le(le_state, state, 25); 49 | keccakf(le_state, 24); 50 | memcpy_swap64le(state, le_state, 25); 51 | #endif 52 | } 53 | 54 | void hash_process(union hash_state *state, const uint8_t *buf, size_t count) { 55 | keccak1600(buf, count, (uint8_t*)state); 56 | } 57 | 58 | void cn_fast_hash(const void *data, size_t length, char *hash) { 59 | union hash_state state; 60 | hash_process(&state, (uint8_t*)data, length); 61 | memcpy(hash, &state, HASH_SIZE); 62 | } 63 | 64 | #if defined(__cplusplus) 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /src/cryptonight/hash.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | 36 | #include "common/pod-class.h" 37 | #include "generic-ops.h" 38 | #include "hex.h" 39 | #include "span.h" 40 | 41 | namespace crypto { 42 | 43 | extern "C" { 44 | #include "hash-ops.h" 45 | } 46 | 47 | #pragma pack(push, 1) 48 | POD_CLASS hash { 49 | char data[HASH_SIZE]; 50 | }; 51 | POD_CLASS hash8 { 52 | char data[8]; 53 | }; 54 | #pragma pack(pop) 55 | 56 | static_assert(sizeof(hash) == HASH_SIZE, "Invalid structure size"); 57 | static_assert(sizeof(hash8) == 8, "Invalid structure size"); 58 | 59 | /* 60 | Cryptonight hash functions 61 | */ 62 | 63 | inline void cn_fast_hash(const void *data, std::size_t length, hash &hash) { 64 | cn_fast_hash(data, length, reinterpret_cast(&hash)); 65 | } 66 | 67 | inline hash cn_fast_hash(const void *data, std::size_t length) { 68 | hash h; 69 | cn_fast_hash(data, length, reinterpret_cast(&h)); 70 | return h; 71 | } 72 | 73 | inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { 74 | cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/, height); 75 | } 76 | 77 | inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) { 78 | cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/, height); 79 | } 80 | 81 | inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { 82 | tree_hash(reinterpret_cast(hashes), count, reinterpret_cast(&root_hash)); 83 | } 84 | 85 | inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { 86 | epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; 87 | } 88 | inline std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { 89 | epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; 90 | } 91 | 92 | constexpr static crypto::hash null_hash = {}; 93 | constexpr static crypto::hash8 null_hash8 = {}; 94 | } 95 | 96 | CRYPTO_MAKE_HASHABLE(hash) 97 | CRYPTO_MAKE_COMPARABLE(hash8) 98 | -------------------------------------------------------------------------------- /src/cryptonight/hmac-keccak.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include "hmac-keccak.h" 30 | #include "memwipe.h" 31 | 32 | #define KECCAK_BLOCKLEN 136 33 | #define HASH_SIZE 32 34 | 35 | void hmac_keccak_init(hmac_keccak_state *S, const uint8_t *_key, size_t keylen) { 36 | const uint8_t *key = _key; 37 | uint8_t keyhash[HASH_SIZE]; 38 | uint8_t pad[KECCAK_BLOCKLEN]; 39 | uint64_t i; 40 | 41 | if (keylen > KECCAK_BLOCKLEN) { 42 | keccak(key, keylen, keyhash, HASH_SIZE); 43 | key = keyhash; 44 | keylen = HASH_SIZE; 45 | } 46 | 47 | keccak_init(&S->inner); 48 | memset(pad, 0x36, KECCAK_BLOCKLEN); 49 | for (i = 0; i < keylen; ++i) { 50 | pad[i] ^= key[i]; 51 | } 52 | keccak_update(&S->inner, pad, KECCAK_BLOCKLEN); 53 | 54 | keccak_init(&S->outer); 55 | memset(pad, 0x5c, KECCAK_BLOCKLEN); 56 | for (i = 0; i < keylen; ++i) { 57 | pad[i] ^= key[i]; 58 | } 59 | keccak_update(&S->outer, pad, KECCAK_BLOCKLEN); 60 | 61 | memwipe(keyhash, HASH_SIZE); 62 | } 63 | 64 | void hmac_keccak_update(hmac_keccak_state *S, const uint8_t *data, size_t datalen) { 65 | keccak_update(&S->inner, data, datalen); 66 | } 67 | 68 | void hmac_keccak_finish(hmac_keccak_state *S, uint8_t *digest) { 69 | uint8_t ihash[HASH_SIZE]; 70 | keccak_finish(&S->inner, ihash); 71 | keccak_update(&S->outer, ihash, HASH_SIZE); 72 | keccak_finish(&S->outer, digest); 73 | memwipe(ihash, HASH_SIZE); 74 | } 75 | 76 | void hmac_keccak_hash(uint8_t *out, const uint8_t *key, size_t keylen, const uint8_t *in, size_t inlen) { 77 | hmac_keccak_state S; 78 | hmac_keccak_init(&S, key, keylen); 79 | hmac_keccak_update(&S, in, inlen); 80 | hmac_keccak_finish(&S, out); 81 | } 82 | -------------------------------------------------------------------------------- /src/cryptonight/hmac-keccak.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #ifndef HMAC_KECCAK_H 30 | #define HMAC_KECCAK_H 31 | 32 | #include "keccak.h" 33 | 34 | // HMAC RFC 2104 with Keccak-256 base hash function 35 | // 36 | // B = KECCAK_BLOCKLEN = 136 B 37 | // L = HASH_SIZE = 32 B 38 | // 39 | // Note this is not HMAC-SHA3 as SHA3 and Keccak differs in 40 | // the padding constant. 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | typedef struct { 47 | KECCAK_CTX inner; 48 | KECCAK_CTX outer; 49 | } hmac_keccak_state; 50 | 51 | void hmac_keccak_init(hmac_keccak_state *S, const uint8_t *_key, size_t keylen); 52 | void hmac_keccak_update(hmac_keccak_state *S, const uint8_t *data, size_t datalen); 53 | void hmac_keccak_finish(hmac_keccak_state *S, uint8_t *digest); 54 | void hmac_keccak_hash(uint8_t *out, const uint8_t *key, size_t keylen, const uint8_t *in, size_t inlen); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | #endif //HMAC_KECCAK_H 60 | -------------------------------------------------------------------------------- /src/cryptonight/initializer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #if defined(__GNUC__) 34 | #if defined(__sun) && defined(__SVR4) 35 | #define INITIALIZER(name) __attribute__((constructor)) static void name(void) 36 | #define FINALIZER(name) __attribute__((destructor)) static void name(void) 37 | #else 38 | #define INITIALIZER(name) __attribute__((constructor(101))) static void name(void) 39 | #define FINALIZER(name) __attribute__((destructor(101))) static void name(void) 40 | #endif 41 | #define REGISTER_FINALIZER(name) ((void) 0) 42 | 43 | #elif defined(_MSC_VER) 44 | #include 45 | #include 46 | // https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc 47 | // https://msdn.microsoft.com/en-us/library/bb918180.aspx 48 | #pragma section(".CRT$XCT", read) 49 | #define INITIALIZER(name) \ 50 | static void __cdecl name(void); \ 51 | __declspec(allocate(".CRT$XCT")) void (__cdecl *const _##name)(void) = &name; \ 52 | static void __cdecl name(void) 53 | #define FINALIZER(name) \ 54 | static void __cdecl name(void) 55 | #define REGISTER_FINALIZER(name) \ 56 | do { \ 57 | int _res = atexit(name); \ 58 | assert(_res == 0); \ 59 | } while (0); 60 | 61 | #else 62 | #error Unsupported compiler 63 | #endif 64 | -------------------------------------------------------------------------------- /src/cryptonight/jh.h: -------------------------------------------------------------------------------- 1 | /*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C 2 | 3 | -------------------------------- 4 | Performance 5 | 6 | Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz) 7 | Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic) 8 | Speed for long message: 9 | 1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2 10 | 2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3 11 | 12 | -------------------------------- 13 | Last Modified: January 16, 2011 14 | */ 15 | #pragma once 16 | 17 | typedef unsigned char BitSequence; 18 | typedef unsigned long long DataLength; 19 | typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn; 20 | 21 | HashReturn jh_hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); 22 | -------------------------------------------------------------------------------- /src/cryptonight/keccak.h: -------------------------------------------------------------------------------- 1 | // keccak.h 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | 4 | #ifndef KECCAK_H 5 | #define KECCAK_H 6 | 7 | #include 8 | #include 9 | 10 | #ifndef KECCAK_ROUNDS 11 | #define KECCAK_ROUNDS 24 12 | #endif 13 | 14 | #ifndef ROTL64 15 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) 16 | #endif 17 | 18 | // SHA3 Algorithm context. 19 | typedef struct KECCAK_CTX 20 | { 21 | // 1600 bits algorithm hashing state 22 | uint64_t hash[25]; 23 | // 1088-bit buffer for leftovers, block size = 136 B for 256-bit keccak 24 | uint64_t message[17]; 25 | // count of bytes in the message[] buffer 26 | size_t rest; 27 | } KECCAK_CTX; 28 | 29 | // compute a keccak hash (md) of given byte length from "in" 30 | void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen); 31 | 32 | // update the state 33 | void keccakf(uint64_t st[25], int norounds); 34 | 35 | void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md); 36 | 37 | void keccak_init(KECCAK_CTX * ctx); 38 | void keccak_update(KECCAK_CTX * ctx, const uint8_t *in, size_t inlen); 39 | void keccak_finish(KECCAK_CTX * ctx, uint8_t *md); 40 | #endif 41 | -------------------------------------------------------------------------------- /src/cryptonight/memwipe.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file Copyright (c) 2009-2015 The Bitcoin Core developers 30 | 31 | #define __STDC_WANT_LIB_EXT1__ 1 32 | #include 33 | #include 34 | #include 35 | #include 36 | #ifdef HAVE_EXPLICIT_BZERO 37 | #include 38 | #endif 39 | #include "memwipe.h" 40 | 41 | #if defined(_MSC_VER) 42 | #define SCARECROW \ 43 | __asm; 44 | #else 45 | #define SCARECROW \ 46 | __asm__ __volatile__("" : : "r"(ptr) : "memory"); 47 | #endif 48 | 49 | #ifdef HAVE_MEMSET_S 50 | 51 | void *memwipe(void *ptr, size_t n) 52 | { 53 | if (n > 0 && memset_s(ptr, n, 0, n)) 54 | { 55 | #ifdef NDEBUG 56 | fprintf(stderr, "Error: memset_s failed\n"); 57 | _exit(1); 58 | #else 59 | abort(); 60 | #endif 61 | } 62 | SCARECROW // might as well... 63 | return ptr; 64 | } 65 | 66 | #elif defined HAVE_EXPLICIT_BZERO 67 | 68 | void *memwipe(void *ptr, size_t n) 69 | { 70 | if (n > 0) 71 | explicit_bzero(ptr, n); 72 | SCARECROW 73 | return ptr; 74 | } 75 | 76 | #else 77 | 78 | /* The memory_cleanse implementation is taken from Bitcoin */ 79 | 80 | /* Compilers have a bad habit of removing "superfluous" memset calls that 81 | * are trying to zero memory. For example, when memset()ing a buffer and 82 | * then free()ing it, the compiler might decide that the memset is 83 | * unobservable and thus can be removed. 84 | * 85 | * Previously we used OpenSSL which tried to stop this by a) implementing 86 | * memset in assembly on x86 and b) putting the function in its own file 87 | * for other platforms. 88 | * 89 | * This change removes those tricks in favour of using asm directives to 90 | * scare the compiler away. As best as our compiler folks can tell, this is 91 | * sufficient and will continue to be so. 92 | * 93 | * Adam Langley 94 | * Commit: ad1907fe73334d6c696c8539646c21b11178f20f 95 | * BoringSSL (LICENSE: ISC) 96 | */ 97 | static void memory_cleanse(void *ptr, size_t len) 98 | { 99 | memset(ptr, 0, len); 100 | 101 | /* As best as we can tell, this is sufficient to break any optimisations that 102 | might try to eliminate "superfluous" memsets. If there's an easy way to 103 | detect memset_s, it would be better to use that. */ 104 | SCARECROW 105 | } 106 | 107 | void *memwipe(void *ptr, size_t n) 108 | { 109 | if (n > 0) 110 | memory_cleanse(ptr, n); 111 | SCARECROW 112 | return ptr; 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/cryptonight/memwipe.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #ifdef __cplusplus 34 | #include 35 | #include 36 | 37 | extern "C" { 38 | #endif 39 | 40 | void *memwipe(void *src, size_t n); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #ifdef __cplusplus 47 | namespace tools { 48 | 49 | /// Scrubs data in the contained type upon destruction. 50 | /// 51 | /// Primarily useful for making sure that private keys don't stick around in 52 | /// memory after the objects that held them have gone out of scope. 53 | template 54 | struct scrubbed : public T { 55 | using type = T; 56 | 57 | ~scrubbed() { 58 | scrub(); 59 | } 60 | 61 | /// Destroy the contents of the contained type. 62 | void scrub() { 63 | static_assert(std::is_pod::value, 64 | "T cannot be auto-scrubbed. T must be POD."); 65 | static_assert(std::is_trivially_destructible::value, 66 | "T cannot be auto-scrubbed. T must be trivially destructable."); 67 | memwipe(this, sizeof(T)); 68 | } 69 | }; 70 | 71 | template 72 | T& unwrap(scrubbed& src) { return src; } 73 | 74 | template 75 | const T& unwrap(scrubbed const& src) { return src; } 76 | 77 | template 78 | using scrubbed_arr = scrubbed>; 79 | } // namespace tools 80 | 81 | #endif // __cplusplus 82 | -------------------------------------------------------------------------------- /src/cryptonight/oaes_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * --------------------------------------------------------------------------- 3 | * OpenAES License 4 | * --------------------------------------------------------------------------- 5 | * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * - Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * - Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * --------------------------------------------------------------------------- 29 | */ 30 | 31 | #ifndef _OAES_CONFIG_H 32 | #define _OAES_CONFIG_H 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | //#ifndef OAES_HAVE_ISAAC 39 | //#define OAES_HAVE_ISAAC 1 40 | //#endif // OAES_HAVE_ISAAC 41 | 42 | //#ifndef OAES_DEBUG 43 | //#define OAES_DEBUG 0 44 | //#endif // OAES_DEBUG 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif // _OAES_CONFIG_H 51 | -------------------------------------------------------------------------------- /src/cryptonight/random.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014-2022, The Monero Project 2 | // 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are 6 | // permitted provided that the following conditions are met: 7 | // 8 | // 1. Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 | // of conditions and the following disclaimer in the documentation and/or other 13 | // materials provided with the distribution. 14 | // 15 | // 3. Neither the name of the copyright holder nor the names of its contributors may be 16 | // used to endorse or promote products derived from this software without specific 17 | // prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | void generate_random_bytes_not_thread_safe(size_t n, void *result); 36 | void add_extra_entropy_not_thread_safe(const void *ptr, size_t bytes); 37 | -------------------------------------------------------------------------------- /src/cryptonight/skein.h: -------------------------------------------------------------------------------- 1 | #ifndef _SKEIN_H_ 2 | #define _SKEIN_H_ 1 3 | /************************************************************************** 4 | ** 5 | ** Interface declarations and internal definitions for Skein hashing. 6 | ** 7 | ** Source code author: Doug Whiting, 2008. 8 | ** 9 | ** This algorithm and source code is released to the public domain. 10 | ** 11 | *************************************************************************** 12 | ** 13 | ** The following compile-time switches may be defined to control some 14 | ** tradeoffs between speed, code size, error checking, and security. 15 | ** 16 | ** The "default" note explains what happens when the switch is not defined. 17 | ** 18 | ** SKEIN_DEBUG -- make callouts from inside Skein code 19 | ** to examine/display intermediate values. 20 | ** [default: no callouts (no overhead)] 21 | ** 22 | ** SKEIN_ERR_CHECK -- how error checking is handled inside Skein 23 | ** code. If not defined, most error checking 24 | ** is disabled (for performance). Otherwise, 25 | ** the switch value is interpreted as: 26 | ** 0: use assert() to flag errors 27 | ** 1: return SKEIN_FAIL to flag errors 28 | ** 29 | ***************************************************************************/ 30 | #include "skein_port.h" /* get platform-specific definitions */ 31 | 32 | typedef enum 33 | { 34 | SKEIN_SUCCESS = 0, /* return codes from Skein calls */ 35 | SKEIN_FAIL = 1, 36 | SKEIN_BAD_HASHLEN = 2 37 | } 38 | HashReturn; 39 | 40 | typedef size_t DataLength; /* bit count type */ 41 | typedef u08b_t BitSequence; /* bit stream type */ 42 | 43 | /* "all-in-one" call */ 44 | HashReturn skein_hash(int hashbitlen, const BitSequence *data, 45 | DataLength databitlen, BitSequence *hashval); 46 | 47 | #endif /* ifndef _SKEIN_H_ */ 48 | -------------------------------------------------------------------------------- /src/cryptonight/warnings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(_MSC_VER) 4 | 5 | #define PUSH_WARNINGS __pragma(warning(push)) 6 | #define POP_WARNINGS __pragma(warning(pop)) 7 | #define DISABLE_VS_WARNINGS(w) __pragma(warning(disable: w)) 8 | #define DISABLE_GCC_WARNING(w) 9 | #define DISABLE_CLANG_WARNING(w) 10 | #define DISABLE_GCC_AND_CLANG_WARNING(w) 11 | 12 | #else 13 | 14 | //#include 15 | 16 | #define PUSH_WARNINGS _Pragma("GCC diagnostic push") 17 | #define POP_WARNINGS _Pragma("GCC diagnostic pop") 18 | #define DISABLE_VS_WARNINGS(w) 19 | 20 | #if defined(__clang__) 21 | #define DISABLE_GCC_WARNING(w) 22 | #define DISABLE_CLANG_WARNING DISABLE_GCC_AND_CLANG_WARNING 23 | #else 24 | #define DISABLE_GCC_WARNING DISABLE_GCC_AND_CLANG_WARNING 25 | #define DISABLE_CLANG_WARNING(w) 26 | #endif 27 | 28 | #define DISABLE_GCC_AND_CLANG_WARNING(w) _Pragma(BOOST_PP_STRINGIZE(GCC diagnostic ignored BOOST_PP_STRINGIZE(-W##w))) 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/misc/getopt.h: -------------------------------------------------------------------------------- 1 | /* Declarations for getopt. 2 | Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU General Public License as published by the 6 | Free Software Foundation; either version 2, or (at your option) any 7 | later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 17 | 18 | #ifndef _GETOPT_H 19 | #define _GETOPT_H 1 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /* For communication from `getopt' to the caller. 26 | When `getopt' finds an option that takes an argument, 27 | the argument value is returned here. 28 | Also, when `ordering' is RETURN_IN_ORDER, 29 | each non-option ARGV-element is returned here. */ 30 | 31 | extern char *optarg; 32 | 33 | /* Index in ARGV of the next element to be scanned. 34 | This is used for communication to and from the caller 35 | and for communication between successive calls to `getopt'. 36 | 37 | On entry to `getopt', zero means this is the first call; initialize. 38 | 39 | When `getopt' returns EOF, this is the index of the first of the 40 | non-option elements that the caller should itself scan. 41 | 42 | Otherwise, `optind' communicates from one call to the next 43 | how much of ARGV has been scanned so far. */ 44 | 45 | extern int optind; 46 | 47 | /* Callers store zero here to inhibit the error message `getopt' prints 48 | for unrecognized options. */ 49 | 50 | extern int opterr; 51 | 52 | /* Set to an option character which was unrecognized. */ 53 | 54 | extern int optopt; 55 | 56 | /* Describe the long-named options requested by the application. 57 | The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector 58 | of `struct option' terminated by an element containing a name which is 59 | zero. 60 | 61 | The field `has_arg' is: 62 | no_argument (or 0) if the option does not take an argument, 63 | required_argument (or 1) if the option requires an argument, 64 | optional_argument (or 2) if the option takes an optional argument. 65 | 66 | If the field `flag' is not NULL, it points to a variable that is set 67 | to the value given in the field `val' when the option is found, but 68 | left unchanged if the option is not found. 69 | 70 | To have a long-named option do something other than set an `int' to 71 | a compiled-in constant, such as set a value from `optarg', set the 72 | option's `flag' field to zero and its `val' field to a nonzero 73 | value (the equivalent single-letter option character, if there is 74 | one). For long options that have a zero `flag' field, `getopt' 75 | returns the contents of the `val' field. */ 76 | 77 | struct option 78 | { 79 | #if __STDC__ 80 | const char *name; 81 | #else 82 | char *name; 83 | #endif 84 | /* has_arg can't be an enum because some compilers complain about 85 | type mismatches in all the code that assumes it is an int. */ 86 | int has_arg; 87 | int *flag; 88 | int val; 89 | }; 90 | 91 | /* Names for the values of the `has_arg' field of `struct option'. */ 92 | 93 | #define no_argument 0 94 | #define required_argument 1 95 | #define optional_argument 2 96 | 97 | //#if __STDC__ || defined(PROTO) 98 | //#if defined(__GNU_LIBRARY__) 99 | /* Many other libraries have conflicting prototypes for getopt, with 100 | differences in the consts, in stdlib.h. To avoid compilation 101 | errors, only prototype getopt for the GNU C library. */ 102 | extern int getopt (int argc, char *const *argv, const char *shortopts); 103 | //#endif /* not __GNU_LIBRARY__ */ 104 | extern int getopt_long (int argc, char *const *argv, const char *shortopts, 105 | const struct option *longopts, int *longind); 106 | extern int getopt_long_only (int argc, char *const *argv, 107 | const char *shortopts, 108 | const struct option *longopts, int *longind); 109 | 110 | /* Internal only. Users should not call this directly. */ 111 | /* extern int _getopt_internal (int argc, char *const *argv, 112 | const char *shortopts, 113 | const struct option *longopts, int *longind, 114 | int long_only); */ 115 | //#else /* not __STDC__ */ 116 | //extern int getopt (); 117 | //extern int getopt_long (); 118 | //extern int getopt_long_only (); 119 | 120 | //extern int _getopt_internal (); 121 | //#endif /* not __STDC__ */ 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif /* _GETOPT_H */ -------------------------------------------------------------------------------- /src/misc/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNISTD_H 2 | #define _UNISTD_H 1 3 | 4 | /* This file intended to serve as a drop-in replacement for 5 | * unistd.h on Windows. 6 | * Please add functionality as neeeded. 7 | * Original file from: http://stackoverflow.com/a/826027 8 | */ 9 | 10 | #include 11 | #include 12 | #include /* getopt at: https://gist.github.com/bikerm16/1b75e2dd20d839dcea58 */ 13 | #include /* for getpid() and the exec..() family */ 14 | #include /* for _getcwd() and _chdir() */ 15 | 16 | #define srandom srand 17 | #define random rand 18 | 19 | /* Values for the second argument to access. 20 | These may be OR'd together. */ 21 | #define R_OK 4 /* Test for read permission. */ 22 | #define W_OK 2 /* Test for write permission. */ 23 | #define X_OK R_OK /* execute permission - unsupported in Windows, use R_OK instead. */ 24 | #define F_OK 0 /* Test for existence. */ 25 | 26 | #define access _access 27 | #define dup2 _dup2 28 | #define execve _execve 29 | #define ftruncate _chsize 30 | #define unlink _unlink 31 | #define fileno _fileno 32 | #define getcwd _getcwd 33 | #define chdir _chdir 34 | #define isatty _isatty 35 | #define lseek _lseek 36 | /* read, write, and close are NOT being #defined here, 37 | * because while there are file handle specific versions for Windows, 38 | * they probably don't work for sockets. 39 | * You need to look at your app and consider whether 40 | * to call e.g. closesocket(). 41 | */ 42 | 43 | #define ssize_t int 44 | #define STDIN_FILENO 0 45 | #define STDOUT_FILENO 1 46 | #define STDERR_FILENO 2 47 | /* should be in some equivalent to */ 48 | typedef __int8 int8_t; 49 | typedef __int16 int16_t; 50 | typedef __int32 int32_t; 51 | typedef __int64 int64_t; 52 | typedef unsigned __int8 uint8_t; 53 | typedef unsigned __int16 uint16_t; 54 | typedef unsigned __int32 uint32_t; 55 | typedef unsigned __int64 uint64_t; 56 | 57 | #endif /* unistd.h */ -------------------------------------------------------------------------------- /src/pycryptonight.cpp: -------------------------------------------------------------------------------- 1 | #define PY_SSIZE_T_CLEAN 2 | #include 3 | 4 | #if defined(__cplusplus) 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "pycryptonight.h" 10 | #include "cryptonight/hash-ops.h" 11 | 12 | 13 | PyDoc_STRVAR(_pycryptonight_cn_fast_hash__doc__, 14 | "cn_fast_hash(data) -> data\n" 15 | "\n" 16 | "Fast hashing, Keccak-256.\n"); 17 | 18 | #define FUNC_DEF_CN_FAST_HASH {"cn_fast_hash", (PyCFunction)_pycryptonight_cn_fast_hash,\ 19 | METH_VARARGS | METH_KEYWORDS, _pycryptonight_cn_fast_hash__doc__} 20 | 21 | static PyObject *_pycryptonight_cn_fast_hash(PyObject *self, PyObject *args, PyObject *kwargs) 22 | { 23 | #if PY_MAJOR_VERSION >= 3 24 | static const char *format = "y#|:cn_fast_hash"; 25 | #else 26 | static const char *format = "s#|:cn_fast_hash"; 27 | #endif 28 | static char *keywords[] = {(char*)"data", NULL}; 29 | 30 | Py_ssize_t input_len = 0; 31 | const char *data = NULL; 32 | char hash[HASH_SIZE]; 33 | PyObject *result = NULL; 34 | 35 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, &data, &input_len)) { 36 | goto bail; 37 | } 38 | 39 | if (input_len < 0 || data == NULL){ 40 | PyErr_SetString(PyExc_ValueError, "invalid input"); 41 | goto bail; 42 | } 43 | 44 | cn_fast_hash(data, input_len, hash); 45 | 46 | #if PY_MAJOR_VERSION >= 3 47 | result = PyBytes_FromStringAndSize(hash, HASH_SIZE); // Py_BuildValue("y#", hash, HASH_SIZE); 48 | #else 49 | result = PyString_FromStringAndSize(hash, HASH_SIZE); //Py_BuildValue("s#", hash, HASH_SIZE); 50 | #endif 51 | return result; 52 | 53 | bail: 54 | return NULL; 55 | } 56 | 57 | 58 | PyDoc_STRVAR(_pycryptonight_cn_slow_hash__doc__, 59 | "cn_slow_hash(data, variant=0, prehashed=0) -> data\n" 60 | "\n" 61 | "Slow hashing, CryptoNight\n"); 62 | 63 | #define FUNC_DEF_CN_SLOW_HASH {"cn_slow_hash", (PyCFunction)_pycryptonight_cn_slow_hash,\ 64 | METH_VARARGS | METH_KEYWORDS, _pycryptonight_cn_slow_hash__doc__} 65 | 66 | static PyObject *_pycryptonight_cn_slow_hash(PyObject *self, PyObject *args, PyObject *kwargs) 67 | { 68 | #if PY_MAJOR_VERSION >= 3 69 | static const char *format = "z#|iil:cn_slow_hash"; 70 | #else 71 | static const char *format = "s#|iil:cn_slow_hash"; 72 | #endif 73 | static char *keywords[] = {(char*)"data", (char*)"variant", (char*)"prehashed", (char*)"height", NULL}; 74 | 75 | Py_ssize_t input_len=0; 76 | char *data = NULL; 77 | char hash[HASH_SIZE]; 78 | int variant = 0; 79 | int prehashed = 0; 80 | long int height = 0; 81 | PyObject *result = NULL; 82 | 83 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, &data, &input_len, &variant, &prehashed, &height)) { 84 | goto bail; 85 | } 86 | 87 | if (input_len < 0 || data == NULL){ 88 | PyErr_SetString(PyExc_ValueError, "invalid input"); 89 | goto bail; 90 | } 91 | 92 | cn_slow_hash(data, input_len, hash, variant, prehashed, height); 93 | 94 | #if PY_MAJOR_VERSION >= 3 95 | result = PyBytes_FromStringAndSize(hash, HASH_SIZE); // Py_BuildValue("y#", hash, HASH_SIZE); 96 | #else 97 | result = PyString_FromStringAndSize(hash, HASH_SIZE); //Py_BuildValue("s#", hash, HASH_SIZE); 98 | #endif 99 | return result; 100 | 101 | bail: 102 | return NULL; 103 | } 104 | 105 | 106 | static PyMethodDef PyCryptonightMethods[] = { 107 | FUNC_DEF_CN_FAST_HASH, 108 | FUNC_DEF_CN_SLOW_HASH, 109 | { NULL, NULL, 0, NULL } 110 | }; 111 | 112 | #if PY_MAJOR_VERSION >= 3 113 | static struct PyModuleDef PyCryptonightModule = { 114 | PyModuleDef_HEAD_INIT, 115 | "_pycryptonight", 116 | "...", 117 | -1, 118 | PyCryptonightMethods 119 | }; 120 | 121 | PyMODINIT_FUNC PyInit__pycryptonight(void) { 122 | return PyModule_Create(&PyCryptonightModule); 123 | } 124 | 125 | #else 126 | 127 | PyMODINIT_FUNC init_pycryptonight(void) { 128 | (void) Py_InitModule("_pycryptonight", PyCryptonightMethods); 129 | } 130 | #endif 131 | 132 | #if defined(__cplusplus) 133 | } 134 | #endif 135 | -------------------------------------------------------------------------------- /src/pycryptonight.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | -------------------------------------------------------------------------------- /src/randomx/aes_hash.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | template 34 | void hashAes1Rx4(const void *input, size_t inputSize, void *hash); 35 | 36 | template 37 | void fillAes1Rx4(void *state, size_t outputSize, void *buffer); 38 | 39 | template 40 | void fillAes4Rx4(void *state, size_t outputSize, void *buffer); 41 | 42 | template 43 | void hashAndFillAes1Rx4(void *scratchpad, size_t scratchpadSize, void *hash, void* fill_state); 44 | -------------------------------------------------------------------------------- /src/randomx/allocator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include "allocator.hpp" 31 | #include "intrin_portable.h" 32 | #include "virtual_memory.h" 33 | #include "common.hpp" 34 | 35 | namespace randomx { 36 | 37 | template 38 | void* AlignedAllocator::allocMemory(size_t count) { 39 | void *mem = rx_aligned_alloc(count, alignment); 40 | if (mem == nullptr) 41 | throw std::bad_alloc(); 42 | return mem; 43 | } 44 | 45 | template 46 | void AlignedAllocator::freeMemory(void* ptr, size_t count) { 47 | rx_aligned_free(ptr); 48 | } 49 | 50 | template struct AlignedAllocator; 51 | 52 | void* LargePageAllocator::allocMemory(size_t count) { 53 | void *mem = allocLargePagesMemory(count); 54 | if (mem == nullptr) 55 | throw std::bad_alloc(); 56 | return mem; 57 | } 58 | 59 | void LargePageAllocator::freeMemory(void* ptr, size_t count) { 60 | freePagedMemory(ptr, count); 61 | }; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/randomx/allocator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | namespace randomx { 34 | 35 | template 36 | struct AlignedAllocator { 37 | static void* allocMemory(size_t); 38 | static void freeMemory(void*, size_t); 39 | }; 40 | 41 | struct LargePageAllocator { 42 | static void* allocMemory(size_t); 43 | static void freeMemory(void*, size_t); 44 | }; 45 | 46 | } -------------------------------------------------------------------------------- /src/randomx/asm/configuration.asm: -------------------------------------------------------------------------------- 1 | ; File start: ..\src\configuration.h 2 | RANDOMX_ARGON_MEMORY EQU 262144t 3 | RANDOMX_ARGON_ITERATIONS EQU 3t 4 | RANDOMX_ARGON_LANES EQU 1t 5 | RANDOMX_ARGON_SALT TEXTEQU <"RandomX\x03"> 6 | RANDOMX_CACHE_ACCESSES EQU 8t 7 | RANDOMX_SUPERSCALAR_LATENCY EQU 170t 8 | RANDOMX_DATASET_BASE_SIZE EQU 2147483648t 9 | RANDOMX_DATASET_EXTRA_SIZE EQU 33554368t 10 | RANDOMX_PROGRAM_SIZE EQU 256t 11 | RANDOMX_PROGRAM_ITERATIONS EQU 2048t 12 | RANDOMX_PROGRAM_COUNT EQU 8t 13 | RANDOMX_SCRATCHPAD_L3 EQU 2097152t 14 | RANDOMX_SCRATCHPAD_L2 EQU 262144t 15 | RANDOMX_SCRATCHPAD_L1 EQU 16384t 16 | RANDOMX_JUMP_BITS EQU 8t 17 | RANDOMX_JUMP_OFFSET EQU 8t 18 | RANDOMX_FREQ_IADD_RS EQU 16t 19 | RANDOMX_FREQ_IADD_M EQU 7t 20 | RANDOMX_FREQ_ISUB_R EQU 16t 21 | RANDOMX_FREQ_ISUB_M EQU 7t 22 | RANDOMX_FREQ_IMUL_R EQU 16t 23 | RANDOMX_FREQ_IMUL_M EQU 4t 24 | RANDOMX_FREQ_IMULH_R EQU 4t 25 | RANDOMX_FREQ_IMULH_M EQU 1t 26 | RANDOMX_FREQ_ISMULH_R EQU 4t 27 | RANDOMX_FREQ_ISMULH_M EQU 1t 28 | RANDOMX_FREQ_IMUL_RCP EQU 8t 29 | RANDOMX_FREQ_INEG_R EQU 2t 30 | RANDOMX_FREQ_IXOR_R EQU 15t 31 | RANDOMX_FREQ_IXOR_M EQU 5t 32 | RANDOMX_FREQ_IROR_R EQU 8t 33 | RANDOMX_FREQ_IROL_R EQU 2t 34 | RANDOMX_FREQ_ISWAP_R EQU 4t 35 | RANDOMX_FREQ_FSWAP_R EQU 4t 36 | RANDOMX_FREQ_FADD_R EQU 16t 37 | RANDOMX_FREQ_FADD_M EQU 5t 38 | RANDOMX_FREQ_FSUB_R EQU 16t 39 | RANDOMX_FREQ_FSUB_M EQU 5t 40 | RANDOMX_FREQ_FSCAL_R EQU 6t 41 | RANDOMX_FREQ_FMUL_R EQU 32t 42 | RANDOMX_FREQ_FDIV_M EQU 4t 43 | RANDOMX_FREQ_FSQRT_R EQU 6t 44 | RANDOMX_FREQ_CBRANCH EQU 25t 45 | RANDOMX_FREQ_CFROUND EQU 1t 46 | RANDOMX_FREQ_ISTORE EQU 16t 47 | RANDOMX_FREQ_NOP EQU 0t 48 | ; File end: ..\src\configuration.h 49 | -------------------------------------------------------------------------------- /src/randomx/asm/program_epilogue_linux.inc: -------------------------------------------------------------------------------- 1 | ;# restore callee-saved registers - System V AMD64 ABI 2 | pop r15 3 | pop r14 4 | pop r13 5 | pop r12 6 | pop rbp 7 | pop rbx 8 | 9 | ;# program finished 10 | ret 0 -------------------------------------------------------------------------------- /src/randomx/asm/program_epilogue_store.inc: -------------------------------------------------------------------------------- 1 | ;# save VM register values 2 | pop rcx 3 | mov qword ptr [rcx+0], r8 4 | mov qword ptr [rcx+8], r9 5 | mov qword ptr [rcx+16], r10 6 | mov qword ptr [rcx+24], r11 7 | mov qword ptr [rcx+32], r12 8 | mov qword ptr [rcx+40], r13 9 | mov qword ptr [rcx+48], r14 10 | mov qword ptr [rcx+56], r15 11 | movdqa xmmword ptr [rcx+64], xmm0 12 | movdqa xmmword ptr [rcx+80], xmm1 13 | movdqa xmmword ptr [rcx+96], xmm2 14 | movdqa xmmword ptr [rcx+112], xmm3 15 | lea rcx, [rcx+64] 16 | movdqa xmmword ptr [rcx+64], xmm4 17 | movdqa xmmword ptr [rcx+80], xmm5 18 | movdqa xmmword ptr [rcx+96], xmm6 19 | movdqa xmmword ptr [rcx+112], xmm7 -------------------------------------------------------------------------------- /src/randomx/asm/program_epilogue_win64.inc: -------------------------------------------------------------------------------- 1 | ;# restore callee-saved registers - Microsoft x64 calling convention 2 | movdqu xmm15, xmmword ptr [rsp] 3 | movdqu xmm14, xmmword ptr [rsp+16] 4 | movdqu xmm13, xmmword ptr [rsp+32] 5 | movdqu xmm12, xmmword ptr [rsp+48] 6 | movdqu xmm11, xmmword ptr [rsp+64] 7 | add rsp, 80 8 | movdqu xmm10, xmmword ptr [rsp] 9 | movdqu xmm9, xmmword ptr [rsp+16] 10 | movdqu xmm8, xmmword ptr [rsp+32] 11 | movdqu xmm7, xmmword ptr [rsp+48] 12 | movdqu xmm6, xmmword ptr [rsp+64] 13 | add rsp, 80 14 | pop r15 15 | pop r14 16 | pop r13 17 | pop r12 18 | pop rsi 19 | pop rdi 20 | pop rbp 21 | pop rbx 22 | 23 | ;# program finished 24 | ret 25 | -------------------------------------------------------------------------------- /src/randomx/asm/program_loop_load.inc: -------------------------------------------------------------------------------- 1 | lea rcx, [rsi+rax] 2 | push rcx 3 | xor r8, qword ptr [rcx+0] 4 | xor r9, qword ptr [rcx+8] 5 | xor r10, qword ptr [rcx+16] 6 | xor r11, qword ptr [rcx+24] 7 | xor r12, qword ptr [rcx+32] 8 | xor r13, qword ptr [rcx+40] 9 | xor r14, qword ptr [rcx+48] 10 | xor r15, qword ptr [rcx+56] 11 | lea rcx, [rsi+rdx] 12 | push rcx 13 | cvtdq2pd xmm0, qword ptr [rcx+0] 14 | cvtdq2pd xmm1, qword ptr [rcx+8] 15 | cvtdq2pd xmm2, qword ptr [rcx+16] 16 | cvtdq2pd xmm3, qword ptr [rcx+24] 17 | cvtdq2pd xmm4, qword ptr [rcx+32] 18 | cvtdq2pd xmm5, qword ptr [rcx+40] 19 | cvtdq2pd xmm6, qword ptr [rcx+48] 20 | cvtdq2pd xmm7, qword ptr [rcx+56] 21 | andps xmm4, xmm13 22 | andps xmm5, xmm13 23 | andps xmm6, xmm13 24 | andps xmm7, xmm13 25 | orps xmm4, xmm14 26 | orps xmm5, xmm14 27 | orps xmm6, xmm14 28 | orps xmm7, xmm14 29 | -------------------------------------------------------------------------------- /src/randomx/asm/program_loop_store.inc: -------------------------------------------------------------------------------- 1 | pop rcx 2 | mov qword ptr [rcx+0], r8 3 | mov qword ptr [rcx+8], r9 4 | mov qword ptr [rcx+16], r10 5 | mov qword ptr [rcx+24], r11 6 | mov qword ptr [rcx+32], r12 7 | mov qword ptr [rcx+40], r13 8 | mov qword ptr [rcx+48], r14 9 | mov qword ptr [rcx+56], r15 10 | pop rcx 11 | xorpd xmm0, xmm4 12 | xorpd xmm1, xmm5 13 | xorpd xmm2, xmm6 14 | xorpd xmm3, xmm7 15 | movapd xmmword ptr [rcx+0], xmm0 16 | movapd xmmword ptr [rcx+16], xmm1 17 | movapd xmmword ptr [rcx+32], xmm2 18 | movapd xmmword ptr [rcx+48], xmm3 19 | -------------------------------------------------------------------------------- /src/randomx/asm/program_prologue_linux.inc: -------------------------------------------------------------------------------- 1 | ;# callee-saved registers - System V AMD64 ABI 2 | push rbx 3 | push rbp 4 | push r12 5 | push r13 6 | push r14 7 | push r15 8 | 9 | ;# function arguments 10 | mov rbx, rcx ;# loop counter 11 | push rdi ;# RegisterFile& registerFile 12 | mov rcx, rdi 13 | mov rbp, qword ptr [rsi] ;# "mx", "ma" 14 | mov rdi, qword ptr [rsi+8] ;# uint8_t* dataset 15 | mov rsi, rdx ;# uint8_t* scratchpad 16 | 17 | mov rax, rbp 18 | ror rbp, 32 19 | 20 | ;# zero integer registers 21 | xor r8, r8 22 | xor r9, r9 23 | xor r10, r10 24 | xor r11, r11 25 | xor r12, r12 26 | xor r13, r13 27 | xor r14, r14 28 | xor r15, r15 29 | 30 | ;# load constant registers 31 | lea rcx, [rcx+120] 32 | movapd xmm8, xmmword ptr [rcx+72] 33 | movapd xmm9, xmmword ptr [rcx+88] 34 | movapd xmm10, xmmword ptr [rcx+104] 35 | movapd xmm11, xmmword ptr [rcx+120] 36 | -------------------------------------------------------------------------------- /src/randomx/asm/program_prologue_win64.inc: -------------------------------------------------------------------------------- 1 | ;# callee-saved registers - Microsoft x64 calling convention 2 | push rbx 3 | push rbp 4 | push rdi 5 | push rsi 6 | push r12 7 | push r13 8 | push r14 9 | push r15 10 | sub rsp, 80 11 | movdqu xmmword ptr [rsp+64], xmm6 12 | movdqu xmmword ptr [rsp+48], xmm7 13 | movdqu xmmword ptr [rsp+32], xmm8 14 | movdqu xmmword ptr [rsp+16], xmm9 15 | movdqu xmmword ptr [rsp+0], xmm10 16 | sub rsp, 80 17 | movdqu xmmword ptr [rsp+64], xmm11 18 | movdqu xmmword ptr [rsp+48], xmm12 19 | movdqu xmmword ptr [rsp+32], xmm13 20 | movdqu xmmword ptr [rsp+16], xmm14 21 | movdqu xmmword ptr [rsp+0], xmm15 22 | 23 | ;# function arguments 24 | push rcx ;# RegisterFile& registerFile 25 | mov rbp, qword ptr [rdx] ;# "mx", "ma" 26 | mov rdi, qword ptr [rdx+8] ;# uint8_t* dataset 27 | mov rsi, r8 ;# uint8_t* scratchpad 28 | mov rbx, r9 ;# loop counter 29 | 30 | mov rax, rbp 31 | ror rbp, 32 32 | 33 | ;# zero integer registers 34 | xor r8, r8 35 | xor r9, r9 36 | xor r10, r10 37 | xor r11, r11 38 | xor r12, r12 39 | xor r13, r13 40 | xor r14, r14 41 | xor r15, r15 42 | 43 | ;# load constant registers 44 | lea rcx, [rcx+120] 45 | movapd xmm8, xmmword ptr [rcx+72] 46 | movapd xmm9, xmmword ptr [rcx+88] 47 | movapd xmm10, xmmword ptr [rcx+104] 48 | movapd xmm11, xmmword ptr [rcx+120] 49 | -------------------------------------------------------------------------------- /src/randomx/asm/program_read_dataset.inc: -------------------------------------------------------------------------------- 1 | mov ecx, ebp ;# ecx = ma 2 | and ecx, RANDOMX_DATASET_BASE_MASK 3 | xor r8, qword ptr [rdi+rcx] 4 | ror rbp, 32 ;# swap "ma" and "mx" 5 | xor rbp, rax ;# modify "mx" 6 | mov edx, ebp ;# edx = mx 7 | and edx, RANDOMX_DATASET_BASE_MASK 8 | prefetchnta byte ptr [rdi+rdx] 9 | xor r9, qword ptr [rdi+rcx+8] 10 | xor r10, qword ptr [rdi+rcx+16] 11 | xor r11, qword ptr [rdi+rcx+24] 12 | xor r12, qword ptr [rdi+rcx+32] 13 | xor r13, qword ptr [rdi+rcx+40] 14 | xor r14, qword ptr [rdi+rcx+48] 15 | xor r15, qword ptr [rdi+rcx+56] 16 | -------------------------------------------------------------------------------- /src/randomx/asm/program_read_dataset_sshash_fin.inc: -------------------------------------------------------------------------------- 1 | mov rbx, qword ptr [rsp+64] 2 | xor r8, qword ptr [rsp+56] 3 | xor r9, qword ptr [rsp+48] 4 | xor r10, qword ptr [rsp+40] 5 | xor r11, qword ptr [rsp+32] 6 | xor r12, qword ptr [rsp+24] 7 | xor r13, qword ptr [rsp+16] 8 | xor r14, qword ptr [rsp+8] 9 | xor r15, qword ptr [rsp+0] 10 | add rsp, 72 -------------------------------------------------------------------------------- /src/randomx/asm/program_read_dataset_sshash_init.inc: -------------------------------------------------------------------------------- 1 | sub rsp, 72 2 | mov qword ptr [rsp+64], rbx 3 | mov qword ptr [rsp+56], r8 4 | mov qword ptr [rsp+48], r9 5 | mov qword ptr [rsp+40], r10 6 | mov qword ptr [rsp+32], r11 7 | mov qword ptr [rsp+24], r12 8 | mov qword ptr [rsp+16], r13 9 | mov qword ptr [rsp+8], r14 10 | mov qword ptr [rsp+0], r15 11 | ror rbp, 32 ;# swap "ma" and "mx" 12 | xor rbp, rax ;# modify "mx" 13 | mov rbx, rbp ;# ebx = ma 14 | shr rbx, 38 15 | and ebx, RANDOMX_DATASET_BASE_MASK / 64 ;# ebx = Dataset block number 16 | ;# add ebx, datasetOffset / 64 17 | ;# call 32768 -------------------------------------------------------------------------------- /src/randomx/asm/program_sshash_constants.inc: -------------------------------------------------------------------------------- 1 | r0_mul: 2 | ;#/ 6364136223846793005 3 | db 45, 127, 149, 76, 45, 244, 81, 88 4 | r1_add: 5 | ;#/ 9298411001130361340 6 | db 252, 161, 245, 89, 138, 151, 10, 129 7 | r2_add: 8 | ;#/ 12065312585734608966 9 | db 70, 216, 194, 56, 223, 153, 112, 167 10 | r3_add: 11 | ;#/ 9306329213124626780 12 | db 92, 73, 34, 191, 28, 185, 38, 129 13 | r4_add: 14 | ;#/ 5281919268842080866 15 | db 98, 138, 159, 23, 151, 37, 77, 73 16 | r5_add: 17 | ;#/ 10536153434571861004 18 | db 12, 236, 170, 206, 185, 239, 55, 146 19 | r6_add: 20 | ;#/ 3398623926847679864 21 | db 120, 45, 230, 108, 116, 86, 42, 47 22 | r7_add: 23 | ;#/ 9549104520008361294 24 | db 78, 229, 44, 182, 247, 59, 133, 132 -------------------------------------------------------------------------------- /src/randomx/asm/program_sshash_load.inc: -------------------------------------------------------------------------------- 1 | xor r8, qword ptr [rbx+0] 2 | xor r9, qword ptr [rbx+8] 3 | xor r10, qword ptr [rbx+16] 4 | xor r11, qword ptr [rbx+24] 5 | xor r12, qword ptr [rbx+32] 6 | xor r13, qword ptr [rbx+40] 7 | xor r14, qword ptr [rbx+48] 8 | xor r15, qword ptr [rbx+56] -------------------------------------------------------------------------------- /src/randomx/asm/program_sshash_prefetch.inc: -------------------------------------------------------------------------------- 1 | and rbx, RANDOMX_CACHE_MASK 2 | shl rbx, 6 3 | add rbx, rdi 4 | prefetchnta byte ptr [rbx] -------------------------------------------------------------------------------- /src/randomx/asm/program_xmm_constants.inc: -------------------------------------------------------------------------------- 1 | mantissaMask: 2 | db 255, 255, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 0 3 | exp240: 4 | db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 5 | scaleMask: 6 | db 0, 0, 0, 0, 0, 0, 240, 128, 0, 0, 0, 0, 0, 0, 240, 128 -------------------------------------------------------------------------------- /src/randomx/asm/randomx_reciprocal.inc: -------------------------------------------------------------------------------- 1 | mov edx, 1 2 | mov r8, rcx 3 | xor eax, eax 4 | bsr rcx, rcx 5 | shl rdx, cl 6 | div r8 7 | ret -------------------------------------------------------------------------------- /src/randomx/assembly_generator_x86.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include "common.hpp" 32 | #include 33 | 34 | namespace randomx { 35 | 36 | class Program; 37 | class SuperscalarProgram; 38 | class AssemblyGeneratorX86; 39 | class Instruction; 40 | 41 | typedef void(AssemblyGeneratorX86::*InstructionGenerator)(Instruction&, int); 42 | 43 | class AssemblyGeneratorX86 { 44 | public: 45 | void generateProgram(Program& prog); 46 | void generateAsm(SuperscalarProgram& prog); 47 | void generateC(SuperscalarProgram& prog); 48 | void printCode(std::ostream& os) { 49 | os << asmCode.rdbuf(); 50 | } 51 | private: 52 | void genAddressReg(Instruction&, const char*); 53 | void genAddressRegDst(Instruction&, int); 54 | int32_t genAddressImm(Instruction&); 55 | void generateCode(Instruction&, int); 56 | void traceint(Instruction&); 57 | void traceflt(Instruction&); 58 | void tracenop(Instruction&); 59 | void h_IADD_RS(Instruction&, int); 60 | void h_IADD_M(Instruction&, int); 61 | void h_ISUB_R(Instruction&, int); 62 | void h_ISUB_M(Instruction&, int); 63 | void h_IMUL_R(Instruction&, int); 64 | void h_IMUL_M(Instruction&, int); 65 | void h_IMULH_R(Instruction&, int); 66 | void h_IMULH_M(Instruction&, int); 67 | void h_ISMULH_R(Instruction&, int); 68 | void h_ISMULH_M(Instruction&, int); 69 | void h_IMUL_RCP(Instruction&, int); 70 | void h_INEG_R(Instruction&, int); 71 | void h_IXOR_R(Instruction&, int); 72 | void h_IXOR_M(Instruction&, int); 73 | void h_IROR_R(Instruction&, int); 74 | void h_IROL_R(Instruction&, int); 75 | void h_ISWAP_R(Instruction&, int); 76 | void h_FSWAP_R(Instruction&, int); 77 | void h_FADD_R(Instruction&, int); 78 | void h_FADD_M(Instruction&, int); 79 | void h_FSUB_R(Instruction&, int); 80 | void h_FSUB_M(Instruction&, int); 81 | void h_FSCAL_R(Instruction&, int); 82 | void h_FMUL_R(Instruction&, int); 83 | void h_FDIV_M(Instruction&, int); 84 | void h_FSQRT_R(Instruction&, int); 85 | void h_CBRANCH(Instruction&, int); 86 | void h_CFROUND(Instruction&, int); 87 | void h_ISTORE(Instruction&, int); 88 | void h_NOP(Instruction&, int); 89 | 90 | static InstructionGenerator engine[256]; 91 | std::stringstream asmCode; 92 | int registerUsage[RegistersCount]; 93 | }; 94 | } -------------------------------------------------------------------------------- /src/randomx/blake2/blake2-impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* Original code from Argon2 reference source code package used under CC0 Licence 30 | * https://github.com/P-H-C/phc-winner-argon2 31 | * Copyright 2015 32 | * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves 33 | */ 34 | 35 | #ifndef PORTABLE_BLAKE2_IMPL_H 36 | #define PORTABLE_BLAKE2_IMPL_H 37 | 38 | #include 39 | 40 | #include "endian.h" 41 | 42 | static FORCE_INLINE uint64_t load48(const void *src) { 43 | const uint8_t *p = (const uint8_t *)src; 44 | uint64_t w = *p++; 45 | w |= (uint64_t)(*p++) << 8; 46 | w |= (uint64_t)(*p++) << 16; 47 | w |= (uint64_t)(*p++) << 24; 48 | w |= (uint64_t)(*p++) << 32; 49 | w |= (uint64_t)(*p++) << 40; 50 | return w; 51 | } 52 | 53 | static FORCE_INLINE void store48(void *dst, uint64_t w) { 54 | uint8_t *p = (uint8_t *)dst; 55 | *p++ = (uint8_t)w; 56 | w >>= 8; 57 | *p++ = (uint8_t)w; 58 | w >>= 8; 59 | *p++ = (uint8_t)w; 60 | w >>= 8; 61 | *p++ = (uint8_t)w; 62 | w >>= 8; 63 | *p++ = (uint8_t)w; 64 | w >>= 8; 65 | *p++ = (uint8_t)w; 66 | } 67 | 68 | static FORCE_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) { 69 | return (w >> c) | (w << (32 - c)); 70 | } 71 | 72 | static FORCE_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) { 73 | return (w >> c) | (w << (64 - c)); 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/randomx/blake2/blake2.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* Original code from Argon2 reference source code package used under CC0 Licence 30 | * https://github.com/P-H-C/phc-winner-argon2 31 | * Copyright 2015 32 | * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves 33 | */ 34 | 35 | #ifndef PORTABLE_BLAKE2_H 36 | #define PORTABLE_BLAKE2_H 37 | 38 | #include 39 | #include 40 | 41 | #if defined(__cplusplus) 42 | extern "C" { 43 | #endif 44 | 45 | enum blake2b_constant { 46 | BLAKE2B_BLOCKBYTES = 128, 47 | BLAKE2B_OUTBYTES = 64, 48 | BLAKE2B_KEYBYTES = 64, 49 | BLAKE2B_SALTBYTES = 16, 50 | BLAKE2B_PERSONALBYTES = 16 51 | }; 52 | 53 | #pragma pack(push, 1) 54 | typedef struct __blake2b_param { 55 | uint8_t digest_length; /* 1 */ 56 | uint8_t key_length; /* 2 */ 57 | uint8_t fanout; /* 3 */ 58 | uint8_t depth; /* 4 */ 59 | uint32_t leaf_length; /* 8 */ 60 | uint64_t node_offset; /* 16 */ 61 | uint8_t node_depth; /* 17 */ 62 | uint8_t inner_length; /* 18 */ 63 | uint8_t reserved[14]; /* 32 */ 64 | uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ 65 | uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ 66 | } blake2b_param; 67 | #pragma pack(pop) 68 | 69 | typedef struct __blake2b_state { 70 | uint64_t h[8]; 71 | uint64_t t[2]; 72 | uint64_t f[2]; 73 | uint8_t buf[BLAKE2B_BLOCKBYTES]; 74 | unsigned buflen; 75 | unsigned outlen; 76 | uint8_t last_node; 77 | } blake2b_state; 78 | 79 | /* Ensure param structs have not been wrongly padded */ 80 | /* Poor man's static_assert */ 81 | enum { 82 | blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), 83 | blake2_size_check_2 = 84 | 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) 85 | }; 86 | 87 | //randomx namespace 88 | #define blake2b_init randomx_blake2b_init 89 | #define blake2b_init_key randomx_blake2b_init_key 90 | #define blake2b_init_param randomx_blake2b_init_param 91 | #define blake2b_update randomx_blake2b_update 92 | #define blake2b_final randomx_blake2b_final 93 | #define blake2b randomx_blake2b 94 | #define blake2b_long randomx_blake2b_long 95 | 96 | /* Streaming API */ 97 | int blake2b_init(blake2b_state *S, size_t outlen); 98 | int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, 99 | size_t keylen); 100 | int blake2b_init_param(blake2b_state *S, const blake2b_param *P); 101 | int blake2b_update(blake2b_state *S, const void *in, size_t inlen); 102 | int blake2b_final(blake2b_state *S, void *out, size_t outlen); 103 | 104 | /* Simple API */ 105 | int blake2b(void *out, size_t outlen, const void *in, size_t inlen, 106 | const void *key, size_t keylen); 107 | 108 | /* Argon2 Team - Begin Code */ 109 | int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); 110 | /* Argon2 Team - End Code */ 111 | 112 | #if defined(__cplusplus) 113 | } 114 | #endif 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/randomx/blake2/blamka-round-ref.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* Original code from Argon2 reference source code package used under CC0 Licence 30 | * https://github.com/P-H-C/phc-winner-argon2 31 | * Copyright 2015 32 | * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves 33 | */ 34 | 35 | #ifndef BLAKE_ROUND_MKA_H 36 | #define BLAKE_ROUND_MKA_H 37 | 38 | #include "blake2.h" 39 | #include "blake2-impl.h" 40 | 41 | /* designed by the Lyra PHC team */ 42 | static FORCE_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { 43 | const uint64_t m = UINT64_C(0xFFFFFFFF); 44 | const uint64_t xy = (x & m) * (y & m); 45 | return x + y + 2 * xy; 46 | } 47 | 48 | #define G(a, b, c, d) \ 49 | do { \ 50 | a = fBlaMka(a, b); \ 51 | d = rotr64(d ^ a, 32); \ 52 | c = fBlaMka(c, d); \ 53 | b = rotr64(b ^ c, 24); \ 54 | a = fBlaMka(a, b); \ 55 | d = rotr64(d ^ a, 16); \ 56 | c = fBlaMka(c, d); \ 57 | b = rotr64(b ^ c, 63); \ 58 | } while ((void)0, 0) 59 | 60 | #define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ 61 | v12, v13, v14, v15) \ 62 | do { \ 63 | G(v0, v4, v8, v12); \ 64 | G(v1, v5, v9, v13); \ 65 | G(v2, v6, v10, v14); \ 66 | G(v3, v7, v11, v15); \ 67 | G(v0, v5, v10, v15); \ 68 | G(v1, v6, v11, v12); \ 69 | G(v2, v7, v8, v13); \ 70 | G(v3, v4, v9, v14); \ 71 | } while ((void)0, 0) 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/randomx/blake2/endian.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #if defined(_MSC_VER) 6 | #define FORCE_INLINE __inline 7 | #elif defined(__GNUC__) || defined(__clang__) 8 | #define FORCE_INLINE __inline__ 9 | #else 10 | #define FORCE_INLINE 11 | #endif 12 | 13 | /* Argon2 Team - Begin Code */ 14 | /* 15 | Not an exhaustive list, but should cover the majority of modern platforms 16 | Additionally, the code will always be correct---this is only a performance 17 | tweak. 18 | */ 19 | #if (defined(__BYTE_ORDER__) && \ 20 | (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ 21 | defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \ 22 | defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \ 23 | defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \ 24 | defined(_M_ARM) 25 | #define NATIVE_LITTLE_ENDIAN 26 | #endif 27 | /* Argon2 Team - End Code */ 28 | 29 | static FORCE_INLINE uint32_t load32(const void *src) { 30 | #if defined(NATIVE_LITTLE_ENDIAN) 31 | uint32_t w; 32 | memcpy(&w, src, sizeof w); 33 | return w; 34 | #else 35 | const uint8_t *p = (const uint8_t *)src; 36 | uint32_t w = *p++; 37 | w |= (uint32_t)(*p++) << 8; 38 | w |= (uint32_t)(*p++) << 16; 39 | w |= (uint32_t)(*p++) << 24; 40 | return w; 41 | #endif 42 | } 43 | 44 | static FORCE_INLINE uint64_t load64_native(const void *src) { 45 | uint64_t w; 46 | memcpy(&w, src, sizeof w); 47 | return w; 48 | } 49 | 50 | static FORCE_INLINE uint64_t load64(const void *src) { 51 | #if defined(NATIVE_LITTLE_ENDIAN) 52 | return load64_native(src); 53 | #else 54 | const uint8_t *p = (const uint8_t *)src; 55 | uint64_t w = *p++; 56 | w |= (uint64_t)(*p++) << 8; 57 | w |= (uint64_t)(*p++) << 16; 58 | w |= (uint64_t)(*p++) << 24; 59 | w |= (uint64_t)(*p++) << 32; 60 | w |= (uint64_t)(*p++) << 40; 61 | w |= (uint64_t)(*p++) << 48; 62 | w |= (uint64_t)(*p++) << 56; 63 | return w; 64 | #endif 65 | } 66 | 67 | static FORCE_INLINE void store32(void *dst, uint32_t w) { 68 | #if defined(NATIVE_LITTLE_ENDIAN) 69 | memcpy(dst, &w, sizeof w); 70 | #else 71 | uint8_t *p = (uint8_t *)dst; 72 | *p++ = (uint8_t)w; 73 | w >>= 8; 74 | *p++ = (uint8_t)w; 75 | w >>= 8; 76 | *p++ = (uint8_t)w; 77 | w >>= 8; 78 | *p++ = (uint8_t)w; 79 | #endif 80 | } 81 | 82 | static FORCE_INLINE void store64_native(void *dst, uint64_t w) { 83 | memcpy(dst, &w, sizeof w); 84 | } 85 | 86 | static FORCE_INLINE void store64(void *dst, uint64_t w) { 87 | #if defined(NATIVE_LITTLE_ENDIAN) 88 | store64_native(dst, w); 89 | #else 90 | uint8_t *p = (uint8_t *)dst; 91 | *p++ = (uint8_t)w; 92 | w >>= 8; 93 | *p++ = (uint8_t)w; 94 | w >>= 8; 95 | *p++ = (uint8_t)w; 96 | w >>= 8; 97 | *p++ = (uint8_t)w; 98 | w >>= 8; 99 | *p++ = (uint8_t)w; 100 | w >>= 8; 101 | *p++ = (uint8_t)w; 102 | w >>= 8; 103 | *p++ = (uint8_t)w; 104 | w >>= 8; 105 | *p++ = (uint8_t)w; 106 | #endif 107 | } 108 | -------------------------------------------------------------------------------- /src/randomx/blake2_generator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include "blake2/blake2.h" 31 | #include "blake2/endian.h" 32 | #include "blake2_generator.hpp" 33 | 34 | namespace randomx { 35 | 36 | constexpr int maxSeedSize = 60; 37 | 38 | Blake2Generator::Blake2Generator(const void* seed, size_t seedSize, int nonce) : dataIndex(sizeof(data)) { 39 | memset(data, 0, sizeof(data)); 40 | memcpy(data, seed, seedSize > maxSeedSize ? maxSeedSize : seedSize); 41 | store32(&data[maxSeedSize], nonce); 42 | } 43 | 44 | uint8_t Blake2Generator::getByte() { 45 | checkData(1); 46 | return data[dataIndex++]; 47 | } 48 | 49 | uint32_t Blake2Generator::getUInt32() { 50 | checkData(4); 51 | auto ret = load32(&data[dataIndex]); 52 | dataIndex += 4; 53 | return ret; 54 | } 55 | 56 | void Blake2Generator::checkData(const size_t bytesNeeded) { 57 | if (dataIndex + bytesNeeded > sizeof(data)) { 58 | blake2b(data, sizeof(data), data, sizeof(data), nullptr, 0); 59 | dataIndex = 0; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/randomx/blake2_generator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | namespace randomx { 34 | 35 | class Blake2Generator { 36 | public: 37 | Blake2Generator(const void* seed, size_t seedSize, int nonce = 0); 38 | uint8_t getByte(); 39 | uint32_t getUInt32(); 40 | private: 41 | void checkData(const size_t); 42 | 43 | uint8_t data[64]; 44 | size_t dataIndex; 45 | }; 46 | } -------------------------------------------------------------------------------- /src/randomx/configuration.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | //Cache size in KiB. Must be a power of 2. 32 | #define RANDOMX_ARGON_MEMORY 262144 33 | 34 | //Number of Argon2d iterations for Cache initialization. 35 | #define RANDOMX_ARGON_ITERATIONS 3 36 | 37 | //Number of parallel lanes for Cache initialization. 38 | #define RANDOMX_ARGON_LANES 1 39 | 40 | //Argon2d salt 41 | #define RANDOMX_ARGON_SALT "RandomX\x03" 42 | 43 | //Number of random Cache accesses per Dataset item. Minimum is 2. 44 | #define RANDOMX_CACHE_ACCESSES 8 45 | 46 | //Target latency for SuperscalarHash (in cycles of the reference CPU). 47 | #define RANDOMX_SUPERSCALAR_LATENCY 170 48 | 49 | //Dataset base size in bytes. Must be a power of 2. 50 | #define RANDOMX_DATASET_BASE_SIZE 2147483648 51 | 52 | //Dataset extra size. Must be divisible by 64. 53 | #define RANDOMX_DATASET_EXTRA_SIZE 33554368 54 | 55 | //Number of instructions in a RandomX program. Must be divisible by 8. 56 | #define RANDOMX_PROGRAM_SIZE 256 57 | 58 | //Number of iterations during VM execution. 59 | #define RANDOMX_PROGRAM_ITERATIONS 2048 60 | 61 | //Number of chained VM executions per hash. 62 | #define RANDOMX_PROGRAM_COUNT 8 63 | 64 | //Scratchpad L3 size in bytes. Must be a power of 2. 65 | #define RANDOMX_SCRATCHPAD_L3 2097152 66 | 67 | //Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3. 68 | #define RANDOMX_SCRATCHPAD_L2 262144 69 | 70 | //Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2. 71 | #define RANDOMX_SCRATCHPAD_L1 16384 72 | 73 | //Jump condition mask size in bits. 74 | #define RANDOMX_JUMP_BITS 8 75 | 76 | //Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16. 77 | #define RANDOMX_JUMP_OFFSET 8 78 | 79 | /* 80 | Instruction frequencies (per 256 opcodes) 81 | Total sum of frequencies must be 256 82 | */ 83 | 84 | //Integer instructions 85 | #define RANDOMX_FREQ_IADD_RS 16 86 | #define RANDOMX_FREQ_IADD_M 7 87 | #define RANDOMX_FREQ_ISUB_R 16 88 | #define RANDOMX_FREQ_ISUB_M 7 89 | #define RANDOMX_FREQ_IMUL_R 16 90 | #define RANDOMX_FREQ_IMUL_M 4 91 | #define RANDOMX_FREQ_IMULH_R 4 92 | #define RANDOMX_FREQ_IMULH_M 1 93 | #define RANDOMX_FREQ_ISMULH_R 4 94 | #define RANDOMX_FREQ_ISMULH_M 1 95 | #define RANDOMX_FREQ_IMUL_RCP 8 96 | #define RANDOMX_FREQ_INEG_R 2 97 | #define RANDOMX_FREQ_IXOR_R 15 98 | #define RANDOMX_FREQ_IXOR_M 5 99 | #define RANDOMX_FREQ_IROR_R 8 100 | #define RANDOMX_FREQ_IROL_R 2 101 | #define RANDOMX_FREQ_ISWAP_R 4 102 | 103 | //Floating point instructions 104 | #define RANDOMX_FREQ_FSWAP_R 4 105 | #define RANDOMX_FREQ_FADD_R 16 106 | #define RANDOMX_FREQ_FADD_M 5 107 | #define RANDOMX_FREQ_FSUB_R 16 108 | #define RANDOMX_FREQ_FSUB_M 5 109 | #define RANDOMX_FREQ_FSCAL_R 6 110 | #define RANDOMX_FREQ_FMUL_R 32 111 | #define RANDOMX_FREQ_FDIV_M 4 112 | #define RANDOMX_FREQ_FSQRT_R 6 113 | 114 | //Control instructions 115 | #define RANDOMX_FREQ_CBRANCH 25 116 | #define RANDOMX_FREQ_CFROUND 1 117 | 118 | //Store instruction 119 | #define RANDOMX_FREQ_ISTORE 16 120 | 121 | //No-op instruction 122 | #define RANDOMX_FREQ_NOP 0 123 | /* ------ 124 | 256 125 | */ 126 | -------------------------------------------------------------------------------- /src/randomx/cpu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "cpu.hpp" 30 | 31 | #if defined(_M_X64) || defined(__x86_64__) 32 | #define HAVE_CPUID 33 | #if defined(_MSC_VER) 34 | #include 35 | #define cpuid(info, x) __cpuidex(info, x, 0) 36 | #else //GCC 37 | #include 38 | void cpuid(int info[4], int InfoType) { 39 | __cpuid_count(InfoType, 0, info[0], info[1], info[2], info[3]); 40 | } 41 | #endif 42 | #endif 43 | 44 | #if defined(HAVE_HWCAP) 45 | #include 46 | #include 47 | #endif 48 | 49 | namespace randomx { 50 | 51 | Cpu::Cpu() : aes_(false), ssse3_(false), avx2_(false) { 52 | #ifdef HAVE_CPUID 53 | int info[4]; 54 | cpuid(info, 0); 55 | int nIds = info[0]; 56 | if (nIds >= 0x00000001) { 57 | cpuid(info, 0x00000001); 58 | ssse3_ = (info[2] & (1 << 9)) != 0; 59 | aes_ = (info[2] & (1 << 25)) != 0; 60 | } 61 | if (nIds >= 0x00000007) { 62 | cpuid(info, 0x00000007); 63 | avx2_ = (info[1] & (1 << 5)) != 0; 64 | } 65 | #elif defined(__aarch64__) 66 | #if defined(HWCAP_AES) 67 | long hwcaps = getauxval(AT_HWCAP); 68 | aes_ = (hwcaps & HWCAP_AES) != 0; 69 | #elif defined(__APPLE__) 70 | aes_ = true; 71 | #endif 72 | #endif 73 | //TODO POWER8 AES 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/randomx/cpu.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | namespace randomx { 32 | 33 | class Cpu { 34 | public: 35 | Cpu(); 36 | bool hasAes() const { 37 | return aes_; 38 | } 39 | bool hasSsse3() const { 40 | return ssse3_; 41 | } 42 | bool hasAvx2() const { 43 | return avx2_; 44 | } 45 | private: 46 | bool aes_, ssse3_, avx2_; 47 | }; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/randomx/dataset.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | #include "common.hpp" 35 | #include "superscalar_program.hpp" 36 | #include "allocator.hpp" 37 | #include "argon2.h" 38 | 39 | /* Global scope for C binding */ 40 | struct randomx_dataset { 41 | uint8_t* memory = nullptr; 42 | randomx::DatasetDeallocFunc* dealloc; 43 | }; 44 | 45 | /* Global scope for C binding */ 46 | struct randomx_cache { 47 | uint8_t* memory = nullptr; 48 | randomx::CacheDeallocFunc* dealloc; 49 | randomx::JitCompiler* jit; 50 | randomx::CacheInitializeFunc* initialize; 51 | randomx::DatasetInitFunc* datasetInit; 52 | randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES]; 53 | std::vector reciprocalCache; 54 | std::string cacheKey; 55 | randomx_argon2_impl* argonImpl; 56 | 57 | bool isInitialized() { 58 | return programs[0].getSize() != 0; 59 | } 60 | }; 61 | 62 | //A pointer to a standard-layout struct object points to its initial member 63 | static_assert(std::is_standard_layout(), "randomx_dataset must be a standard-layout struct"); 64 | 65 | //the following assert fails when compiling Debug in Visual Studio (JIT mode will crash in Debug) 66 | #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_DEBUG) 67 | #define TO_STR(x) #x 68 | #define STR(x) TO_STR(x) 69 | #pragma message ( __FILE__ "(" STR(__LINE__) ") warning: check std::is_standard_layout() is disabled for Debug configuration. JIT mode will crash." ) 70 | #undef STR 71 | #undef TO_STR 72 | #else 73 | static_assert(std::is_standard_layout(), "randomx_cache must be a standard-layout struct"); 74 | #endif 75 | 76 | namespace randomx { 77 | 78 | using DefaultAllocator = AlignedAllocator; 79 | 80 | template 81 | void deallocDataset(randomx_dataset* dataset) { 82 | if (dataset->memory != nullptr) 83 | Allocator::freeMemory(dataset->memory, DatasetSize); 84 | } 85 | 86 | template 87 | void deallocCache(randomx_cache* cache); 88 | 89 | void initCache(randomx_cache*, const void*, size_t); 90 | void initCacheCompile(randomx_cache*, const void*, size_t); 91 | void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber); 92 | void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock); 93 | 94 | inline randomx_argon2_impl* selectArgonImpl(randomx_flags flags) { 95 | if (flags & RANDOMX_FLAG_ARGON2_AVX2) { 96 | return randomx_argon2_impl_avx2(); 97 | } 98 | if (flags & RANDOMX_FLAG_ARGON2_SSSE3) { 99 | return randomx_argon2_impl_ssse3(); 100 | } 101 | return &randomx_argon2_fill_segment_ref; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/randomx/instruction.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | #include "blake2/endian.h" 35 | 36 | namespace randomx { 37 | 38 | class Instruction; 39 | 40 | typedef void(Instruction::*InstructionFormatter)(std::ostream&) const; 41 | 42 | enum class InstructionType : uint16_t { 43 | IADD_RS = 0, 44 | IADD_M = 1, 45 | ISUB_R = 2, 46 | ISUB_M = 3, 47 | IMUL_R = 4, 48 | IMUL_M = 5, 49 | IMULH_R = 6, 50 | IMULH_M = 7, 51 | ISMULH_R = 8, 52 | ISMULH_M = 9, 53 | IMUL_RCP = 10, 54 | INEG_R = 11, 55 | IXOR_R = 12, 56 | IXOR_M = 13, 57 | IROR_R = 14, 58 | IROL_R = 15, 59 | ISWAP_R = 16, 60 | FSWAP_R = 17, 61 | FADD_R = 18, 62 | FADD_M = 19, 63 | FSUB_R = 20, 64 | FSUB_M = 21, 65 | FSCAL_R = 22, 66 | FMUL_R = 23, 67 | FDIV_M = 24, 68 | FSQRT_R = 25, 69 | CBRANCH = 26, 70 | CFROUND = 27, 71 | ISTORE = 28, 72 | NOP = 29, 73 | }; 74 | 75 | class Instruction { 76 | public: 77 | uint32_t getImm32() const { 78 | return load32(&imm32); 79 | } 80 | void setImm32(uint32_t val) { 81 | return store32(&imm32, val); 82 | } 83 | const char* getName() const { 84 | return names[opcode]; 85 | } 86 | friend std::ostream& operator<<(std::ostream& os, const Instruction& i) { 87 | i.print(os); 88 | return os; 89 | } 90 | int getModMem() const { 91 | return mod % 4; //bits 0-1 92 | } 93 | int getModShift() const { 94 | return (mod >> 2) % 4; //bits 2-3 95 | } 96 | int getModCond() const { 97 | return mod >> 4; //bits 4-7 98 | } 99 | void setMod(uint8_t val) { 100 | mod = val; 101 | } 102 | 103 | uint8_t opcode; 104 | uint8_t dst; 105 | uint8_t src; 106 | uint8_t mod; 107 | uint32_t imm32; 108 | private: 109 | void print(std::ostream&) const; 110 | static const char* names[256]; 111 | static InstructionFormatter engine[256]; 112 | void genAddressReg(std::ostream& os, int) const; 113 | void genAddressImm(std::ostream& os) const; 114 | void genAddressRegDst(std::ostream&, int) const; 115 | void h_IADD_RS(std::ostream&) const; 116 | void h_IADD_M(std::ostream&) const; 117 | void h_ISUB_R(std::ostream&) const; 118 | void h_ISUB_M(std::ostream&) const; 119 | void h_IMUL_R(std::ostream&) const; 120 | void h_IMUL_M(std::ostream&) const; 121 | void h_IMULH_R(std::ostream&) const; 122 | void h_IMULH_M(std::ostream&) const; 123 | void h_ISMULH_R(std::ostream&) const; 124 | void h_ISMULH_M(std::ostream&) const; 125 | void h_IMUL_RCP(std::ostream&) const; 126 | void h_INEG_R(std::ostream&) const; 127 | void h_IXOR_R(std::ostream&) const; 128 | void h_IXOR_M(std::ostream&) const; 129 | void h_IROR_R(std::ostream&) const; 130 | void h_IROL_R(std::ostream&) const; 131 | void h_ISWAP_R(std::ostream&) const; 132 | void h_FSWAP_R(std::ostream&) const; 133 | void h_FADD_R(std::ostream&) const; 134 | void h_FADD_M(std::ostream&) const; 135 | void h_FSUB_R(std::ostream&) const; 136 | void h_FSUB_M(std::ostream&) const; 137 | void h_FSCAL_R(std::ostream&) const; 138 | void h_FMUL_R(std::ostream&) const; 139 | void h_FDIV_M(std::ostream&) const; 140 | void h_FSQRT_R(std::ostream&) const; 141 | void h_CBRANCH(std::ostream&) const; 142 | void h_CFROUND(std::ostream&) const; 143 | void h_ISTORE(std::ostream&) const; 144 | void h_NOP(std::ostream&) const; 145 | }; 146 | 147 | static_assert(sizeof(Instruction) == 8, "Invalid size of struct randomx::Instruction"); 148 | static_assert(std::is_standard_layout(), "randomx::Instruction must be a standard-layout struct"); 149 | } -------------------------------------------------------------------------------- /src/randomx/instruction_weights.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #define REP0(x) 32 | #define REP1(x) x, 33 | #define REP2(x) REP1(x) x, 34 | #define REP3(x) REP2(x) x, 35 | #define REP4(x) REP3(x) x, 36 | #define REP5(x) REP4(x) x, 37 | #define REP6(x) REP5(x) x, 38 | #define REP7(x) REP6(x) x, 39 | #define REP8(x) REP7(x) x, 40 | #define REP9(x) REP8(x) x, 41 | #define REP10(x) REP9(x) x, 42 | #define REP11(x) REP10(x) x, 43 | #define REP12(x) REP11(x) x, 44 | #define REP13(x) REP12(x) x, 45 | #define REP14(x) REP13(x) x, 46 | #define REP15(x) REP14(x) x, 47 | #define REP16(x) REP15(x) x, 48 | #define REP17(x) REP16(x) x, 49 | #define REP18(x) REP17(x) x, 50 | #define REP19(x) REP18(x) x, 51 | #define REP20(x) REP19(x) x, 52 | #define REP21(x) REP20(x) x, 53 | #define REP22(x) REP21(x) x, 54 | #define REP23(x) REP22(x) x, 55 | #define REP24(x) REP23(x) x, 56 | #define REP25(x) REP24(x) x, 57 | #define REP26(x) REP25(x) x, 58 | #define REP27(x) REP26(x) x, 59 | #define REP28(x) REP27(x) x, 60 | #define REP29(x) REP28(x) x, 61 | #define REP30(x) REP29(x) x, 62 | #define REP31(x) REP30(x) x, 63 | #define REP32(x) REP31(x) x, 64 | #define REP33(x) REP32(x) x, 65 | #define REP40(x) REP32(x) REP8(x) 66 | #define REP64(x) REP32(x) REP32(x) 67 | #define REP128(x) REP32(x) REP32(x) REP32(x) REP32(x) 68 | #define REP232(x) REP128(x) REP40(x) REP40(x) REP24(x) 69 | #define REP256(x) REP128(x) REP128(x) 70 | #define REPNX(x,N) REP##N(x) 71 | #define REPN(x,N) REPNX(x,N) 72 | #define NUM(x) x 73 | #define WT(x) NUM(RANDOMX_FREQ_##x) 74 | -------------------------------------------------------------------------------- /src/randomx/jit_compiler.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #if defined(_M_X64) || defined(__x86_64__) 32 | #include "jit_compiler_x86.hpp" 33 | #elif defined(__aarch64__) 34 | #include "jit_compiler_a64.hpp" 35 | #else 36 | #include "jit_compiler_fallback.hpp" 37 | #endif 38 | 39 | #if defined(__OpenBSD__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__aarch64__)) 40 | #define RANDOMX_FORCE_SECURE 41 | #endif 42 | -------------------------------------------------------------------------------- /src/randomx/jit_compiler_a64_static.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | Copyright (c) 2019, SChernykh 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the copyright holder nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #pragma once 31 | 32 | extern "C" { 33 | void randomx_program_aarch64(void* reg, void* mem, void* scratchpad, uint64_t iterations); 34 | void randomx_program_aarch64_main_loop(); 35 | void randomx_program_aarch64_vm_instructions(); 36 | void randomx_program_aarch64_imul_rcp_literals_end(); 37 | void randomx_program_aarch64_vm_instructions_end(); 38 | void randomx_program_aarch64_cacheline_align_mask1(); 39 | void randomx_program_aarch64_cacheline_align_mask2(); 40 | void randomx_program_aarch64_update_spMix1(); 41 | void randomx_program_aarch64_vm_instructions_end_light(); 42 | void randomx_program_aarch64_light_cacheline_align_mask(); 43 | void randomx_program_aarch64_light_dataset_offset(); 44 | void randomx_init_dataset_aarch64(); 45 | void randomx_init_dataset_aarch64_end(); 46 | void randomx_calc_dataset_item_aarch64(); 47 | void randomx_calc_dataset_item_aarch64_prefetch(); 48 | void randomx_calc_dataset_item_aarch64_mix(); 49 | void randomx_calc_dataset_item_aarch64_store_result(); 50 | void randomx_calc_dataset_item_aarch64_end(); 51 | } 52 | -------------------------------------------------------------------------------- /src/randomx/jit_compiler_fallback.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | #include "common.hpp" 35 | 36 | namespace randomx { 37 | 38 | class Program; 39 | struct ProgramConfiguration; 40 | class SuperscalarProgram; 41 | 42 | class JitCompilerFallback { 43 | public: 44 | JitCompilerFallback() { 45 | throw std::runtime_error("JIT compilation is not supported on this platform"); 46 | } 47 | void generateProgram(Program&, ProgramConfiguration&) { 48 | 49 | } 50 | void generateProgramLight(Program&, ProgramConfiguration&, uint32_t) { 51 | 52 | } 53 | template 54 | void generateSuperscalarHash(SuperscalarProgram(&programs)[N], std::vector &) { 55 | 56 | } 57 | void generateDatasetInitCode() { 58 | 59 | } 60 | ProgramFunc* getProgramFunc() { 61 | return nullptr; 62 | } 63 | DatasetInitFunc* getDatasetInitFunc() { 64 | return nullptr; 65 | } 66 | uint8_t* getCode() { 67 | return nullptr; 68 | } 69 | size_t getCodeSize() { 70 | return 0; 71 | } 72 | void enableWriting() {} 73 | void enableExecution() {} 74 | void enableAll() {} 75 | }; 76 | } -------------------------------------------------------------------------------- /src/randomx/jit_compiler_x86_static.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | extern "C" { 32 | void randomx_prefetch_scratchpad(); 33 | void randomx_prefetch_scratchpad_end(); 34 | void randomx_program_prologue(); 35 | void randomx_program_loop_begin(); 36 | void randomx_program_loop_load(); 37 | void randomx_program_start(); 38 | void randomx_program_read_dataset(); 39 | void randomx_program_read_dataset_sshash_init(); 40 | void randomx_program_read_dataset_sshash_fin(); 41 | void randomx_program_loop_store(); 42 | void randomx_program_loop_end(); 43 | void randomx_dataset_init(); 44 | void randomx_program_epilogue(); 45 | void randomx_sshash_load(); 46 | void randomx_sshash_prefetch(); 47 | void randomx_sshash_end(); 48 | void randomx_sshash_init(); 49 | void randomx_program_end(); 50 | } 51 | -------------------------------------------------------------------------------- /src/randomx/program.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include "common.hpp" 34 | #include "instruction.hpp" 35 | #include "blake2/endian.h" 36 | 37 | namespace randomx { 38 | 39 | struct ProgramConfiguration { 40 | uint64_t eMask[2]; 41 | uint32_t readReg0, readReg1, readReg2, readReg3; 42 | }; 43 | 44 | class Program { 45 | public: 46 | Instruction& operator()(int pc) { 47 | return programBuffer[pc]; 48 | } 49 | friend std::ostream& operator<<(std::ostream& os, const Program& p) { 50 | p.print(os); 51 | return os; 52 | } 53 | uint64_t getEntropy(int i) { 54 | return load64(&entropyBuffer[i]); 55 | } 56 | uint32_t getSize() { 57 | return RANDOMX_PROGRAM_SIZE; 58 | } 59 | private: 60 | void print(std::ostream& os) const { 61 | for (int i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) { 62 | auto instr = programBuffer[i]; 63 | os << instr; 64 | } 65 | } 66 | uint64_t entropyBuffer[16]; 67 | Instruction programBuffer[RANDOMX_PROGRAM_SIZE]; 68 | }; 69 | 70 | static_assert(sizeof(Program) % 64 == 0, "Invalid size of class randomx::Program"); 71 | } 72 | -------------------------------------------------------------------------------- /src/randomx/reciprocal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #if defined(__cplusplus) 31 | extern "C" 32 | { 33 | #endif 34 | 35 | #include "reciprocal.h" 36 | 37 | /* 38 | Calculates rcp = 2**x / divisor for highest integer x such that rcp < 2**64. 39 | divisor must not be 0 or a power of 2 40 | 41 | Equivalent x86 assembly (divisor in rcx): 42 | 43 | mov edx, 1 44 | mov r8, rcx 45 | xor eax, eax 46 | bsr rcx, rcx 47 | shl rdx, cl 48 | div r8 49 | ret 50 | 51 | */ 52 | uint64_t randomx_reciprocal(uint64_t divisor) { 53 | 54 | assert(divisor != 0); 55 | 56 | const uint64_t p2exp63 = 1ULL << 63; 57 | 58 | uint64_t quotient = p2exp63 / divisor, remainder = p2exp63 % divisor; 59 | 60 | unsigned bsr = 0; //highest set bit in divisor 61 | 62 | for (uint64_t bit = divisor; bit > 0; bit >>= 1) 63 | bsr++; 64 | 65 | for (unsigned shift = 0; shift < bsr; shift++) { 66 | if (remainder >= divisor - remainder) { 67 | quotient = quotient * 2 + 1; 68 | remainder = remainder * 2 - divisor; 69 | } 70 | else { 71 | quotient = quotient * 2; 72 | remainder = remainder * 2; 73 | } 74 | } 75 | 76 | return quotient; 77 | } 78 | 79 | #if !RANDOMX_HAVE_FAST_RECIPROCAL 80 | 81 | uint64_t randomx_reciprocal_fast(uint64_t divisor) { 82 | return randomx_reciprocal(divisor); 83 | } 84 | 85 | #endif 86 | 87 | #if defined(__cplusplus) 88 | } 89 | #endif 90 | -------------------------------------------------------------------------------- /src/randomx/reciprocal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | #if defined(_M_X64) || defined(__x86_64__) 34 | #define RANDOMX_HAVE_FAST_RECIPROCAL 1 35 | #else 36 | #define RANDOMX_HAVE_FAST_RECIPROCAL 0 37 | #endif 38 | 39 | #if defined(__cplusplus) 40 | extern "C" { 41 | #endif 42 | 43 | uint64_t randomx_reciprocal(uint64_t); 44 | uint64_t randomx_reciprocal_fast(uint64_t); 45 | 46 | #if defined(__cplusplus) 47 | } 48 | #endif 49 | -------------------------------------------------------------------------------- /src/randomx/soft_aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "intrin_portable.h" 33 | 34 | rx_vec_i128 soft_aesenc(rx_vec_i128 in, rx_vec_i128 key); 35 | 36 | rx_vec_i128 soft_aesdec(rx_vec_i128 in, rx_vec_i128 key); 37 | 38 | template 39 | inline rx_vec_i128 aesenc(rx_vec_i128 in, rx_vec_i128 key) { 40 | return soft ? soft_aesenc(in, key) : rx_aesenc_vec_i128(in, key); 41 | } 42 | 43 | template 44 | inline rx_vec_i128 aesdec(rx_vec_i128 in, rx_vec_i128 key) { 45 | return soft ? soft_aesdec(in, key) : rx_aesdec_vec_i128(in, key); 46 | } -------------------------------------------------------------------------------- /src/randomx/superscalar.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include "superscalar_program.hpp" 34 | #include "blake2_generator.hpp" 35 | 36 | namespace randomx { 37 | // Intel Ivy Bridge reference 38 | enum class SuperscalarInstructionType { //uOPs (decode) execution ports latency code size 39 | ISUB_R = 0, //1 p015 1 3 (sub) 40 | IXOR_R = 1, //1 p015 1 3 (xor) 41 | IADD_RS = 2, //1 p01 1 4 (lea) 42 | IMUL_R = 3, //1 p1 3 4 (imul) 43 | IROR_C = 4, //1 p05 1 4 (ror) 44 | IADD_C7 = 5, //1 p015 1 7 (add) 45 | IXOR_C7 = 6, //1 p015 1 7 (xor) 46 | IADD_C8 = 7, //1+0 p015 1 7+1 (add+nop) 47 | IXOR_C8 = 8, //1+0 p015 1 7+1 (xor+nop) 48 | IADD_C9 = 9, //1+0 p015 1 7+2 (add+nop) 49 | IXOR_C9 = 10, //1+0 p015 1 7+2 (xor+nop) 50 | IMULH_R = 11, //1+2+1 0+(p1,p5)+0 3 3+3+3 (mov+mul+mov) 51 | ISMULH_R = 12, //1+2+1 0+(p1,p5)+0 3 3+3+3 (mov+imul+mov) 52 | IMUL_RCP = 13, //1+1 p015+p1 4 10+4 (mov+imul) 53 | 54 | COUNT = 14, 55 | INVALID = -1 56 | }; 57 | 58 | void generateSuperscalar(SuperscalarProgram& prog, Blake2Generator& gen); 59 | void executeSuperscalar(uint64_t(&r)[8], SuperscalarProgram& prog, std::vector *reciprocals = nullptr); 60 | } -------------------------------------------------------------------------------- /src/randomx/superscalar_program.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "instruction.hpp" 33 | #include "common.hpp" 34 | 35 | namespace randomx { 36 | 37 | class SuperscalarProgram { 38 | public: 39 | Instruction& operator()(int pc) { 40 | return programBuffer[pc]; 41 | } 42 | friend std::ostream& operator<<(std::ostream& os, const SuperscalarProgram& p) { 43 | p.print(os); 44 | return os; 45 | } 46 | uint32_t getSize() { 47 | return size; 48 | } 49 | void setSize(uint32_t val) { 50 | size = val; 51 | } 52 | int getAddressRegister() { 53 | return addrReg; 54 | } 55 | void setAddressRegister(int val) { 56 | addrReg = val; 57 | } 58 | 59 | Instruction programBuffer[SuperscalarMaxSize]; 60 | uint32_t size 61 | #ifndef NDEBUG 62 | = 0 63 | #endif 64 | ; 65 | int addrReg; 66 | double ipc; 67 | int codeSize; 68 | int macroOps; 69 | int decodeCycles; 70 | int cpuLatency; 71 | int asicLatency; 72 | int mulCount; 73 | int cpuLatencies[8]; 74 | int asicLatencies[8]; 75 | private: 76 | void print(std::ostream& os) const { 77 | for (unsigned i = 0; i < size; ++i) { 78 | auto instr = programBuffer[i]; 79 | os << instr; 80 | } 81 | } 82 | }; 83 | 84 | } -------------------------------------------------------------------------------- /src/randomx/tests/affinity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019, jtgrassie 3 | Copyright (c) 2019, tevador 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the copyright holder nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | 32 | #if defined(_WIN32) || defined(__CYGWIN__) 33 | #include 34 | #else 35 | #ifdef __APPLE__ 36 | #include 37 | #include 38 | #endif 39 | #include 40 | #endif 41 | #include "affinity.hpp" 42 | 43 | int 44 | set_thread_affinity(const unsigned &cpuid) 45 | { 46 | std::thread::native_handle_type thread; 47 | #if defined(_WIN32) || defined(__CYGWIN__) 48 | thread = reinterpret_cast(GetCurrentThread()); 49 | #else 50 | thread = static_cast(pthread_self()); 51 | #endif 52 | return set_thread_affinity(thread, cpuid); 53 | } 54 | 55 | int 56 | set_thread_affinity(std::thread::native_handle_type thread, 57 | const unsigned &cpuid) 58 | { 59 | int rc = -1; 60 | #ifdef __APPLE__ 61 | thread_port_t mach_thread; 62 | thread_affinity_policy_data_t policy = { static_cast(cpuid) }; 63 | mach_thread = pthread_mach_thread_np(thread); 64 | rc = thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, 65 | (thread_policy_t)&policy, 1); 66 | #elif defined(_WIN32) || defined(__CYGWIN__) 67 | rc = SetThreadAffinityMask(reinterpret_cast(thread), 1ULL << cpuid) == 0 ? -2 : 0; 68 | #elif !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__ANDROID__) && !defined(__NetBSD__) 69 | cpu_set_t cs; 70 | CPU_ZERO(&cs); 71 | CPU_SET(cpuid, &cs); 72 | rc = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cs); 73 | #endif 74 | return rc; 75 | } 76 | 77 | unsigned 78 | cpuid_from_mask(uint64_t mask, const unsigned &thread_index) 79 | { 80 | static unsigned lookup[64]; 81 | static bool init = false; 82 | if (init) 83 | return lookup[thread_index]; 84 | unsigned count_found = 0; 85 | for (unsigned i=0; i<64; i++) 86 | { 87 | if (1ULL & mask) 88 | { 89 | lookup[count_found] = i; 90 | count_found++; 91 | } 92 | mask >>= 1; 93 | } 94 | init = true; 95 | return lookup[thread_index]; 96 | } 97 | 98 | std::string 99 | mask_to_string(uint64_t mask) 100 | { 101 | std::ostringstream ss; 102 | unsigned len = 0; 103 | unsigned v = 0; 104 | unsigned i = 64; 105 | while (i--) 106 | { 107 | v = mask >> i; 108 | if (1ULL & v) 109 | { 110 | if (len == 0) len = i + 1; 111 | ss << '1'; 112 | } 113 | else 114 | if (len > 0) ss << '0'; 115 | } 116 | return ss.str(); 117 | } 118 | -------------------------------------------------------------------------------- /src/randomx/tests/affinity.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019, jtgrassie 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | int set_thread_affinity(const unsigned &cpuid); 36 | int set_thread_affinity(std::thread::native_handle_type thread, 37 | const unsigned &cpuid); 38 | unsigned cpuid_from_mask(uint64_t mask, const unsigned &thread_index); 39 | std::string mask_to_string(uint64_t mask); 40 | -------------------------------------------------------------------------------- /src/randomx/tests/api-example1.c: -------------------------------------------------------------------------------- 1 | #include "../randomx.h" 2 | #include 3 | 4 | int main() { 5 | const char myKey[] = "RandomX example key"; 6 | const char myInput[] = "RandomX example input"; 7 | char hash[RANDOMX_HASH_SIZE]; 8 | 9 | randomx_flags flags = randomx_get_flags(); 10 | randomx_cache *myCache = randomx_alloc_cache(flags); 11 | randomx_init_cache(myCache, &myKey, sizeof myKey); 12 | randomx_vm *myMachine = randomx_create_vm(flags, myCache, NULL); 13 | 14 | randomx_calculate_hash(myMachine, &myInput, sizeof myInput, hash); 15 | 16 | randomx_destroy_vm(myMachine); 17 | randomx_release_cache(myCache); 18 | 19 | for (unsigned i = 0; i < RANDOMX_HASH_SIZE; ++i) 20 | printf("%02x", hash[i] & 0xff); 21 | 22 | printf("\n"); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/randomx/tests/api-example2.cpp: -------------------------------------------------------------------------------- 1 | #include "../randomx.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | const char myKey[] = "RandomX example key"; 8 | const char myInput[] = "RandomX example input"; 9 | char hash[RANDOMX_HASH_SIZE]; 10 | 11 | randomx_flags flags = randomx_get_flags(); 12 | flags |= RANDOMX_FLAG_LARGE_PAGES; 13 | flags |= RANDOMX_FLAG_FULL_MEM; 14 | randomx_cache *myCache = randomx_alloc_cache(flags); 15 | if (myCache == nullptr) { 16 | std::cout << "Cache allocation failed" << std::endl; 17 | return 1; 18 | } 19 | randomx_init_cache(myCache, myKey, sizeof myKey); 20 | 21 | randomx_dataset *myDataset = randomx_alloc_dataset(flags); 22 | if (myDataset == nullptr) { 23 | std::cout << "Dataset allocation failed" << std::endl; 24 | return 1; 25 | } 26 | 27 | auto datasetItemCount = randomx_dataset_item_count(); 28 | std::thread t1(&randomx_init_dataset, myDataset, myCache, 0, datasetItemCount / 2); 29 | std::thread t2(&randomx_init_dataset, myDataset, myCache, datasetItemCount / 2, datasetItemCount - datasetItemCount / 2); 30 | t1.join(); 31 | t2.join(); 32 | randomx_release_cache(myCache); 33 | 34 | randomx_vm *myMachine = randomx_create_vm(flags, nullptr, myDataset); 35 | if (myMachine == nullptr) { 36 | std::cout << "Failed to create a virtual machine" << std::endl; 37 | return 1; 38 | } 39 | 40 | randomx_calculate_hash(myMachine, &myInput, sizeof myInput, hash); 41 | 42 | randomx_destroy_vm(myMachine); 43 | randomx_release_dataset(myDataset); 44 | 45 | for (unsigned i = 0; i < RANDOMX_HASH_SIZE; ++i) 46 | std::cout << std::hex << std::setw(2) << std::setfill('0') << ((int)hash[i] & 0xff); 47 | 48 | std::cout << std::endl; 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /src/randomx/virtual_machine.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "common.hpp" 33 | #include "program.hpp" 34 | 35 | /* Global namespace for C binding */ 36 | class randomx_vm { 37 | public: 38 | virtual ~randomx_vm() = 0; 39 | virtual void allocate() = 0; 40 | virtual void getFinalResult(void* out, size_t outSize) = 0; 41 | virtual void hashAndFill(void* out, size_t outSize, uint64_t *fill_state) = 0; 42 | virtual void setDataset(randomx_dataset* dataset) { } 43 | virtual void setCache(randomx_cache* cache) { } 44 | virtual void initScratchpad(void* seed) = 0; 45 | virtual void run(void* seed) = 0; 46 | void resetRoundingMode(); 47 | randomx::RegisterFile *getRegisterFile() { 48 | return ® 49 | } 50 | const void* getScratchpad() { 51 | return scratchpad; 52 | } 53 | const randomx::Program& getProgram() 54 | { 55 | return program; 56 | } 57 | const uint8_t* getMemory() const { 58 | return mem.memory; 59 | } 60 | protected: 61 | void initialize(); 62 | alignas(64) randomx::Program program; 63 | alignas(64) randomx::RegisterFile reg; 64 | alignas(16) randomx::ProgramConfiguration config; 65 | randomx::MemoryRegisters mem; 66 | uint8_t* scratchpad = nullptr; 67 | union { 68 | randomx_cache* cachePtr = nullptr; 69 | randomx_dataset* datasetPtr; 70 | }; 71 | uint64_t datasetOffset; 72 | public: 73 | std::string cacheKey; 74 | alignas(16) uint64_t tempHash[8]; //8 64-bit values used to store intermediate data 75 | }; 76 | 77 | namespace randomx { 78 | 79 | template 80 | class VmBase : public randomx_vm { 81 | public: 82 | ~VmBase() override; 83 | void allocate() override; 84 | void initScratchpad(void* seed) override; 85 | void getFinalResult(void* out, size_t outSize) override; 86 | void hashAndFill(void* out, size_t outSize, uint64_t *fill_state) override; 87 | protected: 88 | void generateProgram(void* seed); 89 | }; 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/randomx/virtual_memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #include 36 | 37 | #define alignSize(pos, align) (((pos - 1) / align + 1) * align) 38 | 39 | void* allocMemoryPages(size_t); 40 | void setPagesRW(void*, size_t); 41 | void setPagesRX(void*, size_t); 42 | void setPagesRWX(void*, size_t); 43 | void* allocLargePagesMemory(size_t); 44 | void freePagedMemory(void*, size_t); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | -------------------------------------------------------------------------------- /src/randomx/vm_compiled.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "vm_compiled.hpp" 30 | #include "common.hpp" 31 | 32 | namespace randomx { 33 | 34 | static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct randomx::MemoryRegisters"); 35 | static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct randomx::RegisterFile"); 36 | 37 | template 38 | CompiledVm::CompiledVm() { 39 | if (!secureJit) { 40 | compiler.enableAll(); //make JIT buffer both writable and executable 41 | } 42 | } 43 | 44 | template 45 | void CompiledVm::setDataset(randomx_dataset* dataset) { 46 | datasetPtr = dataset; 47 | } 48 | 49 | template 50 | void CompiledVm::run(void* seed) { 51 | VmBase::generateProgram(seed); 52 | randomx_vm::initialize(); 53 | if (secureJit) { 54 | compiler.enableWriting(); 55 | } 56 | compiler.generateProgram(program, config); 57 | if (secureJit) { 58 | compiler.enableExecution(); 59 | } 60 | mem.memory = datasetPtr->memory + datasetOffset; 61 | execute(); 62 | } 63 | 64 | template 65 | void CompiledVm::execute() { 66 | #ifdef __aarch64__ 67 | memcpy(reg.f, config.eMask, sizeof(config.eMask)); 68 | #endif 69 | compiler.getProgramFunc()(reg, mem, scratchpad, RANDOMX_PROGRAM_ITERATIONS); 70 | } 71 | 72 | template class CompiledVm, false, false>; 73 | template class CompiledVm, true, false>; 74 | template class CompiledVm; 75 | template class CompiledVm; 76 | template class CompiledVm, false, true>; 77 | template class CompiledVm, true, true>; 78 | template class CompiledVm; 79 | template class CompiledVm; 80 | } -------------------------------------------------------------------------------- /src/randomx/vm_compiled.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include "virtual_machine.hpp" 34 | #include "jit_compiler.hpp" 35 | #include "allocator.hpp" 36 | #include "dataset.hpp" 37 | 38 | namespace randomx { 39 | 40 | template 41 | class CompiledVm : public VmBase { 42 | public: 43 | void* operator new(size_t size) { 44 | void* ptr = AlignedAllocator::allocMemory(size); 45 | if (ptr == nullptr) 46 | throw std::bad_alloc(); 47 | return ptr; 48 | } 49 | void operator delete(void* ptr) { 50 | AlignedAllocator::freeMemory(ptr, sizeof(CompiledVm)); 51 | } 52 | CompiledVm(); 53 | void setDataset(randomx_dataset* dataset) override; 54 | void run(void* seed) override; 55 | 56 | using VmBase::mem; 57 | using VmBase::program; 58 | using VmBase::config; 59 | using VmBase::reg; 60 | using VmBase::scratchpad; 61 | using VmBase::datasetPtr; 62 | using VmBase::datasetOffset; 63 | protected: 64 | void execute(); 65 | 66 | JitCompiler compiler; 67 | }; 68 | 69 | using CompiledVmDefault = CompiledVm, true, false>; 70 | using CompiledVmHardAes = CompiledVm, false, false>; 71 | using CompiledVmLargePage = CompiledVm; 72 | using CompiledVmLargePageHardAes = CompiledVm; 73 | using CompiledVmDefaultSecure = CompiledVm, true, true>; 74 | using CompiledVmHardAesSecure = CompiledVm, false, true>; 75 | using CompiledVmLargePageSecure = CompiledVm; 76 | using CompiledVmLargePageHardAesSecure = CompiledVm; 77 | } 78 | -------------------------------------------------------------------------------- /src/randomx/vm_compiled_light.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "vm_compiled_light.hpp" 30 | #include "common.hpp" 31 | #include 32 | 33 | namespace randomx { 34 | 35 | template 36 | void CompiledLightVm::setCache(randomx_cache* cache) { 37 | cachePtr = cache; 38 | mem.memory = cache->memory; 39 | if (secureJit) { 40 | compiler.enableWriting(); 41 | } 42 | compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache); 43 | if (secureJit) { 44 | compiler.enableExecution(); 45 | } 46 | } 47 | 48 | template 49 | void CompiledLightVm::run(void* seed) { 50 | VmBase::generateProgram(seed); 51 | randomx_vm::initialize(); 52 | if (secureJit) { 53 | compiler.enableWriting(); 54 | } 55 | compiler.generateProgramLight(program, config, datasetOffset); 56 | if (secureJit) { 57 | compiler.enableExecution(); 58 | } 59 | CompiledVm::execute(); 60 | } 61 | 62 | template class CompiledLightVm, false, false>; 63 | template class CompiledLightVm, true, false>; 64 | template class CompiledLightVm; 65 | template class CompiledLightVm; 66 | template class CompiledLightVm, false, true>; 67 | template class CompiledLightVm, true, true>; 68 | template class CompiledLightVm; 69 | template class CompiledLightVm; 70 | } -------------------------------------------------------------------------------- /src/randomx/vm_compiled_light.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "vm_compiled.hpp" 33 | 34 | namespace randomx { 35 | 36 | template 37 | class CompiledLightVm : public CompiledVm { 38 | public: 39 | void* operator new(size_t size) { 40 | void* ptr = AlignedAllocator::allocMemory(size); 41 | if (ptr == nullptr) 42 | throw std::bad_alloc(); 43 | return ptr; 44 | } 45 | void operator delete(void* ptr) { 46 | AlignedAllocator::freeMemory(ptr, sizeof(CompiledLightVm)); 47 | } 48 | void setCache(randomx_cache* cache) override; 49 | void setDataset(randomx_dataset* dataset) override { } 50 | void run(void* seed) override; 51 | 52 | using CompiledVm::mem; 53 | using CompiledVm::compiler; 54 | using CompiledVm::program; 55 | using CompiledVm::config; 56 | using CompiledVm::cachePtr; 57 | using CompiledVm::datasetOffset; 58 | }; 59 | 60 | using CompiledLightVmDefault = CompiledLightVm, true, false>; 61 | using CompiledLightVmHardAes = CompiledLightVm, false, false>; 62 | using CompiledLightVmLargePage = CompiledLightVm; 63 | using CompiledLightVmLargePageHardAes = CompiledLightVm; 64 | using CompiledLightVmDefaultSecure = CompiledLightVm, true, true>; 65 | using CompiledLightVmHardAesSecure = CompiledLightVm, false, true>; 66 | using CompiledLightVmLargePageSecure = CompiledLightVm; 67 | using CompiledLightVmLargePageHardAesSecure = CompiledLightVm; 68 | } -------------------------------------------------------------------------------- /src/randomx/vm_interpreted.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include "common.hpp" 34 | #include "virtual_machine.hpp" 35 | #include "bytecode_machine.hpp" 36 | #include "intrin_portable.h" 37 | #include "allocator.hpp" 38 | 39 | namespace randomx { 40 | 41 | template 42 | class InterpretedVm : public VmBase, public BytecodeMachine { 43 | public: 44 | using VmBase::mem; 45 | using VmBase::scratchpad; 46 | using VmBase::program; 47 | using VmBase::config; 48 | using VmBase::reg; 49 | using VmBase::datasetPtr; 50 | using VmBase::datasetOffset; 51 | void* operator new(size_t size) { 52 | void* ptr = AlignedAllocator::allocMemory(size); 53 | if (ptr == nullptr) 54 | throw std::bad_alloc(); 55 | return ptr; 56 | } 57 | void operator delete(void* ptr) { 58 | AlignedAllocator::freeMemory(ptr, sizeof(InterpretedVm)); 59 | } 60 | void run(void* seed) override; 61 | void setDataset(randomx_dataset* dataset) override; 62 | protected: 63 | virtual void datasetRead(uint64_t blockNumber, int_reg_t(&r)[RegistersCount]); 64 | virtual void datasetPrefetch(uint64_t blockNumber); 65 | private: 66 | void execute(); 67 | 68 | InstructionByteCode bytecode[RANDOMX_PROGRAM_SIZE]; 69 | }; 70 | 71 | using InterpretedVmDefault = InterpretedVm, true>; 72 | using InterpretedVmHardAes = InterpretedVm, false>; 73 | using InterpretedVmLargePage = InterpretedVm; 74 | using InterpretedVmLargePageHardAes = InterpretedVm; 75 | } -------------------------------------------------------------------------------- /src/randomx/vm_interpreted_light.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "vm_interpreted_light.hpp" 30 | #include "dataset.hpp" 31 | 32 | namespace randomx { 33 | 34 | template 35 | void InterpretedLightVm::setCache(randomx_cache* cache) { 36 | cachePtr = cache; 37 | mem.memory = cache->memory; 38 | } 39 | 40 | template 41 | void InterpretedLightVm::datasetRead(uint64_t address, int_reg_t(&r)[8]) { 42 | uint32_t itemNumber = address / CacheLineSize; 43 | int_reg_t rl[8]; 44 | 45 | initDatasetItem(cachePtr, (uint8_t*)rl, itemNumber); 46 | 47 | for (unsigned q = 0; q < 8; ++q) 48 | r[q] ^= rl[q]; 49 | } 50 | 51 | template class InterpretedLightVm, false>; 52 | template class InterpretedLightVm, true>; 53 | template class InterpretedLightVm; 54 | template class InterpretedLightVm; 55 | } 56 | -------------------------------------------------------------------------------- /src/randomx/vm_interpreted_light.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018-2019, tevador 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the copyright holder nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "vm_interpreted.hpp" 33 | 34 | namespace randomx { 35 | 36 | template 37 | class InterpretedLightVm : public InterpretedVm { 38 | public: 39 | using VmBase::mem; 40 | using VmBase::cachePtr; 41 | void* operator new(size_t size) { 42 | void* ptr = AlignedAllocator::allocMemory(size); 43 | if (ptr == nullptr) 44 | throw std::bad_alloc(); 45 | return ptr; 46 | } 47 | void operator delete(void* ptr) { 48 | AlignedAllocator::freeMemory(ptr, sizeof(InterpretedLightVm)); 49 | } 50 | void setDataset(randomx_dataset* dataset) override { } 51 | void setCache(randomx_cache* cache) override; 52 | protected: 53 | void datasetRead(uint64_t address, int_reg_t(&r)[8]) override; 54 | void datasetPrefetch(uint64_t address) override { } 55 | }; 56 | 57 | using InterpretedLightVmDefault = InterpretedLightVm, true>; 58 | using InterpretedLightVmHardAes = InterpretedLightVm, false>; 59 | using InterpretedLightVmLargePage = InterpretedLightVm; 60 | using InterpretedLightVmLargePageHardAes = InterpretedLightVm; 61 | } 62 | -------------------------------------------------------------------------------- /test-travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 3 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 4 | 5 | /bin/rm -rf build/ ; MONERO_NO_AES=1 MONERO_NO_JIT=1 python setup.py develop 6 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 7 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 8 | 9 | /bin/rm -rf build/ ; MONERO_NO_AES=0 MONERO_NO_JIT=1 python setup.py develop 10 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 11 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 12 | 13 | /bin/rm -rf build/ ; MONERO_NO_AES=0 MONERO_NO_JIT=0 python setup.py develop 14 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 15 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 16 | 17 | /bin/rm -rf build/ ; MONERO_NO_AES=0 MONERO_NO_JIT=0 MONERO_STATIC_JIT=0 python setup.py develop 18 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 19 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 20 | 21 | /bin/rm -rf build/ ; MONERO_NO_AES=0 MONERO_NO_JIT=0 MONERO_STATIC_JIT=0 MONERO_DEBUG_JIT=1 MONERO_DUMP_JIT=1 python setup.py develop 22 | MONERO_USE_CNV4_JIT=0 python -m unittest discover $* 23 | MONERO_USE_CNV4_JIT=1 python -m unittest discover $* 24 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./venv/bin/python3 -m unittest discover 3 | #python -m unittest discover 4 | -------------------------------------------------------------------------------- /tools/convert_s_to_c.py: -------------------------------------------------------------------------------- 1 | """ 2 | Converts .S file to the .C file 3 | Used to generate CryptonightR_template.c 4 | """ 5 | 6 | import re 7 | 8 | # Read the .S file here, the CryptonightR_instruction* definitions 9 | data = """ 10 | FN_PREFIX(CryptonightR_instruction51): 11 | add edi, esi 12 | add edi, 2147483647 13 | """ 14 | 15 | is_body = False 16 | fnc_name = None 17 | body = [] 18 | instructions = [] 19 | lines = [x.strip() for x in data.split("\n") if x] 20 | 21 | 22 | def try_int(x): 23 | try: 24 | return int(x) 25 | except: 26 | return x 27 | 28 | 29 | for idx, line in enumerate(lines): 30 | if not line: 31 | continue 32 | m = re.match(r'^FN_PREFIX\(([\w_-]+)\):$', line) 33 | if m: 34 | is_body = False 35 | if fnc_name: 36 | instructions.append((fnc_name, body)) 37 | 38 | fnc_name = m.group(1) 39 | body = [] 40 | else: 41 | m2 = re.match(r'^([\w]+)\s+([\w]+)\s*,\s*([\w]+)\s*$', line.strip()) 42 | if not m2: 43 | raise ValueError('Problem') 44 | body.append(m2.groups()) 45 | instructions.append((fnc_name, body)) 46 | 47 | def gen_functions(instructions): 48 | for fname, body in instructions: 49 | print('ASMFNC void %s(void){' % fname) 50 | # print('ins_%s_s:' % fname.lower()) 51 | print(' ASM_B') 52 | for b in body: 53 | arg1 = try_int(b[1]) 54 | arg2 = try_int(b[2]) 55 | arg1s = ('C(%s)' % arg1) if isinstance(arg1, int) else ('R(%s)' % arg1) 56 | arg2s = ('C(%s)' % arg2) if isinstance(arg2, int) else ('R(%s)' % arg2) 57 | print(' %s(%s, %s)' % (b[0].upper(), arg1s, arg2s)) 58 | print(' NOP()') 59 | print(' ASM_E') 60 | print('}\n') 61 | 62 | 63 | def gen_asms(instructions): 64 | for fname, body in instructions: 65 | print('ASM_FNC(%s, ' % fname) 66 | for b in body: 67 | arg1 = try_int(b[1]) 68 | arg2 = try_int(b[2]) 69 | arg1s = ('C(%s)' % arg1) if isinstance(arg1, int) else ('R(%s)' % arg1) 70 | arg2s = ('C(%s)' % arg2) if isinstance(arg2, int) else ('R(%s)' % arg2) 71 | print(' %s(%s, %s)' % (b[0].upper(), arg1s, arg2s)) 72 | if not body: 73 | print(' NOP()') 74 | print(')') 75 | 76 | 77 | gen_asms(instructions) 78 | 79 | --------------------------------------------------------------------------------