Path: blob/master/algo/cryptonight.c
1295 views
// Copyright (c) 2012-2013 The Cryptonote developers1// Distributed under the MIT/X11 software license, see the accompanying2// file COPYING or http://www.opensource.org/licenses/mit-license.php.34// Modified for CPUminer by Lucas Jones56#include "miner.h"78#if defined(__arm__) || defined(_MSC_VER)9#ifndef NOASM10#define NOASM11#endif12#endif1314#include "crypto/oaes_lib.h"15#include "crypto/c_keccak.h"16#include "crypto/c_groestl.h"17#include "crypto/c_blake256.h"18#include "crypto/c_jh.h"19#include "crypto/c_skein.h"20#include "crypto/int-util.h"21#include "crypto/hash-ops.h"2223#if USE_INT1282425#if __GNUC__ == 4 && __GNUC_MINOR__ >= 4 && __GNUC_MINOR__ < 626typedef unsigned int uint128_t __attribute__ ((__mode__ (TI)));27#elif defined (_MSC_VER)28/* only for mingw64 on windows */29#undef USE_INT12830#define USE_INT128 (0)31#else32typedef __uint128_t uint128_t;33#endif3435#endif3637#define LITE 038#if LITE /* cryptonight-light */39#define MEMORY (1 << 20)40#define ITER (1 << 19)41#else42#define MEMORY (1 << 21) /* 2 MiB */43#define ITER (1 << 20)44#endif4546#define AES_BLOCK_SIZE 1647#define AES_KEY_SIZE 32 /*16*/48#define INIT_SIZE_BLK 849#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE)5051#pragma pack(push, 1)52union cn_slow_hash_state {53union hash_state hs;54struct {55uint8_t k[64];56uint8_t init[INIT_SIZE_BYTE];57};58};59#pragma pack(pop)6061static void do_blake_hash(const void* input, size_t len, char* output) {62blake256_hash((uint8_t*)output, input, len);63}6465static void do_groestl_hash(const void* input, size_t len, char* output) {66groestl(input, len * 8, (uint8_t*)output);67}6869static void do_jh_hash(const void* input, size_t len, char* output) {70int r = jh_hash(HASH_SIZE * 8, input, 8 * len, (uint8_t*)output);71assert(likely(SUCCESS == r));72}7374static void do_skein_hash(const void* input, size_t len, char* output) {75int r = skein_hash(8 * HASH_SIZE, input, 8 * len, (uint8_t*)output);76assert(likely(SKEIN_SUCCESS == r));77}7879extern int aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey);80extern int aesb_pseudo_round_mut(uint8_t *val, uint8_t *expandedKey);81#if !defined(_MSC_VER) && !defined(NOASM)82extern int fast_aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey);83extern int fast_aesb_pseudo_round_mut(uint8_t *val, uint8_t *expandedKey);84#else85#define fast_aesb_single_round aesb_single_round86#define fast_aesb_pseudo_round_mut aesb_pseudo_round_mut87#endif8889#if defined(NOASM) || !defined(__x86_64__)90static uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) {91// multiplier = ab = a * 2^32 + b92// multiplicand = cd = c * 2^32 + d93// ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d94uint64_t a = hi_dword(multiplier);95uint64_t b = lo_dword(multiplier);96uint64_t c = hi_dword(multiplicand);97uint64_t d = lo_dword(multiplicand);9899uint64_t ac = a * c;100uint64_t ad = a * d;101uint64_t bc = b * c;102uint64_t bd = b * d;103104uint64_t adbc = ad + bc;105uint64_t adbc_carry = adbc < ad ? 1 : 0;106107// multiplier * multiplicand = product_hi * 2^64 + product_lo108uint64_t product_lo = bd + (adbc << 32);109uint64_t product_lo_carry = product_lo < bd ? 1 : 0;110*product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry;111assert(ac <= *product_hi);112113return product_lo;114}115#else116extern uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi);117#endif118119static void (* const extra_hashes[4])(const void *, size_t, char *) = {120do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash121};122123124static inline size_t e2i(const uint8_t* a) {125#if !LITE126return ((uint32_t *)a)[0] & 0x1FFFF0;127#else128return ((uint32_t *)a)[0] & 0xFFFF0;129#endif130}131132static inline void mul_sum_xor_dst(const uint8_t* a, uint8_t* c, uint8_t* dst, int variant, const uint64_t tweak) {133uint64_t hi, lo = mul128(((uint64_t*) a)[0], ((uint64_t*) dst)[0], &hi) + ((uint64_t*) c)[1];134hi += ((uint64_t*) c)[0];135((uint64_t*) c)[0] = ((uint64_t*) dst)[0] ^ hi;136((uint64_t*) c)[1] = ((uint64_t*) dst)[1] ^ lo;137((uint64_t*) dst)[0] = hi;138((uint64_t*) dst)[1] = variant ? lo ^ tweak : lo;139}140141static inline void xor_blocks(uint8_t* a, const uint8_t* b) {142#if USE_INT128143*((uint128_t*) a) ^= *((uint128_t*) b);144#else145((uint64_t*) a)[0] ^= ((uint64_t*) b)[0];146((uint64_t*) a)[1] ^= ((uint64_t*) b)[1];147#endif148}149150static inline void xor_blocks_dst(const uint8_t* a, const uint8_t* b, uint8_t* dst) {151#if USE_INT128152*((uint128_t*) dst) = *((uint128_t*) a) ^ *((uint128_t*) b);153#else154((uint64_t*) dst)[0] = ((uint64_t*) a)[0] ^ ((uint64_t*) b)[0];155((uint64_t*) dst)[1] = ((uint64_t*) a)[1] ^ ((uint64_t*) b)[1];156#endif157}158159static void cryptonight_store_variant(void* state, int variant) {160if (variant == 1) {161const uint8_t tmp = ((const uint8_t*)(state))[11];162const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1;163((uint8_t*)(state))[11] = tmp ^ ((0x75310 >> index) & 0x30);164}165}166167struct cryptonight_ctx {168uint8_t _ALIGN(16) long_state[MEMORY];169union cn_slow_hash_state state;170uint8_t _ALIGN(16) text[INIT_SIZE_BYTE];171uint8_t _ALIGN(16) a[AES_BLOCK_SIZE];172uint8_t _ALIGN(16) b[AES_BLOCK_SIZE];173uint8_t _ALIGN(16) c[AES_BLOCK_SIZE];174oaes_ctx* aes_ctx;175};176177static void cryptonight_hash_ctx(void* output, const void* input, int len, struct cryptonight_ctx* ctx, int variant)178{179size_t i, j;180181hash_process(&ctx->state.hs, (const uint8_t*) input, len);182ctx->aes_ctx = (oaes_ctx*) oaes_alloc();183memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);184185const uint64_t tweak = variant ? *((uint64_t*) (((uint8_t*)input) + 35)) ^ ctx->state.hs.w[24] : 0;186187oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);188for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {189aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data);190aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data);191aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data);192aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data);193aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data);194aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data);195aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data);196aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data);197memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);198}199200xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a);201xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b);202203for (i = 0; likely(i < ITER / 4); ++i) {204/* Dependency chain: address -> read value ------+205* written value <-+ hard function (AES or MUL) <+206* next address <-+207*/208/* Iteration 1 */209j = e2i(ctx->a);210aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a);211xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);212/* Iteration 2 */213cryptonight_store_variant(&ctx->long_state[j], variant);214mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)], variant, tweak);215216/* Iteration 3 */217j = e2i(ctx->a);218aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a);219xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);220/* Iteration 4 */221cryptonight_store_variant(&ctx->long_state[j], variant);222mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)], variant, tweak);223}224225memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);226oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);227for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {228xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]);229aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);230xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]);231aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);232xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]);233aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);234xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]);235aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);236xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]);237aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);238xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]);239aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);240xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]);241aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);242xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]);243aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);244}245memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);246hash_permutation(&ctx->state.hs);247/*memcpy(hash, &state, 32);*/248extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);249oaes_free((OAES_CTX **) &ctx->aes_ctx);250}251252void cryptonight_hash(void* output, const void* input) {253const int variant = 1;254struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx));255cryptonight_hash_ctx(output, input, 76, ctx, variant);256free(ctx);257}258259void cryptonight_hash_v1(void* output, const void* input) {260const int variant = 0;261struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx));262cryptonight_hash_ctx(output, input, 76, ctx, variant);263free(ctx);264}265266static void cryptonight_hash_ctx_aes_ni(void* output, const void* input, int len, struct cryptonight_ctx* ctx, int variant)267{268size_t i, j;269270hash_process(&ctx->state.hs, (const uint8_t*)input, len);271ctx->aes_ctx = (oaes_ctx*) oaes_alloc();272memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);273274const uint64_t tweak = variant ? *((uint64_t*) (((uint8_t*)input) + 35)) ^ ctx->state.hs.w[24] : 0;275276oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);277for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {278fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data);279fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data);280fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data);281fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data);282fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data);283fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data);284fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data);285fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data);286memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);287}288289xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a);290xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b);291292for (i = 0; likely(i < ITER / 4); ++i) {293/* Dependency chain: address -> read value ------+294* written value <-+ hard function (AES or MUL) <+295* next address <-+296*/297/* Iteration 1 */298j = e2i(ctx->a);299fast_aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a);300xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);301/* Iteration 2 */302cryptonight_store_variant(&ctx->long_state[j], variant);303mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)], variant, tweak);304305/* Iteration 3 */306j = e2i(ctx->a);307fast_aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a);308xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);309/* Iteration 4 */310cryptonight_store_variant(&ctx->long_state[j], variant);311mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)], variant, tweak);312}313314memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);315oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);316for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {317xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]);318fast_aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);319xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]);320fast_aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);321xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]);322fast_aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);323xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]);324fast_aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);325xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]);326fast_aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);327xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]);328fast_aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);329xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]);330fast_aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);331xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]);332fast_aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);333}334memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);335hash_permutation(&ctx->state.hs);336/*memcpy(hash, &state, 32);*/337extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);338oaes_free((OAES_CTX **) &ctx->aes_ctx);339}340341int scanhash_cryptonight(int thr_id, struct work *work, uint32_t max_nonce, uint64_t *hashes_done)342{343uint32_t _ALIGN(128) hash[HASH_SIZE / 4];344uint32_t *pdata = work->data;345uint32_t *ptarget = work->target;346347uint32_t *nonceptr = (uint32_t*) (((char*)pdata) + 39);348uint32_t n = *nonceptr - 1;349const uint32_t first_nonce = n + 1;350351// todo: make it dynamic352const int variant = 1;353354struct cryptonight_ctx *ctx = (struct cryptonight_ctx*)malloc(sizeof(struct cryptonight_ctx));355356if (aes_ni_supported) {357do {358*nonceptr = ++n;359cryptonight_hash_ctx_aes_ni(hash, pdata, 76, ctx, variant);360if (unlikely(hash[7] < ptarget[7])) {361work_set_target_ratio(work, hash);362*hashes_done = n - first_nonce + 1;363free(ctx);364return 1;365}366} while (likely((n <= max_nonce && !work_restart[thr_id].restart)));367} else {368do {369*nonceptr = ++n;370cryptonight_hash_ctx(hash, pdata, 76, ctx, variant);371if (unlikely(hash[7] < ptarget[7])) {372work_set_target_ratio(work, hash);373*hashes_done = n - first_nonce + 1;374free(ctx);375return 1;376}377} while (likely((n <= max_nonce && !work_restart[thr_id].restart)));378}379380free(ctx);381*hashes_done = n - first_nonce + 1;382return 0;383}384385386