使用openssl实现web3中的SHA3函数

web3中的SHA3

使用keccak-256哈希算法,来计算哈希值,注意这不是标准的SHA3-256函数。
具体的实现如下图所示,需要先转为字节数组



调用:

var hashOfHash = web3.sha3("0000000000000000000000000000000000000000000000000000000000000002", {encoding: 'hex'});
console.log(hashOfHash);

openssl实现

版本:openssl1.1.1
转换为字节数组

void hex2bytearray(char s[], unsigned char bits[])
{
	int n = 0;
	for (int i = 0; s[i]; i += 2) {
		if (s[i] >= 'a' && s[i] <= 'f')
			bits[n] = s[i] - 'a' + 10;
		else bits[n] = s[i] - '0';
		if (s[i + 1] >= 'a' && s[i + 1] <= 'f')
			bits[n] = (bits[n] << 4) | (s[i + 1] - 'a' + 10);
		else bits[n] = (bits[n] << 4) | (s[i + 1] - '0');
		n++;
	}
}

openssl中SHA3和以太坊的差异,以及以下结构参考:https://blog.csdn.net/hnlylyb/article/details/81335862

struct EVP_MD_CTX_t {
	const EVP_MD *digest;
	ENGINE *engine;             /* functional reference if 'digest' is
											* ENGINE-provided */
	unsigned long flags;
	void *md_data;
	/* Public key context for sign/verify */
	EVP_PKEY_CTX *pctx;
	/* Update function: usually copied from EVP_MD */
	int(*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
} /* EVP_MD_CTX */;

struct KECCAK1600_CTX {
	uint64_t A[5][5];
	size_t block_size;          /* cached ctx->digest->block_size */
	size_t md_size;             /* output length, variable in XOF */
	size_t num;                 /* used bytes in below buffer */
	unsigned char buf[1600 / 8 - 32];
	unsigned char pad;
};

之后调用即可

	char *data1 = (char *)"0000000000000000000000000000000000000000000000000000000000000002";
	unsigned char data[32];
	hex2bytearray(data1, data);
	unsigned int size = sizeof(data);

	const EVP_MD* evp_md = EVP_sha3_256();
	EVP_MD_CTX *evp_md_ctx = EVP_MD_CTX_new();
	EVP_DigestInit(evp_md_ctx, evp_md);
	KECCAK1600_CTX* keccak256 = reinterpret_cast<KECCAK1600_CTX*>((reinterpret_cast<EVP_MD_CTX_t*>(evp_md_ctx))->md_data);
	keccak256->pad = 0x01;
	EVP_DigestUpdate(evp_md_ctx, data, size);
	unsigned int * len = new unsigned[10];
	unsigned char* result = (unsigned char*)malloc(32);
	EVP_DigestFinal(evp_md_ctx, result, &size);

	for (int i = 0; i < 32; i++) //16进制输出
	{
		printf("%02x", (int)result[i]);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenSSL ,PRF(Pseudo-Random Function)函数是通过使用 HMAC(Hash-based Message Authentication Code)函数实现的。HMAC 是一种基于哈希函数的消息认证码,用于计算消息的完整性和真实性。 以下是一个使用 OpenSSL 的 PRF 函数的示例代码: ```c #include <openssl/ssl.h> #include <openssl/hmac.h> // 计算 PRF 值 void calculate_PRF(unsigned char *secret, int secret_len, const char *label, unsigned char *seed, int seed_len, unsigned char *output, int output_len) { const EVP_MD *md = EVP_sha256(); // 使用 SHA-256 哈希函数 HMAC_CTX ctx; HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, secret, secret_len, md, NULL); HMAC_Update(&ctx, (unsigned char *)label, strlen(label)); HMAC_Update(&ctx, seed, seed_len); HMAC_Final(&ctx, output, &output_len); HMAC_CTX_cleanup(&ctx); } ``` 在这个示例,我们使用OpenSSL 的 EVP_sha256() 函数来获取 SHA-256 哈希函数实现,然后使用 HMAC_Init_ex() 函数初始化 HMAC 上下文,HMAC_Update() 函数更新 HMAC 上下文的输入数据,HMAC_Final() 函数计算输出值,并且使用 HMAC_CTX_cleanup() 函数清除 HMAC 上下文。 调用示例: ```c int main() { unsigned char secret[] = "mysecret"; const char *label = "mylabel"; unsigned char seed[] = {0x01, 0x02, 0x03}; unsigned char output[32]; // 输出长度为 32 字节 calculate_PRF(secret, strlen(secret), label, seed, sizeof(seed), output, sizeof(output)); // 输出 PRF 值 for (int i = 0; i < sizeof(output); i++) { printf("%02x", output[i]); } printf("\n"); return 0; } ``` 在这个示例,我们使用了一个长度为 9 字节的密钥(即 secret 数组),一个字符串标签(即 label 变量),一个长度为 3 字节的种子(即 seed 数组),并且计算一个长度为 32 字节的 PRF 值,这个 PRF 值将被存储在 output 数组。最后,我们使用一个循环来打印输出值的每个字节。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值