Changeset View
Changeset View
Standalone View
Standalone View
src/key.cpp
Show First 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/** | /** | ||||
* This serializes to a DER encoding of the ECPrivateKey type from section C.4 | * This serializes to a DER encoding of the ECPrivateKey type from section C.4 | ||||
* of SEC 1 <http://www.secg.org/sec1-v2.pdf>. The optional parameters and | * of SEC 1 <http://www.secg.org/sec1-v2.pdf>. The optional parameters and | ||||
* publicKey fields are included. | * publicKey fields are included. | ||||
* | * | ||||
* privkey must point to an output buffer of length at least | * privkey must point to an output buffer of length at least | ||||
* CKey::PRIVATE_KEY_SIZE bytes. privkeylen must initially be set to the size of | * CKey::SIZE bytes. privkeylen must initially be set to the size of | ||||
* the privkey buffer. Upon return it will be set to the number of bytes used in | * the privkey buffer. Upon return it will be set to the number of bytes used in | ||||
* the buffer. key32 must point to a 32-byte raw private key. | * the buffer. key32 must point to a 32-byte raw private key. | ||||
*/ | */ | ||||
static int ec_privkey_export_der(const secp256k1_context *ctx, uint8_t *privkey, | static int ec_privkey_export_der(const secp256k1_context *ctx, uint8_t *privkey, | ||||
size_t *privkeylen, const uint8_t *key32, | size_t *privkeylen, const uint8_t *key32, | ||||
int compressed) { | int compressed) { | ||||
assert(*privkeylen >= CKey::PRIVATE_KEY_SIZE); | assert(*privkeylen >= CKey::SIZE); | ||||
secp256k1_pubkey pubkey; | secp256k1_pubkey pubkey; | ||||
size_t pubkeylen = 0; | size_t pubkeylen = 0; | ||||
if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { | if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { | ||||
*privkeylen = 0; | *privkeylen = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
if (compressed) { | if (compressed) { | ||||
Show All 15 Lines | if (compressed) { | ||||
0x41, 0x02, 0x01, 0x01, 0xA1, 0x24, 0x03, 0x22, 0x00}; | 0x41, 0x02, 0x01, 0x01, 0xA1, 0x24, 0x03, 0x22, 0x00}; | ||||
uint8_t *ptr = privkey; | uint8_t *ptr = privkey; | ||||
memcpy(ptr, begin, sizeof(begin)); | memcpy(ptr, begin, sizeof(begin)); | ||||
ptr += sizeof(begin); | ptr += sizeof(begin); | ||||
memcpy(ptr, key32, 32); | memcpy(ptr, key32, 32); | ||||
ptr += 32; | ptr += 32; | ||||
memcpy(ptr, middle, sizeof(middle)); | memcpy(ptr, middle, sizeof(middle)); | ||||
ptr += sizeof(middle); | ptr += sizeof(middle); | ||||
pubkeylen = CPubKey::COMPRESSED_PUBLIC_KEY_SIZE; | pubkeylen = CPubKey::COMPRESSED_SIZE; | ||||
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, | ||||
SECP256K1_EC_COMPRESSED); | SECP256K1_EC_COMPRESSED); | ||||
ptr += pubkeylen; | ptr += pubkeylen; | ||||
*privkeylen = ptr - privkey; | *privkeylen = ptr - privkey; | ||||
assert(*privkeylen == CKey::COMPRESSED_PRIVATE_KEY_SIZE); | assert(*privkeylen == CKey::COMPRESSED_SIZE); | ||||
} else { | } else { | ||||
static const uint8_t begin[] = {0x30, 0x82, 0x01, 0x13, 0x02, | static const uint8_t begin[] = {0x30, 0x82, 0x01, 0x13, 0x02, | ||||
0x01, 0x01, 0x04, 0x20}; | 0x01, 0x01, 0x04, 0x20}; | ||||
static const uint8_t middle[] = { | static const uint8_t middle[] = { | ||||
0xA0, 0x81, 0xA5, 0x30, 0x81, 0xA2, 0x02, 0x01, 0x01, 0x30, 0x2C, | 0xA0, 0x81, 0xA5, 0x30, 0x81, 0xA2, 0x02, 0x01, 0x01, 0x30, 0x2C, | ||||
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21, | 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01, 0x02, 0x21, | ||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||||
Show All 11 Lines | if (compressed) { | ||||
0x02, 0x01, 0x01, 0xA1, 0x44, 0x03, 0x42, 0x00}; | 0x02, 0x01, 0x01, 0xA1, 0x44, 0x03, 0x42, 0x00}; | ||||
uint8_t *ptr = privkey; | uint8_t *ptr = privkey; | ||||
memcpy(ptr, begin, sizeof(begin)); | memcpy(ptr, begin, sizeof(begin)); | ||||
ptr += sizeof(begin); | ptr += sizeof(begin); | ||||
memcpy(ptr, key32, 32); | memcpy(ptr, key32, 32); | ||||
ptr += 32; | ptr += 32; | ||||
memcpy(ptr, middle, sizeof(middle)); | memcpy(ptr, middle, sizeof(middle)); | ||||
ptr += sizeof(middle); | ptr += sizeof(middle); | ||||
pubkeylen = CPubKey::PUBLIC_KEY_SIZE; | pubkeylen = CPubKey::SIZE; | ||||
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, | secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, | ||||
SECP256K1_EC_UNCOMPRESSED); | SECP256K1_EC_UNCOMPRESSED); | ||||
ptr += pubkeylen; | ptr += pubkeylen; | ||||
*privkeylen = ptr - privkey; | *privkeylen = ptr - privkey; | ||||
assert(*privkeylen == CKey::PRIVATE_KEY_SIZE); | assert(*privkeylen == CKey::SIZE); | ||||
} | } | ||||
return 1; | return 1; | ||||
} | } | ||||
bool CKey::Check(const uint8_t *vch) { | bool CKey::Check(const uint8_t *vch) { | ||||
return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch); | return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch); | ||||
} | } | ||||
Show All 10 Lines | bool CKey::Negate() { | ||||
return secp256k1_ec_privkey_negate(secp256k1_context_sign, keydata.data()); | return secp256k1_ec_privkey_negate(secp256k1_context_sign, keydata.data()); | ||||
} | } | ||||
CPrivKey CKey::GetPrivKey() const { | CPrivKey CKey::GetPrivKey() const { | ||||
assert(fValid); | assert(fValid); | ||||
CPrivKey privkey; | CPrivKey privkey; | ||||
int ret; | int ret; | ||||
size_t privkeylen; | size_t privkeylen; | ||||
privkey.resize(PRIVATE_KEY_SIZE); | privkey.resize(SIZE); | ||||
privkeylen = PRIVATE_KEY_SIZE; | privkeylen = SIZE; | ||||
ret = ec_privkey_export_der( | ret = ec_privkey_export_der( | ||||
secp256k1_context_sign, privkey.data(), &privkeylen, begin(), | secp256k1_context_sign, privkey.data(), &privkeylen, begin(), | ||||
fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | ||||
assert(ret); | assert(ret); | ||||
privkey.resize(privkeylen); | privkey.resize(privkeylen); | ||||
return privkey; | return privkey; | ||||
} | } | ||||
CPubKey CKey::GetPubKey() const { | CPubKey CKey::GetPubKey() const { | ||||
assert(fValid); | assert(fValid); | ||||
secp256k1_pubkey pubkey; | secp256k1_pubkey pubkey; | ||||
size_t clen = CPubKey::PUBLIC_KEY_SIZE; | size_t clen = CPubKey::SIZE; | ||||
CPubKey result; | CPubKey result; | ||||
int ret = | int ret = | ||||
secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin()); | secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin()); | ||||
assert(ret); | assert(ret); | ||||
secp256k1_ec_pubkey_serialize( | secp256k1_ec_pubkey_serialize( | ||||
secp256k1_context_sign, (uint8_t *)result.begin(), &clen, &pubkey, | secp256k1_context_sign, (uint8_t *)result.begin(), &clen, &pubkey, | ||||
fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); | ||||
assert(result.size() == clen); | assert(result.size() == clen); | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
bool CKey::Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild, | bool CKey::Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild, | ||||
const ChainCode &cc) const { | const ChainCode &cc) const { | ||||
assert(IsValid()); | assert(IsValid()); | ||||
assert(IsCompressed()); | assert(IsCompressed()); | ||||
std::vector<uint8_t, secure_allocator<uint8_t>> vout(64); | std::vector<uint8_t, secure_allocator<uint8_t>> vout(64); | ||||
if ((nChild >> 31) == 0) { | if ((nChild >> 31) == 0) { | ||||
CPubKey pubkey = GetPubKey(); | CPubKey pubkey = GetPubKey(); | ||||
assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE); | assert(pubkey.size() == CPubKey::COMPRESSED_SIZE); | ||||
BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin() + 1, vout.data()); | BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin() + 1, vout.data()); | ||||
} else { | } else { | ||||
assert(size() == 32); | assert(size() == 32); | ||||
BIP32Hash(cc, nChild, 0, begin(), vout.data()); | BIP32Hash(cc, nChild, 0, begin(), vout.data()); | ||||
} | } | ||||
memcpy(ccChild.begin(), vout.data() + 32, 32); | memcpy(ccChild.begin(), vout.data() + 32, 32); | ||||
memcpy((uint8_t *)keyChild.begin(), begin(), 32); | memcpy((uint8_t *)keyChild.begin(), begin(), 32); | ||||
bool ret = secp256k1_ec_privkey_tweak_add( | bool ret = secp256k1_ec_privkey_tweak_add( | ||||
▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines |