Windows — C ++: эффективно получить дайджест Sha256 в OpenSSL Bignum?

проблема

Поэтому я использую C ++ с библиотекой OpenSSL, чтобы попытаться реализовать свой собственный блокчейн с нуля, и все шло очень хорошо, пока я не наткнулся на проблему:

Как я могу хранить свои 256-битные дайджесты?

Сначала я попытался реализовать свой собственный 256-битный тип из uint8_t

но потом я сдался и решил использовать bignums OpenSSL.

Но вот в чем дело, насколько мне известно, бигнумы OpenSSL предназначены для использования в криптографических функциях с открытым ключом, как я могу выполнять хэш-функции, такие как sha256, и сохранять дайджест в BigNum?

Или есть альтернативный вариант, который эффективен для хранения 256-битных или более значений?

Вот код, который я использовал до bignums:

UINT<SHA256_DIGEST_LENGTH> Crypto::Sha256 (const std::string &p_Data)
{
UINT<SHA256_DIGEST_LENGTH> result;
SHA256_CTX context;

SHA256_Init (&context);
SHA256_Update (&context, p_Data.c_str (), p_Data.length ());
SHA256_Final (result.m_Bytes, &context);

return result;
}

Вот моя собственная реализация BigNum: (Не очень эффективно)

template<size_t BLOCK_SIZE>
struct UINT
{
size_t blockSize = BLOCK_SIZE;
uint8_t m_Bytes[BLOCK_SIZE];

static UINT<BLOCK_SIZE> Zero ()
{
UINT<BLOCK_SIZE> r;

for ( uint8_t &byte : r.m_Bytes )
byte = 0b0000'0000;

return r;
}

static UINT<BLOCK_SIZE> One ()
{
UINT<BLOCK_SIZE> r;

for ( uint8_t &byte : r.m_Bytes )
byte = 0b1111'1111;

return r;
}

friend std::ostream& operator<<(std::ostream& p_OS, const UINT<BLOCK_SIZE>& p_Value)
{
for ( const uint8_t &byte : p_Value.m_Bytes )
p_OS << (int) byte;

return p_OS;
}

std::string Str ()
{
std::stringstream ss;

for ( const uint8_t &byte : m_Bytes )
ss << (int) byte;

return ss.str();
}

bool operator==(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= ~(X ^ Y);
}

return r;
}

bool operator!=(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= X ^ Y;
}

return r;
}

bool operator>(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= X & ~Y;
}

return r;
}

bool operator<(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= ~X & Y;
}

return r;
}

bool operator>=(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= (X & ~Y) | ~(X ^ Y);
}

return r;
}

bool operator<=(const UINT<BLOCK_SIZE> &p_Other) const
{
bool r = true;

for ( int i = 0; i < 256; ++i )
{
const bool X = (m_Bytes[i / 8] >> (i % 8)) & 1;
const bool Y = (p_Other.m_Bytes[i / 8] >> (i % 8)) & 1;

r &= (~X & Y) | ~(X ^ Y);
}

return r;
}
};

Также важно отметить:
Первоначально я реализовал свою собственную функцию Sha256, но использовать это было бы плохой идеей. Во-первых, я не эксперт в криптографии, во-вторых, с точки зрения масштабируемости это очень плохо, потому что мне пришлось бы также реализовывать все остальные криптографические функции с нуля, поэтому я решил использовать готовые хеш-функции OpenSSL.

Решения, о которых я думал
Я думал об установке каждого бита во вновь созданном BigNum, используя
BN_set_bit (), однако, это было бы не очень эффективно, поскольку мы уже помещаем дайджест в массив uint8_t. Мы будем копировать результаты дважды, что является своего рода глупым решением.

Теперь мне нужна одна из двух вещей:

  • Чтобы сохранить дайджест из Sha256_final или EVP_DigestFinal_ex в bignum
  • Использовать другую структуру данных для хранения этой информации.

И мне нужно уметь выполнять арифметику, хотя бы с 256-битным делением & Большее-Равное сравнение.

Пожалуйста, помогите мне!!

1

Решение

В конце концов я использовал BN_bin2bn () для преобразования uint8_t в BigNum.

#include <openssl/bn.h>

void Crypto::Sha256 (const std::string &p_Data, BIGNUM* hash)
{
uint8_t digestBuffer[256];
SHA256_CTX context;

SHA256_Init (&context);
SHA256_Update (&context, p_Data.c_str (), p_Data.length ());
SHA256_Final (digestBuffer, &context);

BN_bin2bn (digestBuffer, 256, hash);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector