C++:有效地将Sha256摘要放入OpenSSL Bignum?



>问题

所以我正在使用OpenSSL库的C++来尝试从头开始实现我自己的区块链,一切都进展顺利,直到我偶然遇到一个问题:

如何存储我的 256 位哈希摘要?

起初,我尝试从uint8_t中实现自己的 256 位类型

但后来我放弃了,决定使用OpenSSL的bignums。

但事情是这样的,据我所知,OpenSSL bignums 旨在用于公钥加密函数,我如何执行 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位除法和大等比较。

请帮帮我!!

最后我最终使用 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);
}

最新更新