mirror of
https://github.com/jwinterm/xmr-stak.git
synced 2026-10-17 05:41:41 +02:00
188 lines
4.6 KiB
C++
188 lines
4.6 KiB
C++
/*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
extern "C"
|
|
{
|
|
#include "c_groestl.h"
|
|
#include "c_blake256.h"
|
|
#include "c_jh.h"
|
|
#include "c_skein.h"
|
|
}
|
|
#include "cryptonight.h"
|
|
#include "cryptonight_aesni.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef __GNUC__
|
|
#include <mm_malloc.h>
|
|
#else
|
|
#include <malloc.h>
|
|
#endif // __GNUC__
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#else
|
|
#include <sys/mman.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#endif // _WIN32
|
|
|
|
void do_blake_hash(const void* input, size_t len, char* output) {
|
|
blake256_hash((uint8_t*)output, (const uint8_t*)input, len);
|
|
}
|
|
|
|
void do_groestl_hash(const void* input, size_t len, char* output) {
|
|
groestl((const uint8_t*)input, len * 8, (uint8_t*)output);
|
|
}
|
|
|
|
void do_jh_hash(const void* input, size_t len, char* output) {
|
|
jh_hash(32 * 8, (const uint8_t*)input, 8 * len, (uint8_t*)output);
|
|
}
|
|
|
|
void do_skein_hash(const void* input, size_t len, char* output) {
|
|
skein_hash(8 * 32, (const uint8_t*)input, 8 * len, (uint8_t*)output);
|
|
}
|
|
|
|
void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
|
|
|
|
#ifdef _WIN32
|
|
BOOL AddPrivilege(TCHAR* pszPrivilege)
|
|
{
|
|
HANDLE hToken;
|
|
TOKEN_PRIVILEGES tp;
|
|
BOOL status;
|
|
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
return FALSE;
|
|
|
|
if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))
|
|
return FALSE;
|
|
|
|
tp.PrivilegeCount = 1;
|
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
status = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
|
|
|
if (!status || (GetLastError() != ERROR_SUCCESS))
|
|
return FALSE;
|
|
|
|
CloseHandle(hToken);
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
size_t cryptonight_init(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg)
|
|
{
|
|
#ifdef _WIN32
|
|
if (AddPrivilege(TEXT("SeLockMemoryPrivilege")) == 0)
|
|
{
|
|
msg->warning = "Obtaning SeLockMemoryPrivilege failed.";
|
|
return 0;
|
|
}
|
|
return 1;
|
|
#else
|
|
return 1;
|
|
#endif // _WIN32
|
|
}
|
|
|
|
cryptonight_ctx* cryptonight_alloc_ctx(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg)
|
|
{
|
|
cryptonight_ctx* ptr = (cryptonight_ctx*)_mm_malloc(sizeof(cryptonight_ctx), 4096);
|
|
|
|
if(use_fast_mem == 0)
|
|
{
|
|
ptr->long_state = (uint8_t*)_mm_malloc(MEMORY, 4096);
|
|
ptr->ctx_info[0] = 0;
|
|
ptr->ctx_info[1] = 0;
|
|
return ptr;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
SIZE_T iLargePageMin = GetLargePageMinimum();
|
|
|
|
if(MEMORY > iLargePageMin)
|
|
iLargePageMin *= 2;
|
|
|
|
ptr->long_state = (uint8_t*)VirtualAlloc(NULL, iLargePageMin,
|
|
MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
|
|
|
|
if(ptr->long_state == NULL)
|
|
{
|
|
_mm_free(ptr);
|
|
msg->warning = "VirtualAlloc failed.";
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
ptr->ctx_info[0] = 1;
|
|
return ptr;
|
|
}
|
|
#else
|
|
ptr->long_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0);
|
|
|
|
if (ptr->long_state == MAP_FAILED)
|
|
{
|
|
_mm_free(ptr);
|
|
msg->warning = "mmap failed";
|
|
return NULL;
|
|
}
|
|
|
|
ptr->ctx_info[0] = 1;
|
|
|
|
if(madvise(ptr->long_state, MEMORY, MADV_RANDOM|MADV_WILLNEED) != 0)
|
|
msg->warning = "madvise failed";
|
|
|
|
ptr->ctx_info[1] = 0;
|
|
if(use_mlock != 0 && mlock(ptr->long_state, MEMORY) != 0)
|
|
msg->warning = "mlock failed";
|
|
else
|
|
ptr->ctx_info[1] = 1;
|
|
|
|
return ptr;
|
|
#endif // _WIN32
|
|
}
|
|
|
|
void cryptonight_free_ctx(cryptonight_ctx* ctx)
|
|
{
|
|
if(ctx->ctx_info[0] != 0)
|
|
{
|
|
#ifdef _WIN32
|
|
VirtualFree(ctx->long_state, 0, MEM_RELEASE);
|
|
#else
|
|
if(ctx->ctx_info[1] != 0)
|
|
munlock(ctx->long_state, MEMORY);
|
|
munmap(ctx->long_state, MEMORY);
|
|
#endif // _WIN32
|
|
}
|
|
else
|
|
_mm_free(ctx->long_state);
|
|
|
|
_mm_free(ctx);
|
|
}
|
|
|
|
void cryptonight_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* ctx)
|
|
{
|
|
cryptonight_hash<0x8000, MEMORY, true>(input, len, output, ctx);
|
|
}
|
|
|
|
void cryptonight_hash_ctx_np(const void* input, size_t len, void* output, cryptonight_ctx* ctx)
|
|
{
|
|
cryptonight_hash<0x8000, MEMORY, false>(input, len, output, ctx);
|
|
}
|
|
|
|
void cryptonight_double_hash_ctx(const void* input, size_t len, void* output, cryptonight_ctx* __restrict ctx0, cryptonight_ctx* __restrict ctx1)
|
|
{
|
|
cryptonight_double_hash<0x8000, MEMORY, false>(input, len, output, ctx0, ctx1);
|
|
} |