Monero
Loading...
Searching...
No Matches
slow-hash.c File Reference
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "int-util.h"
#include "hash-ops.h"
#include "oaes_lib.h"
#include "variant2_int_sqrt.h"
#include "variant4_random_math.h"
#include "CryptonightR_JIT.h"
#include <errno.h>
Include dependency graph for slow-hash.c:

Classes

union  cn_slow_hash_state

Macros

#define MEMORY   (1 << 21)
#define ITER   (1 << 20)
#define AES_BLOCK_SIZE   16
#define AES_KEY_SIZE   32
#define INIT_SIZE_BLK   8
#define INIT_SIZE_BYTE   (INIT_SIZE_BLK * AES_BLOCK_SIZE)
#define THREADV   __thread
#define VARIANT1_1(p)
#define VARIANT1_2(p)
#define VARIANT1_CHECK()
#define NONCE_POINTER   (((const uint8_t*)data)+35)
#define VARIANT1_PORTABLE_INIT()
#define VARIANT1_INIT64()
#define VARIANT2_INIT64()
#define VARIANT2_PORTABLE_INIT()
#define VARIANT2_SHUFFLE_ADD_SSE2(base_ptr, offset)
#define VARIANT2_SHUFFLE_ADD_NEON(base_ptr, offset)
#define VARIANT2_PORTABLE_SHUFFLE_ADD(out, a_, base_ptr, offset)
#define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr)
#define VARIANT2_INTEGER_MATH_SSE2(b, ptr)
#define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr)
#define VARIANT2_2_PORTABLE()
#define VARIANT2_2()
#define V4_REG_LOAD(dst, src)
#define VARIANT4_RANDOM_MATH_INIT()
#define VARIANT4_RANDOM_MATH(a, b, r, _b, _b1)
#define hp_jitfunc   ((v4_random_math_JIT_func)NULL)
#define U64(x)

Functions

void aesb_single_round (const uint8_t *in, uint8_t *out, const uint8_t *expandedKey)
void aesb_pseudo_round (const uint8_t *in, uint8_t *out, const uint8_t *expandedKey)
static void local_abort (const char *msg)
static int use_v4_jit (void)
void cn_slow_hash_allocate_state (void)
void cn_slow_hash_free_state (void)
static size_t e2i (const uint8_t *a, size_t count)
static void mul (const uint8_t *a, const uint8_t *b, uint8_t *res)
static void sum_half_blocks (uint8_t *a, const uint8_t *b)
static void copy_block (uint8_t *dst, const uint8_t *src)
static void swap_blocks (uint8_t *a, uint8_t *b)
static void xor_blocks (uint8_t *a, const uint8_t *b)
static void xor64 (uint8_t *left, const uint8_t *right)
void cn_slow_hash (const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
void slow_hash_allocate_state (void)
void slow_hash_free_state (void)

Variables

volatile int use_v4_jit_flag = -1
static void(*const extra_hashes [4])(const void *, size_t, char *)

Macro Definition Documentation

◆ AES_BLOCK_SIZE

#define AES_BLOCK_SIZE   16

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   32

◆ hp_jitfunc

#define hp_jitfunc   ((v4_random_math_JIT_func)NULL)

◆ INIT_SIZE_BLK

#define INIT_SIZE_BLK   8

◆ INIT_SIZE_BYTE

#define INIT_SIZE_BYTE   (INIT_SIZE_BLK * AES_BLOCK_SIZE)

◆ ITER

#define ITER   (1 << 20)

◆ MEMORY

#define MEMORY   (1 << 21)

◆ NONCE_POINTER

#define NONCE_POINTER   (((const uint8_t*)data)+35)

◆ THREADV

#define THREADV   __thread

◆ U64

#define U64 ( x)
Value:
((uint64_t *) (x))
unsigned __int64 uint64_t
Definition stdint.h:136

◆ V4_REG_LOAD

#define V4_REG_LOAD ( dst,
src )
Value:
do { \
memcpy((dst), (src), sizeof(v4_reg)); \
if (sizeof(v4_reg) == sizeof(uint32_t)) \
*(dst) = SWAP32LE(*(dst)); \
else \
*(dst) = SWAP64LE(*(dst)); \
} while (0)
#define SWAP64LE
Definition int-util.h:285
#define SWAP32LE
Definition int-util.h:277
unsigned int uint32_t
Definition stdint.h:126
uint32_t v4_reg
Definition variant4_random_math.h:5

◆ VARIANT1_1

#define VARIANT1_1 ( p)
Value:
do if (variant == 1) \
{ \
const uint8_t tmp = ((const uint8_t*)(p))[11]; \
static const uint32_t table = 0x75310; \
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \
((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \
} while(0)
unsigned char uint8_t
Definition stdint.h:124

◆ VARIANT1_2

#define VARIANT1_2 ( p)
Value:
do if (variant == 1) \
{ \
xor64(p, tweak1_2); \
} while(0)

◆ VARIANT1_CHECK

#define VARIANT1_CHECK ( )
Value:
do if (length < 43) \
{ \
fprintf(stderr, "Cryptonight variant 1 needs at least 43 bytes of data"); \
_exit(1); \
} while(0)

◆ VARIANT1_INIT64

#define VARIANT1_INIT64 ( )
Value:
if (variant == 1) \
{ \
VARIANT1_CHECK(); \
} \
const uint64_t tweak1_2 = (variant == 1) ? (state.hs.w[24] ^ (*((const uint64_t*)NONCE_POINTER))) : 0
#define NONCE_POINTER
Definition slow-hash.c:142
Definition blake256.h:36

◆ VARIANT1_PORTABLE_INIT

#define VARIANT1_PORTABLE_INIT ( )
Value:
uint8_t tweak1_2[8]; \
do if (variant == 1) \
{ \
VARIANT1_CHECK(); \
memcpy(&tweak1_2, &state.hs.b[192], sizeof(tweak1_2)); \
xor64(tweak1_2, NONCE_POINTER); \
} while(0)

◆ VARIANT2_2

#define VARIANT2_2 ( )
Value:
do if (variant == 2 || variant == 3) \
{ \
*U64(local_hp_state + (j ^ 0x10)) ^= SWAP64LE(hi); \
*(U64(local_hp_state + (j ^ 0x10)) + 1) ^= SWAP64LE(lo); \
hi ^= SWAP64LE(*U64(local_hp_state + (j ^ 0x20))); \
lo ^= SWAP64LE(*(U64(local_hp_state + (j ^ 0x20)) + 1)); \
} while (0)
#define U64(x)
Definition slow-hash.c:1734

◆ VARIANT2_2_PORTABLE

#define VARIANT2_2_PORTABLE ( )
Value:
if (variant == 2 || variant == 3) { \
xor_blocks(long_state + (j ^ 0x10), d); \
xor_blocks(d, long_state + (j ^ 0x20)); \
}
Definition d.py:1

◆ VARIANT2_INIT64

#define VARIANT2_INIT64 ( )
Value:
uint64_t division_result = 0; \
uint64_t sqrt_result = 0; \
do if (variant >= 2) \
{ \
U64(b)[2] = state.hs.w[8] ^ state.hs.w[10]; \
U64(b)[3] = state.hs.w[9] ^ state.hs.w[11]; \
division_result = SWAP64LE(state.hs.w[12]); \
sqrt_result = SWAP64LE(state.hs.w[13]); \
} while (0)
cryptonote::block b
Definition block.cpp:40

◆ VARIANT2_INTEGER_MATH_DIVISION_STEP

#define VARIANT2_INTEGER_MATH_DIVISION_STEP ( b,
ptr )
Value:
uint64_t tmpx = division_result ^ (sqrt_result << 32); \
((uint64_t*)(b))[0] ^= SWAP64LE(tmpx); \
{ \
const uint64_t dividend = SWAP64LE(((uint64_t*)(ptr))[1]); \
const uint32_t divisor = (SWAP64LE(((uint64_t*)(ptr))[0]) + (uint32_t)(sqrt_result << 1)) | 0x80000001UL; \
division_result = ((uint32_t)(dividend / divisor)) + \
(((uint64_t)(dividend % divisor)) << 32); \
} \
const uint64_t sqrt_input = SWAP64LE(((uint64_t*)(ptr))[0]) + division_result

◆ VARIANT2_INTEGER_MATH_SSE2

#define VARIANT2_INTEGER_MATH_SSE2 ( b,
ptr )
Value:
do if ((variant == 2) || (variant == 3)) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2(); \
VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result); \
} while(0)

◆ VARIANT2_PORTABLE_INIT

#define VARIANT2_PORTABLE_INIT ( )
Value:
uint64_t division_result = 0; \
uint64_t sqrt_result = 0; \
do if (variant >= 2) \
{ \
memcpy(b + AES_BLOCK_SIZE, state.hs.b + 64, AES_BLOCK_SIZE); \
xor64(b + AES_BLOCK_SIZE, state.hs.b + 80); \
xor64(b + AES_BLOCK_SIZE + 8, state.hs.b + 88); \
division_result = SWAP64LE(state.hs.w[12]); \
sqrt_result = SWAP64LE(state.hs.w[13]); \
} while (0)
#define AES_BLOCK_SIZE
Definition aesb.c:32

◆ VARIANT2_PORTABLE_INTEGER_MATH

#define VARIANT2_PORTABLE_INTEGER_MATH ( b,
ptr )
Value:
do if ((variant == 2) || (variant == 3)) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_REF(); \
} while (0)

◆ VARIANT2_PORTABLE_SHUFFLE_ADD

#define VARIANT2_PORTABLE_SHUFFLE_ADD ( out,
a_,
base_ptr,
offset )

◆ VARIANT2_SHUFFLE_ADD_NEON

#define VARIANT2_SHUFFLE_ADD_NEON ( base_ptr,
offset )
Value:
do if (variant >= 2) \
{ \
uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \
const uint64x2_t chunk2 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x20))); \
const uint64x2_t chunk3 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64(U64((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
if (variant >= 4) \
{ \
chunk1 = veorq_u64(chunk1, chunk2); \
_c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk3)); \
_c = vreinterpretq_u8_u64(veorq_u64(vreinterpretq_u64_u8(_c), chunk1)); \
} \
} while (0)

◆ VARIANT2_SHUFFLE_ADD_SSE2

#define VARIANT2_SHUFFLE_ADD_SSE2 ( base_ptr,
offset )
Value:
do if (variant >= 2) \
{ \
__m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
if (variant >= 4) \
{ \
chunk1 = _mm_xor_si128(chunk1, chunk2); \
_c = _mm_xor_si128(_c, chunk3); \
_c = _mm_xor_si128(_c, chunk1); \
} \
} while (0)

◆ VARIANT4_RANDOM_MATH

#define VARIANT4_RANDOM_MATH ( a,
b,
r,
_b,
_b1 )

◆ VARIANT4_RANDOM_MATH_INIT

#define VARIANT4_RANDOM_MATH_INIT ( )
Value:
v4_reg r[9]; \
int jit = use_v4_jit(); \
do if (variant >= 4) \
{ \
for (int i = 0; i < 4; ++i) \
V4_REG_LOAD(r + i, (uint8_t*)(state.hs.w + 12) + sizeof(v4_reg) * i); \
v4_random_math_init(code, height); \
if (jit) \
{ \
int ret = v4_generate_JIT_code(code, hp_jitfunc, 4096); \
if (ret < 0) \
local_abort("Error generating CryptonightR code"); \
} \
} while (0)
int v4_generate_JIT_code(const struct V4_Instruction *code, v4_random_math_JIT_func buf, const size_t buf_size)
Definition CryptonightR_JIT.c:58
const portMappingElt code
Definition portlistingparse.c:22
#define V4_REG_LOAD(dst, src)
Definition slow-hash.c:310
#define hp_jitfunc
Definition slow-hash.c:1691
static int use_v4_jit(void)
Definition slow-hash.c:75
Definition variant4_random_math.h:54
@ NUM_INSTRUCTIONS_MAX
Definition variant4_random_math.h:16

Function Documentation

◆ aesb_pseudo_round()

void aesb_pseudo_round ( const uint8_t * in,
uint8_t * out,
const uint8_t * expandedKey )
extern

◆ aesb_single_round()

void aesb_single_round ( const uint8_t * in,
uint8_t * out,
const uint8_t * expandedKey )
extern

◆ cn_slow_hash()

void cn_slow_hash ( const void * data,
size_t length,
char * hash,
int variant,
int prehashed,
uint64_t height )

◆ cn_slow_hash_allocate_state()

void cn_slow_hash_allocate_state ( void )

◆ cn_slow_hash_free_state()

void cn_slow_hash_free_state ( void )

◆ copy_block()

void copy_block ( uint8_t * dst,
const uint8_t * src )
static

◆ e2i()

size_t e2i ( const uint8_t * a,
size_t count )
static

◆ local_abort()

void local_abort ( const char * msg)
static

◆ mul()

void mul ( const uint8_t * a,
const uint8_t * b,
uint8_t * res )
static

◆ slow_hash_allocate_state()

void slow_hash_allocate_state ( void )

◆ slow_hash_free_state()

void slow_hash_free_state ( void )

◆ sum_half_blocks()

void sum_half_blocks ( uint8_t * a,
const uint8_t * b )
static

◆ swap_blocks()

void swap_blocks ( uint8_t * a,
uint8_t * b )
static

◆ use_v4_jit()

int use_v4_jit ( void )
inlinestatic

◆ xor64()

void xor64 ( uint8_t * left,
const uint8_t * right )
static

◆ xor_blocks()

void xor_blocks ( uint8_t * a,
const uint8_t * b )
static

Variable Documentation

◆ extra_hashes

void(*const extra_hashes[4])(const void *, size_t, char *) ( const void * ,
size_t ,
char *  )
static
Initial value:
= {
}
void hash_extra_blake(const void *data, size_t length, char *hash)
Definition hash-extra-blake.c:36
void hash_extra_groestl(const void *data, size_t length, char *hash)
Definition hash-extra-groestl.c:36
void hash_extra_jh(const void *data, size_t length, char *hash)
Definition hash-extra-jh.c:39
void hash_extra_skein(const void *data, size_t length, char *hash)
Definition hash-extra-skein.c:37

◆ use_v4_jit_flag

volatile int use_v4_jit_flag = -1