randomx.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. Copyright (c) 2018-2019, tevador <tevador@gmail.com>
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of the copyright holder nor the
  12. names of its contributors may be used to endorse or promote products
  13. derived from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  18. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  20. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  21. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  22. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef RANDOMX_H
  26. #define RANDOMX_H
  27. #include <stddef.h>
  28. #include <stdint.h>
  29. #define RANDOMX_HASH_SIZE 32
  30. #define RANDOMX_DATASET_ITEM_SIZE 64
  31. #ifndef RANDOMX_EXPORT
  32. #define RANDOMX_EXPORT
  33. #endif
  34. typedef enum {
  35. RANDOMX_FLAG_DEFAULT = 0,
  36. RANDOMX_FLAG_LARGE_PAGES = 1,
  37. RANDOMX_FLAG_HARD_AES = 2,
  38. RANDOMX_FLAG_FULL_MEM = 4,
  39. RANDOMX_FLAG_JIT = 8,
  40. RANDOMX_FLAG_SECURE = 16,
  41. RANDOMX_FLAG_ARGON2_SSSE3 = 32,
  42. RANDOMX_FLAG_ARGON2_AVX2 = 64,
  43. RANDOMX_FLAG_ARGON2 = 96
  44. } randomx_flags;
  45. typedef struct randomx_dataset randomx_dataset;
  46. typedef struct randomx_cache randomx_cache;
  47. typedef struct randomx_vm randomx_vm;
  48. #if defined(__cplusplus)
  49. #ifdef __cpp_constexpr
  50. #define CONSTEXPR constexpr
  51. #else
  52. #define CONSTEXPR
  53. #endif
  54. inline CONSTEXPR randomx_flags operator |(randomx_flags a, randomx_flags b) {
  55. return static_cast<randomx_flags>(static_cast<int>(a) | static_cast<int>(b));
  56. }
  57. inline CONSTEXPR randomx_flags operator &(randomx_flags a, randomx_flags b) {
  58. return static_cast<randomx_flags>(static_cast<int>(a) & static_cast<int>(b));
  59. }
  60. inline randomx_flags& operator |=(randomx_flags& a, randomx_flags b) {
  61. return a = a | b;
  62. }
  63. extern "C" {
  64. #endif
  65. /**
  66. * @return The recommended flags to be used on the current machine.
  67. * Does not include:
  68. * RANDOMX_FLAG_LARGE_PAGES
  69. * RANDOMX_FLAG_FULL_MEM
  70. * RANDOMX_FLAG_SECURE
  71. * These flags must be added manually if desired.
  72. * On OpenBSD RANDOMX_FLAG_SECURE is enabled by default in JIT mode as W^X is enforced by the OS.
  73. */
  74. RANDOMX_EXPORT randomx_flags randomx_get_flags(void);
  75. /**
  76. * Creates a randomx_cache structure and allocates memory for RandomX Cache.
  77. *
  78. * @param flags is any combination of these 2 flags (each flag can be set or not set):
  79. * RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages
  80. * RANDOMX_FLAG_JIT - create cache structure with JIT compilation support; this makes
  81. * subsequent Dataset initialization faster
  82. * Optionally, one of these two flags may be selected:
  83. * RANDOMX_FLAG_ARGON2_SSSE3 - optimized Argon2 for CPUs with the SSSE3 instruction set
  84. * makes subsequent cache initialization faster
  85. * RANDOMX_FLAG_ARGON2_AVX2 - optimized Argon2 for CPUs with the AVX2 instruction set
  86. * makes subsequent cache initialization faster
  87. *
  88. * @return Pointer to an allocated randomx_cache structure.
  89. * Returns NULL if:
  90. * (1) memory allocation fails
  91. * (2) the RANDOMX_FLAG_JIT is set and JIT compilation is not supported on the current platform
  92. * (3) an invalid or unsupported RANDOMX_FLAG_ARGON2 value is set
  93. */
  94. RANDOMX_EXPORT randomx_cache *randomx_alloc_cache(randomx_flags flags);
  95. /**
  96. * Initializes the cache memory and SuperscalarHash using the provided key value.
  97. * Does nothing if called again with the same key value.
  98. *
  99. * @param cache is a pointer to a previously allocated randomx_cache structure. Must not be NULL.
  100. * @param key is a pointer to memory which contains the key value. Must not be NULL.
  101. * @param keySize is the number of bytes of the key.
  102. */
  103. RANDOMX_EXPORT void randomx_init_cache(randomx_cache *cache, const void *key, size_t keySize);
  104. /**
  105. * Releases all memory occupied by the randomx_cache structure.
  106. *
  107. * @param cache is a pointer to a previously allocated randomx_cache structure.
  108. */
  109. RANDOMX_EXPORT void randomx_release_cache(randomx_cache* cache);
  110. /**
  111. * Creates a randomx_dataset structure and allocates memory for RandomX Dataset.
  112. *
  113. * @param flags is the initialization flags. Only one flag is supported (can be set or not set):
  114. * RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages
  115. *
  116. * @return Pointer to an allocated randomx_dataset structure.
  117. * NULL is returned if memory allocation fails.
  118. */
  119. RANDOMX_EXPORT randomx_dataset *randomx_alloc_dataset(randomx_flags flags);
  120. /**
  121. * Gets the number of items contained in the dataset.
  122. *
  123. * @return the number of items contained in the dataset.
  124. */
  125. RANDOMX_EXPORT unsigned long randomx_dataset_item_count(void);
  126. /**
  127. * Initializes dataset items.
  128. *
  129. * Note: In order to use the Dataset, all items from 0 to (randomx_dataset_item_count() - 1) must be initialized.
  130. * This may be done by several calls to this function using non-overlapping item sequences.
  131. *
  132. * @param dataset is a pointer to a previously allocated randomx_dataset structure. Must not be NULL.
  133. * @param cache is a pointer to a previously allocated and initialized randomx_cache structure. Must not be NULL.
  134. * @param startItem is the item number where initialization should start.
  135. * @param itemCount is the number of items that should be initialized.
  136. */
  137. RANDOMX_EXPORT void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount);
  138. /**
  139. * Returns a pointer to the internal memory buffer of the dataset structure. The size
  140. * of the internal memory buffer is randomx_dataset_item_count() * RANDOMX_DATASET_ITEM_SIZE.
  141. *
  142. * @param dataset is a pointer to a previously allocated randomx_dataset structure. Must not be NULL.
  143. *
  144. * @return Pointer to the internal memory buffer of the dataset structure.
  145. */
  146. RANDOMX_EXPORT void *randomx_get_dataset_memory(randomx_dataset *dataset);
  147. /**
  148. * Releases all memory occupied by the randomx_dataset structure.
  149. *
  150. * @param dataset is a pointer to a previously allocated randomx_dataset structure.
  151. */
  152. RANDOMX_EXPORT void randomx_release_dataset(randomx_dataset *dataset);
  153. /**
  154. * Creates and initializes a RandomX virtual machine.
  155. *
  156. * @param flags is any combination of these 5 flags (each flag can be set or not set):
  157. * RANDOMX_FLAG_LARGE_PAGES - allocate scratchpad memory in large pages
  158. * RANDOMX_FLAG_HARD_AES - virtual machine will use hardware accelerated AES
  159. * RANDOMX_FLAG_FULL_MEM - virtual machine will use the full dataset
  160. * RANDOMX_FLAG_JIT - virtual machine will use a JIT compiler
  161. * RANDOMX_FLAG_SECURE - when combined with RANDOMX_FLAG_JIT, the JIT pages are never
  162. * writable and executable at the same time (W^X policy)
  163. * The numeric values of the first 4 flags are ordered so that a higher value will provide
  164. * faster hash calculation and a lower numeric value will provide higher portability.
  165. * Using RANDOMX_FLAG_DEFAULT (all flags not set) works on all platforms, but is the slowest.
  166. * @param cache is a pointer to an initialized randomx_cache structure. Can be
  167. * NULL if RANDOMX_FLAG_FULL_MEM is set.
  168. * @param dataset is a pointer to a randomx_dataset structure. Can be NULL
  169. * if RANDOMX_FLAG_FULL_MEM is not set.
  170. *
  171. * @return Pointer to an initialized randomx_vm structure.
  172. * Returns NULL if:
  173. * (1) Scratchpad memory allocation fails.
  174. * (2) The requested initialization flags are not supported on the current platform.
  175. * (3) cache parameter is NULL and RANDOMX_FLAG_FULL_MEM is not set
  176. * (4) dataset parameter is NULL and RANDOMX_FLAG_FULL_MEM is set
  177. */
  178. RANDOMX_EXPORT randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset);
  179. /**
  180. * Reinitializes a virtual machine with a new Cache. This function should be called anytime
  181. * the Cache is reinitialized with a new key. Does nothing if called with a Cache containing
  182. * the same key value as already set.
  183. *
  184. * @param machine is a pointer to a randomx_vm structure that was initialized
  185. * without RANDOMX_FLAG_FULL_MEM. Must not be NULL.
  186. * @param cache is a pointer to an initialized randomx_cache structure. Must not be NULL.
  187. */
  188. RANDOMX_EXPORT void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache);
  189. /**
  190. * Reinitializes a virtual machine with a new Dataset.
  191. *
  192. * @param machine is a pointer to a randomx_vm structure that was initialized
  193. * with RANDOMX_FLAG_FULL_MEM. Must not be NULL.
  194. * @param dataset is a pointer to an initialized randomx_dataset structure. Must not be NULL.
  195. */
  196. RANDOMX_EXPORT void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset);
  197. /**
  198. * Releases all memory occupied by the randomx_vm structure.
  199. *
  200. * @param machine is a pointer to a previously created randomx_vm structure.
  201. */
  202. RANDOMX_EXPORT void randomx_destroy_vm(randomx_vm *machine);
  203. /**
  204. * Calculates a RandomX hash value.
  205. *
  206. * @param machine is a pointer to a randomx_vm structure. Must not be NULL.
  207. * @param input is a pointer to memory to be hashed. Must not be NULL.
  208. * @param inputSize is the number of bytes to be hashed.
  209. * @param output is a pointer to memory where the hash will be stored. Must not
  210. * be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing.
  211. */
  212. RANDOMX_EXPORT void randomx_calculate_hash(randomx_vm *machine, const void *input, size_t inputSize, void *output);
  213. /**
  214. * Set of functions used to calculate multiple RandomX hashes more efficiently.
  215. * randomx_calculate_hash_first will begin a hash calculation.
  216. * randomx_calculate_hash_next will output the hash value of the previous input
  217. * and begin the calculation of the next hash.
  218. * randomx_calculate_hash_last will output the hash value of the previous input.
  219. *
  220. * WARNING: These functions may alter the floating point rounding mode of the calling thread.
  221. *
  222. * @param machine is a pointer to a randomx_vm structure. Must not be NULL.
  223. * @param input is a pointer to memory to be hashed. Must not be NULL.
  224. * @param inputSize is the number of bytes to be hashed.
  225. * @param nextInput is a pointer to memory to be hashed for the next hash. Must not be NULL.
  226. * @param nextInputSize is the number of bytes to be hashed for the next hash.
  227. * @param output is a pointer to memory where the hash will be stored. Must not
  228. * be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing.
  229. */
  230. RANDOMX_EXPORT void randomx_calculate_hash_first(randomx_vm* machine, const void* input, size_t inputSize);
  231. RANDOMX_EXPORT void randomx_calculate_hash_next(randomx_vm* machine, const void* nextInput, size_t nextInputSize, void* output);
  232. RANDOMX_EXPORT void randomx_calculate_hash_last(randomx_vm* machine, void* output);
  233. /**
  234. * Calculate a RandomX commitment from a RandomX hash and its input.
  235. *
  236. * @param input is a pointer to memory that was hashed. Must not be NULL.
  237. * @param inputSize is the number of bytes in the input.
  238. * @param hash_in is the output from randomx_calculate_hash* (RANDOMX_HASH_SIZE bytes).
  239. * @param com_out is a pointer to memory where the commitment will be stored. Must not
  240. * be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing.
  241. */
  242. RANDOMX_EXPORT void randomx_calculate_commitment(const void* input, size_t inputSize, const void* hash_in, void* com_out);
  243. #if defined(__cplusplus)
  244. }
  245. #endif
  246. #endif