REDACTED-rig/src/crypto/argon2_hasher/hash/argon2/Argon2.cpp
2019-08-26 12:38:34 +03:00

143 lines
4.8 KiB
C++
Executable file

//
// Created by Haifa Bogdan Adnan on 05/08/2018.
//
#include "../../common/common.h"
#include "../../crypt/base64.h"
#include "../../crypt/hex.h"
#include "../../crypt/random_generator.h"
#include "blake2/blake2.h"
#include "../../common/DLLExport.h"
#include "../../../Argon2_constants.h"
#include "Argon2.h"
#include "Defs.h"
Argon2::Argon2(argon2BlocksPrehash prehash, argon2BlocksFillerPtr filler, argon2BlocksPosthash posthash, void *memory, void *userData) {
m_prehash = prehash;
m_filler = filler;
m_posthash = posthash;
m_outputMemory = m_seedMemory = (uint8_t*)memory;
m_userData = userData;
m_threads = 1;
}
int Argon2::generateHashes(const Argon2Profile &profile, HashData &hashData) {
if(initializeSeeds(profile, hashData)) {
if(fillBlocks(profile)) {
return encodeHashes(profile, hashData);
}
}
return 0;
}
bool Argon2::initializeSeeds(const Argon2Profile &profile, HashData &hashData) {
if(m_prehash != NULL) {
return (*m_prehash)(hashData.input, m_threads, (Argon2Profile*)&profile, m_userData);
}
else {
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
for (int i = 0; i < m_threads; i++, (*(nonce(hashData)))++) {
initialHash(profile, blockhash, (char *) hashData.input, hashData.inSize, xmrig::ARGON2_HASHLEN);
memset(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0,
ARGON2_PREHASH_SEED_LENGTH -
ARGON2_PREHASH_DIGEST_LENGTH);
fillFirstBlocks(profile, blockhash, i);
}
return true;
}
}
bool Argon2::fillBlocks(const Argon2Profile &profile) {
m_outputMemory = (uint8_t *)(*m_filler) (m_threads, (Argon2Profile*)&profile, m_userData);
return m_outputMemory != NULL;
}
int Argon2::encodeHashes(const Argon2Profile &profile, HashData &hashData) {
if(m_posthash != NULL) {
if((*m_posthash)(hashData.output, m_threads, (Argon2Profile*)&profile, m_userData)) {
return m_threads;
}
return 0;
}
else {
if (m_outputMemory != NULL) {
uint32_t nonceInfo = *(nonce(hashData)) - m_threads;
for (int i = 0; i < m_threads; i++, nonceInfo++) {
blake2b_long((void *) (hashData.output + i * hashData.outSize), xmrig::ARGON2_HASHLEN,
(void *) (m_outputMemory + i * profile.memSize), ARGON2_BLOCK_SIZE);
memcpy(hashData.output + i * hashData.outSize + xmrig::ARGON2_HASHLEN, &nonceInfo, 4);
}
return m_threads;
}
else
return 0;
}
}
void Argon2::initialHash(const Argon2Profile &profile, uint8_t *blockhash, const char *data, size_t dataSz,size_t outSz) {
blake2b_state BlakeHash;
uint32_t value;
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
value = profile.thrCost;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = outSz;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = profile.memCost;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = profile.tmCost;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = ARGON2_VERSION;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = ARGON2_TYPE_VALUE;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
value = (uint32_t)dataSz;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
blake2b_update(&BlakeHash, (const uint8_t *)data, dataSz);
value = xmrig::ARGON2_SALTLEN;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
blake2b_update(&BlakeHash, (const uint8_t *)data, xmrig::ARGON2_SALTLEN);
value = 0;
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
}
void Argon2::fillFirstBlocks(const Argon2Profile &profile, uint8_t *blockhash, int thread) {
block *blocks = (block *)(m_seedMemory + thread * profile.memSize);
size_t lane_length = profile.memCost / profile.thrCost;
for (uint32_t l = 0; l < profile.thrCost; ++l) {
*((uint32_t*)(blockhash + ARGON2_PREHASH_DIGEST_LENGTH)) = 0;
*((uint32_t*)(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4)) = l;
blake2b_long((void *)(blocks + l * lane_length), ARGON2_BLOCK_SIZE, blockhash,
ARGON2_PREHASH_SEED_LENGTH);
*((uint32_t*)(blockhash + ARGON2_PREHASH_DIGEST_LENGTH)) = 1;
blake2b_long((void *)(blocks + l * lane_length + 1), ARGON2_BLOCK_SIZE, blockhash,
ARGON2_PREHASH_SEED_LENGTH);
}
}
void Argon2::setThreads(int threads) {
m_threads = threads;
}