#include <iostream>
#include <secp256k1.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <assert.h>
#include <openssl/sha.h>
//十六进制字符串转字符串, 如 "313233" -> "123"
std::string hex2string(const std::string &strHex);
//字符串转二进制字符串, 如 "123" -> "313233"
std::string string2hex(const std::uint8_t *data, int len);
int main()
{
secp256k1_context *ctx = nullptr;
secp256k1_pubkey pubkey;
//随机一个256位的私钥
std::uint8_t private_key[] = "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725";
int pk_size = std::extent<decltype(private_key)>::value;
std::cout << "private key : " << private_key << "|" << pk_size << std::endl;
//创建一个上下文
assert(ctx == nullptr);
ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY|SECP256K1_CONTEXT_SIGN);
assert(ctx != nullptr);
//二进制私钥
std::string prikey = hex2string((const char *)private_key);
//根据私钥生成公钥
secp256k1_ec_pubkey_create(ctx, &pubkey, (unsigned char *)prikey.c_str());
unsigned char pub[65];
size_t publen = 65;
//将公钥转为64字节的公钥, 不是可读字符串, 需要string2hex()转换
secp256k1_ec_pubkey_serialize(ctx, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
std::cout << "pub: " << string2hex((unsigned char *)pub, 65) << std::endl;
//签名
unsigned char hash[33] = { 0 };
//对一个字符串进行hash, 签名就是对32字节的hash进行签名的
SHA256((const unsigned char *)"123", 3, hash);
std::cout << string2hex(hash, 32) << std::endl;
secp256k1_ecdsa_signature sig;
int ret = secp256k1_ecdsa_sign(ctx, &sig, hash, (const unsigned char *)prikey.c_str(), NULL, NULL);
assert(ret == 1);
//转为der格式, 这里用不到, len要足够大能放下der结果
//unsigned char der[200];
//size_t derlen = 200;
//ret = secp256k1_ecdsa_signature_serialize_der(ctx,
// der, &derlen, &sig);
//assert(ret == 1);
//将签名转为64字节的签名格式
unsigned char sig64[65] = { 0 };
secp256k1_ecdsa_signature_serialize_compact(ctx,
sig64, &sig);
std::cout << "sig64 : " << string2hex(sig64, 64) << std::endl;
//std::cout << "der : " << string2hex(der, derlen) << std::endl;
//验证签名, 返回值为1, 则验证通过
ret = secp256k1_ecdsa_verify(ctx, &sig, hash, &pubkey);
assert(ret == 1);
return 0;
}
std::string hex2string(const std::string &strHex)
{
if (strHex.size() % 2 != 0)
{
return "";
}
std::string strBin;
strBin.resize(strHex.size() / 2);
for (size_t i = 0; i < strBin.size(); i++)
{
uint8_t cTemp = 0;
for (size_t j = 0; j < 2; j++)
{
char cCur = strHex[2 * i + j];
if (cCur >= '0' && cCur <= '9')
{
cTemp = (cTemp << 4) + (cCur - '0');
}
else if (cCur >= 'a' && cCur <= 'f')
{
cTemp = (cTemp << 4) + (cCur - 'a' + 10);
}
else if (cCur >= 'A' && cCur <= 'F')
{
cTemp = (cTemp << 4) + (cCur - 'A' + 10);
}
else
{
return "";
}
}
strBin[i] = cTemp;
}
return strBin;
}
std::string string2hex(const std::uint8_t *data, int len)
{
std::string result;
std::string tmp;
std::stringstream ss;
for (int i = 0; i < len; i++)
{
int r = int(data[i]);
ss << std::hex << std::setw(2)
<< std::setfill('0') << r << std::endl;
ss >> tmp;
result += tmp;
}
return result;
}
SECP256K1签名
猜你喜欢
转载自blog.csdn.net/huang714/article/details/104749025
今日推荐
周排行