近日阅读了比特币源码中与哈希相关的部分,对于其中一些细节还是有不清晰的地方。
于是我写了一个小的测试demo:sha256_test
,代码下载
分别测试了三个版本对于SHA-256算法的实现:
对比发现,开源算法库crypto-algorithms
与在线SHA-256测试工具
对于同一数据的哈希结果相同,但 Bitcoin Version
的哈希结果与其余两个测试版本不一致。因此,我想了解:
比特币中的SHA256算法的实现与标准的SHA256算法实现是否相同?
如果相同,那一定是我对比特币源码的使用出现了问题,可否指出我在测试时调用错误的地方?
如果不相同,可否指出哪些实现细节有差异,比如或许大小端的差异?字符串转换存在差异?
具体地,我将Bitcoin Core源码中与SHA256相关的部分剥离出来,放置于sha256_test
目录下,构成Bitcoin Version
的测试代码
我将开源算法库crypto-algorithms
中与SHA256相关的部分,放置于standard_implement_test
目录下,构成crypto Version
的测试代码
在线测试工具对于字符串”hello”的计算结果如下:
Conversion Completed
Your hash has been successfully generated.
hex: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
HEX: 2CF24DBA5FB0A30E26E83B2AC5B9E29E1B161E5C1FA7425E73043362938B9824
算法库crypto-algorithms
对于字符串”hello”的计算结果如下:
$ ./test
the string to test SHA-256: hello
result of SHA-256
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Bitcoin Version对于字符串”hello”的计算结果如下:
其中,我使用了两种方法从哈希结果中解析出16进制字符串,但均与希望的结果不一致。
$ ./test hello
The string to test SHA-256:
hello
Bitcoin SHA-256 result by GetHex():
fa20f248146c7b29c2d6d2b52ed56fd6465503a39919ca848d763bd32d72f95c
Bitcoin SHA-256 result by parse data[Width]:
5cf9722dd33b768d84ca1999a3035546d66fd52eb5d2d6c2297b6c1448f220fa
Bitcoin Version包含了以下文件:
$ ls
common.h sha256.h tinyformat.h utilstrencodings.cpp
makefile standard_implementation uint256.cpp utilstrencodings.h
sha256.cpp test.cpp uint256.h
test.cpp的代码如下:
#include<iostream>
#include "sha256.h"
#include "uint256.h"
//using namespace std;
int main(int argc, char* argv[])
{
if(argc!=2)
{
std::cout<<"please type a string to test sha-256"<<std::endl;
return 1;
}
char* str = argv[1];
std::cout << "The string to test SHA-256:" << std::endl;
int strLen = strlen(str);
for(char* p = str; p<str+strLen; p++)
{
std::cout<<*p;
}
std::cout<<std::endl;
uint256 sha256_result;
// use code in Bitcoin Core to solve SHA-256
CSHA256 sha;
sha.Write((unsigned char*)str, strLen);
sha.Finalize((unsigned char*)&sha256_result);
// show hash result by GetHex()
std::cout << std::endl << "Bitcoin SHA-256 result by GetHex():" << std::endl;
std::cout << sha256_result.GetHex() << std::endl;
// show hash result by parsing member variable data[Width]
std::cout << std::endl << "Bitcoin SHA-256 result by parse data[Width]:" << std::endl;
unsigned int size = sha256_result.size();
unsigned char* pointer = sha256_result.begin();
unsigned char temp;
for(unsigned char* pdata = pointer; pdata < pointer + size; pdata++)
{
temp = *pdata;
unsigned char hex1 = temp >> 4;
unsigned char hex2 = temp & 0x0f;
if(hex1<10)
std::printf("%c",hex1+48);
else
std::printf("%c",hex1+87);
if(hex2<10)
std::printf("%c",hex2+48);
else
std::printf("%c",hex2+87);
}
std::cout << std::endl;
}
如果哪位大神有见解,多多交流,还望赐教~
后续如果对于这个问题有了答案,我会回来更新的。