41 const uint8_t *privkey,
size_t privkeylen) {
42 const uint8_t *end = privkey + privkeylen;
45 if (end - privkey < 1 || *privkey != 0x30u) {
50 if (end - privkey < 1 || !(*privkey & 0x80u)) {
53 ptrdiff_t lenb = *privkey & ~0x80u;
55 if (lenb < 1 || lenb > 2) {
58 if (end - privkey < lenb) {
63 privkey[lenb - 1] | (lenb > 1 ? privkey[lenb - 2] << 8 : 0u);
65 if (end - privkey < len) {
69 if (end - privkey < 3 || privkey[0] != 0x02u || privkey[1] != 0x01u ||
70 privkey[2] != 0x01u) {
75 if (end - privkey < 2 || privkey[0] != 0x04u) {
78 ptrdiff_t oslen = privkey[1];
80 if (oslen > 32 || end - privkey < oslen) {
83 memcpy(out32 + (32 - oslen), privkey, oslen);
102 size_t *privkeylen,
const uint8_t *key32,
106 size_t pubkeylen = 0;
113 static const uint8_t begin[] = {0x30, 0x81, 0xD3, 0x02,
114 0x01, 0x01, 0x04, 0x20};
115 static const uint8_t middle[] = {
116 0xA0, 0x81, 0x85, 0x30, 0x81, 0x82, 0x02, 0x01, 0x01, 0x30, 0x2C,
117 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21,
118 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
121 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x21, 0x02,
122 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62,
123 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE,
124 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02,
125 0x21, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6,
127 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
128 0x41, 0x02, 0x01, 0x01, 0xA1, 0x24, 0x03, 0x22, 0x00};
129 uint8_t *ptr = privkey;
130 memcpy(ptr, begin,
sizeof(begin));
131 ptr +=
sizeof(begin);
132 memcpy(ptr, key32, 32);
134 memcpy(ptr, middle,
sizeof(middle));
135 ptr +=
sizeof(middle);
140 *privkeylen = ptr - privkey;
143 static const uint8_t begin[] = {0x30, 0x82, 0x01, 0x13, 0x02,
144 0x01, 0x01, 0x04, 0x20};
145 static const uint8_t middle[] = {
146 0xA0, 0x81, 0xA5, 0x30, 0x81, 0xA2, 0x02, 0x01, 0x01, 0x30, 0x2C,
147 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21,
148 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
149 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
150 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
151 0x30, 0x06, 0x04, 0x01, 0x00, 0x04, 0x01, 0x07, 0x04, 0x41, 0x04,
152 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62,
153 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE,
154 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x48,
155 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC,
156 0x0E, 0x11, 0x08, 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54,
157 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8, 0x02, 0x21,
158 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF,
160 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
161 0x02, 0x01, 0x01, 0xA1, 0x44, 0x03, 0x42, 0x00};
162 uint8_t *ptr = privkey;
163 memcpy(ptr, begin,
sizeof(begin));
164 ptr +=
sizeof(begin);
165 memcpy(ptr, key32, 32);
167 memcpy(ptr, middle,
sizeof(middle));
168 ptr +=
sizeof(middle);
173 *privkeylen = ptr - privkey;
201 privkey.resize(
SIZE);
206 privkey.resize(privkeylen);
219 secp256k1_context_sign, (uint8_t *)result.
begin(), &clen, &pubkey,
221 assert(result.
size() == clen);
228 uint8_t compact_sig[64];
239 return compact_sig[0] < 0x80;
243 bool grind, uint32_t test_case)
const {
249 uint8_t extra_entropy[32] = {0};
252 uint32_t counter = 0;
256 (!grind && test_case) ? extra_entropy :
nullptr);
267 vchSig.data(), &nSigLen, &
sig);
268 vchSig.resize(nSigLen);
273 uint32_t test_case) {
278 uint8_t extra_entropy[32] = {0};
282 secp256k1_context_sign, buf, hash.
begin(), key.
begin(),
289 std::array<uint8_t, CPubKey::SCHNORR_SIZE> &
sig,
290 uint32_t test_case)
const {
295 uint32_t test_case)
const {
308 std::string str =
"Bitcoin key verification\n";
312 .
Write((uint8_t *)str.data(), str.size())
313 .Write(rnd,
sizeof(rnd))
314 .Finalize(hash.
begin());
315 std::vector<uint8_t> vchSig;
321 std::vector<uint8_t> &vchSig)
const {
329 secp256k1_context_sign, &sig, hash.
begin(),
begin(),
333 secp256k1_context_sign, &vchSig[1], &rec, &sig);
341 bool fSkipCheck =
false) {
343 privkey.data(), privkey.size())) {
360 std::vector<uint8_t, secure_allocator<uint8_t>> vout(64);
361 if ((nChild >> 31) == 0) {
366 assert(
size() == 32);
369 memcpy(ccChild.
begin(), vout.data() + 32, 32);
370 memcpy((uint8_t *)keyChild.
begin(),
begin(), 32);
372 secp256k1_context_sign, (uint8_t *)keyChild.
begin(), vout.data());
380 CKeyID id = key.GetPubKey().GetID();
383 return key.Derive(out.
key, out.
chaincode, _nChild, chaincode);
387 static const uint8_t hashkey[] = {
'B',
'i',
't',
'c',
'o',
'i',
388 'n',
' ',
's',
'e',
'e',
'd'};
389 std::vector<uint8_t, secure_allocator<uint8_t>> vout(64);
391 .
Write(seed, nSeedLen)
393 key.Set(vout.data(), vout.data() + 32,
true);
394 memcpy(chaincode.begin(), vout.data() + 32, 32);
397 memset(vchFingerprint, 0,
sizeof(vchFingerprint));
405 ret.
pubkey = key.GetPubKey();
412 memcpy(code + 1, vchFingerprint, 4);
413 code[5] = (nChild >> 24) & 0xFF;
414 code[6] = (nChild >> 16) & 0xFF;
415 code[7] = (nChild >> 8) & 0xFF;
416 code[8] = (nChild >> 0) & 0xFF;
417 memcpy(code + 9, chaincode.begin(), 32);
419 assert(key.size() == 32);
420 memcpy(code + 42, key.begin(), 32);
425 memcpy(vchFingerprint, code + 1, 4);
426 nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
427 memcpy(chaincode.begin(), code + 9, 32);
428 key.Set(code + 42, code + BIP32_EXTKEY_SIZE,
true);
439 assert(secp256k1_context_sign ==
nullptr);
442 assert(ctx !=
nullptr);
446 std::vector<uint8_t, secure_allocator<uint8_t>> vseed(32);
452 secp256k1_context_sign =
ctx;
457 secp256k1_context_sign =
nullptr;
std::vector< uint8_t, secure_allocator< uint8_t > > keydata
The actual byte data.
void ECC_Start()
Initialize the elliptic curve support.
bool SignECDSA(const uint256 &hash, std::vector< uint8_t > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized ECDSA signature.
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
std::array< uint8_t, 64 > sig
static constexpr unsigned int SIZE
secp256k1:
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context *ctx, unsigned char *output64, const secp256k1_ecdsa_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize an ECDSA signature in compact (64 byte) format.
static int ec_privkey_import_der(const secp256k1_context *ctx, uint8_t *out32, const uint8_t *privkey, size_t privkeylen)
These functions are taken from the libsecp256k1 distribution and are very ugly.
static void WriteLE32(uint8_t *ptr, uint32_t x)
SECP256K1_API int secp256k1_schnorr_sign(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a signature using a custom EC-Schnorr-SHA256 construction.
bool Negate()
Negate private key.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(secp256k1_context *ctx, const unsigned char *seed32) SECP256K1_ARG_NONNULL(1)
Updates the context randomization to protect against side-channel leakage.
bool Derive(CExtKey &out, unsigned int nChild) const
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
CPubKey GetPubKey() const
Compute the public key from a private key.
Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery.
bool VerifyECDSA(const uint256 &hash, const std::vector< uint8_t > &vchSig) const
Verify a DER-serialized ECDSA signature (~72 bytes).
void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
static const unsigned int SIZE
secp256k1:
#define SECP256K1_CONTEXT_SIGN
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(const secp256k1_context *ctx, unsigned char *seckey, const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED.
bool fValid
see www.keylength.com script supports up to 75 for single byte push
const uint8_t * begin() const
std::vector< uint8_t, secure_allocator< uint8_t > > CPrivKey
secure_allocator is defined in allocators.h CPrivKey is a serialized private key, with all parameters...
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(const secp256k1_context *ctx, unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Same as secp256k1_ec_seckey_negate, but DEPRECATED.
SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979
An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
void GetRandBytes(uint8_t *buf, int num) noexcept
Overall design of the RNG and entropy sources.
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object (created in dynamically allocated memory).
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
#define SECP256K1_EC_UNCOMPRESSED
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
static const unsigned int COMPRESSED_SIZE
static constexpr unsigned int COMPRESSED_SIZE
void BIP32Hash(const ChainCode &chainCode, uint32_t nChild, uint8_t header, const uint8_t data[32], uint8_t output[64])
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Verify an ECDSA secret key.
void SetSeed(const uint8_t *seed, unsigned int nSeedLen)
static bool DoSignSchnorr(const CKey &key, const uint256 &hash, uint8_t *buf, uint32_t test_case)
void ECC_Stop()
Deinitialize the elliptic curve support.
SECP256K1_API int secp256k1_ecdsa_sign(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create an ECDSA signature.
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a recoverable ECDSA signature.
An encapsulated public key.
static bool Check(const uint8_t *vch)
Check whether the 32-byte array pointed to by vch is valid keydata.
static int ec_privkey_export_der(const secp256k1_context *ctx, uint8_t *privkey, size_t *privkeylen, const uint8_t *key32, bool compressed)
This serializes to a DER encoding of the ECPrivateKey type from section C.4 of SEC 1 http://www...
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
uint8_t vchFingerprint[4]
bool SignCompact(const uint256 &hash, std::vector< uint8_t > &vchSig) const
Create a compact ECDSA signature (65 bytes), which allows reconstructing the used public key...
static constexpr unsigned int SCHNORR_SIZE
unsigned int size() const
Simple read-only vector-like interface.
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Opaque data structured that holds a parsed ECDSA signature.
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context *ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize an ECDSA signature in compact format (64 bytes + recovery id).
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
const uint8_t * begin() const
uint8_t vchFingerprint[4]
static secp256k1_context * secp256k1_context_sign
CHash256 & Write(const uint8_t *data, size_t len)
void GetStrongRandBytes(uint8_t *buf, int num) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize an ECDSA signature in DER format.
CExtPubKey Neuter() const
bool Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child key.
const unsigned int BIP32_EXTKEY_SIZE
A reference to a CKey: the Hash160 of its serialized public key.
bool fCompressed
Whether the public key corresponding to this private key is (to be) compressed.
void Decode(const uint8_t code[BIP32_EXTKEY_SIZE])
An encapsulated secp256k1 private key.
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
bool SignSchnorr(const uint256 &hash, std::array< uint8_t, CPubKey::SCHNORR_SIZE > &sig, uint32_t test_case=0) const
Create a Schnorr signature.
static constexpr unsigned int SIGNATURE_SIZE
void Finalize(uint8_t hash[OUTPUT_SIZE])
static bool SigHasLowR(const secp256k1_ecdsa_signature *sig)
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
bool IsValid() const
Check whether this private key is valid.
Opaque data structure that holds a parsed and valid public key.
CHMAC_SHA512 & Write(const uint8_t *data, size_t len)
bool IsCompressed() const
Check whether this is a compressed public key.
A hasher class for HMAC-SHA-512.