gpt4 book ai didi

c++ - 从 ECDSA 公钥生成比特币地址

转载 作者:可可西里 更新时间:2023-11-01 16:35:41 34 4
gpt4 key购买 nike

我正在使用 OpenSSL 在 C++ 中编写简单代码以生成有效的比特币地址 - 私钥对。

我正在使用此代码段从给定的十六进制形式私钥生成公钥:

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>

int main()
{
EC_KEY *eckey = NULL;
EC_POINT *pub_key = NULL;
const EC_GROUP *group = NULL;
BIGNUM start;
BIGNUM *res;
BN_CTX *ctx;



BN_init(&start);
ctx = BN_CTX_new(); // ctx is an optional buffer to save time from allocating and deallocating memory whenever required

res = &start;
BN_hex2bn(&res,"30caae2fcb7c34ecadfddc45e0a27e9103bd7cfc87730d7818cc096b1266a683");
eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);

EC_KEY_set_private_key(eckey, res);

/* pub_key is a new uninitialized `EC_POINT*`. priv_key res is a `BIGNUM*`. */
if (!EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx))
printf("Error at EC_POINT_mul.\n");

EC_KEY_set_public_key(eckey, pub_key);

char *cc = EC_POINT_point2hex(group, pub_key, 4, ctx);

char *c=cc;

int i;

for (i=0; i<130; i++) // 1 byte 0x42, 32 bytes for X coordinate, 32 bytes for Y coordinate
{
printf("%c", *c++);
}

printf("\n");

BN_CTX_free(ctx);

free(cc);

return 0;
}

我想要的是将这个公钥转换为比特币地址 - 最快的实现方式是什么?我不知道如何从 OpenSSL 的 BIGNUM 创建 RIPEMD160。或者也许还有其他更好的解决方案?

最佳答案

假设您所做的是基于此转化:

enter image description here

我将用伪代码描述您可以做什么:

首先从公钥中提取x,y。

// get x and y from Public key "point"
EC_POINT_get_affine_coordinates_GFp(group, pub_key, x, y, ctx);
// convert BIGNUMs x, y into binary form
BN_bn2bin(x,x_char);
BN_bn2bin(y,y_char);

接下来需要做几次message digest,包括3次sha256和1次ripemd160。在下面的伪代码中,我将向您展示如何使用 ripemd160。要使用 EVP_MD 执行 sha256,只需将 EVP_ripemd160() 替换为 EVP_sha256(),并使用单个或多个 EVP_DigestUpdate() 更新(输入到 EVP_MD)您的输入消息

EVP_MD_CTX ctx;
EVP_MD_CTX_init(&md_ctx);
EVP_DigestInit(&md_ctx, EVP_ripemd160());
// hdr = 0x04
EVP_DigestUpdate(&md_ctx,hdr,1);
EVP_DigestUpdate(&md_ctx,x_char,32);
EVP_DigestUpdate(&md_ctx,y_char,32);
// put message degest into dgst and set length to dgstlen
EVP_DigestFinal(&md_ctx,dgst,&dgstlen);
EVP_MD_CTX_cleanup(&md_ctx);

或者更简单的方法,直接调用 sha256()ripemd160()。但是您需要在调用散列函数 sha256()ripemd160() 之前准备您的输入消息。

25 字节的二进制地址是 ripemd160 的结果,连同 32 字节校验和的前 4 个字节。您需要找到一种方法将其从 Base 256 转换为 Base 58。我认为 OpenSSL 不支持这种方式。

关于c++ - 从 ECDSA 公钥生成比特币地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17672696/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com