Browse Source

Scope the ECDSA constant sizes to CPubKey / CKey classes

0.16
Jack Grigg 7 years ago
parent
commit
63179d0283
No known key found for this signature in database
GPG Key ID: 665DBCD284F7DAFF
  1. 25
      src/key.cpp
  2. 24
      src/key.h
  3. 4
      src/pubkey.cpp
  4. 31
      src/pubkey.h

25
src/key.cpp

@ -85,16 +85,13 @@ static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *ou
* <http://www.secg.org/sec1-v2.pdf>. The optional parameters and publicKey fields are * <http://www.secg.org/sec1-v2.pdf>. The optional parameters and publicKey fields are
* included. * included.
* *
* privkey must point to an output buffer of length at least PRIVATE_KEY_SIZE bytes. * 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 the privkey buffer. Upon return it * 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 buffer. * will be set to the number of bytes used in the buffer.
* key32 must point to a 32-byte raw private key. * key32 must point to a 32-byte raw private key.
*/ */
static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
assert(*privkeylen >= PRIVATE_KEY_SIZE); assert(*privkeylen >= CKey::PRIVATE_KEY_SIZE);
static_assert(
PRIVATE_KEY_SIZE >= COMPRESSED_PRIVATE_KEY_SIZE,
"COMPRESSED_PRIVATE_KEY_SIZE is larger than PRIVATE_KEY_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)) {
@ -120,11 +117,11 @@ static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *pr
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
memcpy(ptr, key32, 32); ptr += 32; memcpy(ptr, key32, 32); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
pubkeylen = COMPRESSED_PUBLIC_KEY_SIZE; pubkeylen = CPubKey::COMPRESSED_PUBLIC_KEY_SIZE;
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
ptr += pubkeylen; ptr += pubkeylen;
*privkeylen = ptr - privkey; *privkeylen = ptr - privkey;
assert(*privkeylen == COMPRESSED_PRIVATE_KEY_SIZE); assert(*privkeylen == CKey::COMPRESSED_PRIVATE_KEY_SIZE);
} else { } else {
static const unsigned char begin[] = { static const unsigned char begin[] = {
0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
@ -146,11 +143,11 @@ static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *pr
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
memcpy(ptr, key32, 32); ptr += 32; memcpy(ptr, key32, 32); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
pubkeylen = PUBLIC_KEY_SIZE; pubkeylen = CPubKey::PUBLIC_KEY_SIZE;
secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
ptr += pubkeylen; ptr += pubkeylen;
*privkeylen = ptr - privkey; *privkeylen = ptr - privkey;
assert(*privkeylen == PRIVATE_KEY_SIZE); assert(*privkeylen == CKey::PRIVATE_KEY_SIZE);
} }
return 1; return 1;
} }
@ -183,7 +180,7 @@ CPrivKey CKey::GetPrivKey() const {
CPubKey CKey::GetPubKey() const { CPubKey CKey::GetPubKey() const {
assert(fValid); assert(fValid);
secp256k1_pubkey pubkey; secp256k1_pubkey pubkey;
size_t clen = PUBLIC_KEY_SIZE; size_t clen = CPubKey::PUBLIC_KEY_SIZE;
CPubKey result; CPubKey result;
int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin()); int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin());
assert(ret); assert(ret);
@ -196,8 +193,8 @@ CPubKey CKey::GetPubKey() const {
bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const { bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const {
if (!fValid) if (!fValid)
return false; return false;
vchSig.resize(SIGNATURE_SIZE); vchSig.resize(CPubKey::SIGNATURE_SIZE);
size_t nSigLen = SIGNATURE_SIZE; size_t nSigLen = CPubKey::SIGNATURE_SIZE;
unsigned char extra_entropy[32] = {0}; unsigned char extra_entropy[32] = {0};
WriteLE32(extra_entropy, test_case); WriteLE32(extra_entropy, test_case);
secp256k1_ecdsa_signature sig; secp256k1_ecdsa_signature sig;
@ -225,7 +222,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
if (!fValid) if (!fValid)
return false; return false;
vchSig.resize(COMPACT_SIGNATURE_SIZE); vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE);
int rec = -1; int rec = -1;
secp256k1_ecdsa_recoverable_signature sig; secp256k1_ecdsa_recoverable_signature sig;
int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL); int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL);
@ -255,7 +252,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
std::vector<unsigned char, secure_allocator<unsigned char>> vout(64); std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
if ((nChild >> 31) == 0) { if ((nChild >> 31) == 0) {
CPubKey pubkey = GetPubKey(); CPubKey pubkey = GetPubKey();
assert(pubkey.size() == COMPRESSED_PUBLIC_KEY_SIZE); assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_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);

24
src/key.h

@ -16,16 +16,6 @@
#include <vector> #include <vector>
/**
* secp256k1:
*/
const unsigned int PRIVATE_KEY_SIZE = 279;
const unsigned int COMPRESSED_PRIVATE_KEY_SIZE = 214;
/**
* see www.keylength.com
* script supports up to 75 for single byte push
*/
/** /**
* secure_allocator is defined in allocators.h * secure_allocator is defined in allocators.h
* CPrivKey is a serialized private key, with all parameters included * CPrivKey is a serialized private key, with all parameters included
@ -36,6 +26,20 @@ typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
/** An encapsulated private key. */ /** An encapsulated private key. */
class CKey class CKey
{ {
public:
/**
* secp256k1:
*/
static const unsigned int PRIVATE_KEY_SIZE = 279;
static const unsigned int COMPRESSED_PRIVATE_KEY_SIZE = 214;
/**
* see www.keylength.com
* script supports up to 75 for single byte push
*/
static_assert(
PRIVATE_KEY_SIZE >= COMPRESSED_PRIVATE_KEY_SIZE,
"COMPRESSED_PRIVATE_KEY_SIZE is larger than PRIVATE_KEY_SIZE");
private: private:
//! Whether this private key is valid. We check for correctness when modifying the key //! Whether this private key is valid. We check for correctness when modifying the key
//! data, so fValid should always correspond to the actual state. //! data, so fValid should always correspond to the actual state.

4
src/pubkey.cpp

@ -252,8 +252,8 @@ void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF; code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
memcpy(code+9, chaincode.begin(), 32); memcpy(code+9, chaincode.begin(), 32);
assert(pubkey.size() == COMPRESSED_PUBLIC_KEY_SIZE); assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
memcpy(code+41, pubkey.begin(), COMPRESSED_PUBLIC_KEY_SIZE); memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
} }
void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) { void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {

31
src/pubkey.h

@ -14,18 +14,6 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
/**
* secp256k1:
*/
const unsigned int PUBLIC_KEY_SIZE = 65;
const unsigned int COMPRESSED_PUBLIC_KEY_SIZE = 33;
const unsigned int SIGNATURE_SIZE = 72;
const unsigned int COMPACT_SIGNATURE_SIZE = 65;
/**
* see www.keylength.com
* script supports up to 75 for single byte push
*/
const unsigned int BIP32_EXTKEY_SIZE = 74; const unsigned int BIP32_EXTKEY_SIZE = 74;
/** A reference to a CKey: the Hash160 of its serialized public key */ /** A reference to a CKey: the Hash160 of its serialized public key */
@ -41,6 +29,22 @@ typedef uint256 ChainCode;
/** An encapsulated public key. */ /** An encapsulated public key. */
class CPubKey class CPubKey
{ {
public:
/**
* secp256k1:
*/
static const unsigned int PUBLIC_KEY_SIZE = 65;
static const unsigned int COMPRESSED_PUBLIC_KEY_SIZE = 33;
static const unsigned int SIGNATURE_SIZE = 72;
static const unsigned int COMPACT_SIGNATURE_SIZE = 65;
/**
* see www.keylength.com
* script supports up to 75 for single byte push
*/
static_assert(
PUBLIC_KEY_SIZE >= COMPRESSED_PUBLIC_KEY_SIZE,
"COMPRESSED_PUBLIC_KEY_SIZE is larger than PUBLIC_KEY_SIZE");
private: private:
/** /**
@ -48,9 +52,6 @@ private:
* Its length can very cheaply be computed from the first byte. * Its length can very cheaply be computed from the first byte.
*/ */
unsigned char vch[PUBLIC_KEY_SIZE]; unsigned char vch[PUBLIC_KEY_SIZE];
static_assert(
PUBLIC_KEY_SIZE >= COMPRESSED_PUBLIC_KEY_SIZE,
"COMPRESSED_PUBLIC_KEY_SIZE is larger than PUBLIC_KEY_SIZE");
//! Compute the length of a pubkey with a given first byte. //! Compute the length of a pubkey with a given first byte.
unsigned int static GetLen(unsigned char chHeader) unsigned int static GetLen(unsigned char chHeader)

Loading…
Cancel
Save