Monero
Classes | Macros | Functions | Variables
slow-hash.c File Reference
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "common/int-util.h"
#include "hash-ops.h"
#include "oaes_lib.h"
#include "variant2_int_sqrt.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 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(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 U64(x)   ((uint64_t *) (x))
 

Functions

int aesb_single_round (const uint8_t *in, uint8_t *out, const uint8_t *expandedKey)
 
int aesb_pseudo_round (const uint8_t *in, uint8_t *out, const uint8_t *expandedKey)
 
void slow_hash_allocate_state (void)
 
void 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)
 

Variables

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

◆ 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)

◆ U64

#define U64 (   x)    ((uint64_t *) (x))

◆ 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)

◆ 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
Definition: blake256.h:36
#define NONCE_POINTER
Definition: slow-hash.c:75

◆ 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)
Definition: blake256.h:36
#define NONCE_POINTER
Definition: slow-hash.c:75

◆ VARIANT2_2

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

◆ VARIANT2_2_PORTABLE

#define VARIANT2_2_PORTABLE ( )
Value:
if (variant >= 2) { \
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 = state.hs.w[12]; \
sqrt_result = state.hs.w[13]; \
} while (0)
int b
Definition: base.py:1
Definition: blake256.h:36

◆ VARIANT2_INTEGER_MATH_DIVISION_STEP

#define VARIANT2_INTEGER_MATH_DIVISION_STEP (   b,
  ptr 
)
Value:
((uint64_t*)(b))[0] ^= division_result ^ (sqrt_result << 32); \
{ \
const uint64_t dividend = ((uint64_t*)(ptr))[1]; \
const uint32_t divisor = (((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 = ((uint64_t*)(ptr))[0] + division_result
int b
Definition: base.py:1

◆ VARIANT2_INTEGER_MATH_SSE2

#define VARIANT2_INTEGER_MATH_SSE2 (   b,
  ptr 
)
Value:
do if (variant >= 2) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2(); \
VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result); \
} while(0)
int b
Definition: base.py:1

◆ 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 = state.hs.w[12]; \
sqrt_result = state.hs.w[13]; \
} while (0)
#define AES_BLOCK_SIZE
Definition: slow-hash.c:45
int b
Definition: base.py:1
Definition: blake256.h:36

◆ VARIANT2_PORTABLE_INTEGER_MATH

#define VARIANT2_PORTABLE_INTEGER_MATH (   b,
  ptr 
)
Value:
do if (variant >= 2) \
{ \
VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \
VARIANT2_INTEGER_MATH_SQRT_STEP_REF(); \
} while (0)
int b
Definition: base.py:1

◆ VARIANT2_PORTABLE_SHUFFLE_ADD

#define VARIANT2_PORTABLE_SHUFFLE_ADD (   base_ptr,
  offset 
)
Value:
do if (variant >= 2) \
{ \
uint64_t* chunk1 = U64((base_ptr) + ((offset) ^ 0x10)); \
uint64_t* chunk2 = U64((base_ptr) + ((offset) ^ 0x20)); \
uint64_t* chunk3 = U64((base_ptr) + ((offset) ^ 0x30)); \
\
const uint64_t chunk1_old[2] = { chunk1[0], chunk1[1] }; \
\
uint64_t b1[2]; \
memcpy(b1, b + 16, 16); \
chunk1[0] = chunk3[0] + b1[0]; \
chunk1[1] = chunk3[1] + b1[1]; \
\
uint64_t a0[2]; \
memcpy(a0, a, 16); \
chunk3[0] = chunk2[0] + a0[0]; \
chunk3[1] = chunk2[1] + a0[1]; \
\
uint64_t b0[2]; \
memcpy(b0, b, 16); \
chunk2[0] = chunk1_old[0] + b0[0]; \
chunk2[1] = chunk1_old[1] + b0[1]; \
} while (0)
#define U64(x)
Definition: slow-hash.c:1409
int b
Definition: base.py:1
string a
Definition: MakeCryptoOps.py:15

◆ VARIANT2_SHUFFLE_ADD_NEON

#define VARIANT2_SHUFFLE_ADD_NEON (   base_ptr,
  offset 
)
Value:
do if (variant >= 2) \
{ \
const 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))); \
} while (0)
#define U64(x)
Definition: slow-hash.c:1409

◆ VARIANT2_SHUFFLE_ADD_SSE2

#define VARIANT2_SHUFFLE_ADD_SSE2 (   base_ptr,
  offset 
)
Value:
do if (variant >= 2) \
{ \
const __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)); \
} while (0)

Function Documentation

◆ aesb_pseudo_round()

int aesb_pseudo_round ( const uint8_t *  in,
uint8_t *  out,
const uint8_t *  expandedKey 
)

◆ aesb_single_round()

int aesb_single_round ( const uint8_t *  in,
uint8_t *  out,
const uint8_t *  expandedKey 
)

◆ cn_slow_hash()

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

◆ copy_block()

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

◆ e2i()

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

◆ mul()

static 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()

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

◆ swap_blocks()

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

◆ xor64()

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

◆ xor_blocks()

static 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 *)
static
Initial value:
= {
}
void hash_extra_jh(const void *data, size_t length, char *hash)
Definition: hash-extra-jh.c:39
void hash_extra_blake(const void *data, size_t length, char *hash)
Definition: hash-extra-blake.c:36
void hash_extra_skein(const void *data, size_t length, char *hash)
Definition: hash-extra-skein.c:37
void hash_extra_groestl(const void *data, size_t length, char *hash)
Definition: hash-extra-groestl.c:36