Задача
Так что я использую C ++ с библиотекой OpenSSL, чтобы попытаться реализовать мой собственный блокчейн с нуля, и все шло очень хорошо, пока я не наткнулся на проблему:
Как я могу хранить свои 256-битные хеш-коды?
Сначала я попытался реализовать свой собственный 256-битный тип из
uint8_t.
но потом я сдался и решил использовать OpenSSL 'bignums.
Но вот, насколько я знаю, бигнумы 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-битное деление и сравнение с большим равенством.
Пожалуйста, помогите мне !!