neobytes/src/key.h

219 lines
6.2 KiB
C
Raw Normal View History

2010-07-14 17:54:31 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2012-02-07 17:28:30 +01:00
// Copyright (c) 2009-2012 The Bitcoin developers
2010-07-14 17:54:31 +02:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEY_H
#define BITCOIN_KEY_H
2010-07-14 17:54:31 +02:00
2011-06-26 16:11:56 +02:00
#include <stdexcept>
#include <vector>
2012-04-17 20:37:47 +02:00
#include "allocators.h"
2012-05-14 19:07:52 +02:00
#include "serialize.h"
2011-06-26 16:11:56 +02:00
#include "uint256.h"
2012-12-18 20:56:21 +01:00
#include "hash.h"
2011-06-26 16:11:56 +02:00
#include <openssl/ec.h> // for EC_KEY definition
2010-07-14 17:54:31 +02:00
// secp160k1
// const unsigned int PRIVATE_KEY_SIZE = 192;
// const unsigned int PUBLIC_KEY_SIZE = 41;
// const unsigned int SIGNATURE_SIZE = 48;
//
// secp192k1
// const unsigned int PRIVATE_KEY_SIZE = 222;
// const unsigned int PUBLIC_KEY_SIZE = 49;
// const unsigned int SIGNATURE_SIZE = 57;
//
// secp224k1
// const unsigned int PRIVATE_KEY_SIZE = 250;
// const unsigned int PUBLIC_KEY_SIZE = 57;
// const unsigned int SIGNATURE_SIZE = 66;
//
// secp256k1:
// const unsigned int PRIVATE_KEY_SIZE = 279;
// const unsigned int PUBLIC_KEY_SIZE = 65;
// const unsigned int SIGNATURE_SIZE = 72;
//
// see www.keylength.com
// script supports up to 75 for single byte push
class key_error : public std::runtime_error
{
public:
explicit key_error(const std::string& str) : std::runtime_error(str) {}
};
/** A reference to a CKey: the Hash160 of its serialized public key */
class CKeyID : public uint160
{
public:
CKeyID() : uint160(0) { }
CKeyID(const uint160 &in) : uint160(in) { }
};
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
class CScriptID : public uint160
{
public:
CScriptID() : uint160(0) { }
CScriptID(const uint160 &in) : uint160(in) { }
};
/** An encapsulated public key. */
2012-05-14 19:07:52 +02:00
class CPubKey {
private:
2013-04-30 21:56:04 +02:00
unsigned char vch[65];
unsigned int static GetLen(unsigned char chHeader) {
if (chHeader == 2 || chHeader == 3)
return 33;
if (chHeader == 4 || chHeader == 6 || chHeader == 7)
return 65;
return 0;
}
unsigned char *begin() {
return vch;
}
2012-05-14 19:07:52 +02:00
friend class CKey;
public:
2013-04-30 21:56:04 +02:00
CPubKey() { vch[0] = 0xFF; }
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) {
int len = vchPubKeyIn.empty() ? 0 : GetLen(vchPubKeyIn[0]);
if (len) {
memcpy(vch, &vchPubKeyIn[0], len);
} else {
vch[0] = 0xFF;
}
}
unsigned int size() const {
return GetLen(vch[0]);
}
const unsigned char *begin() const {
return vch;
}
2012-05-14 19:07:52 +02:00
2013-04-30 21:56:04 +02:00
const unsigned char *end() const {
return vch+size();
}
friend bool operator==(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) == 0; }
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return memcmp(a.vch, b.vch, a.size()) != 0; }
friend bool operator<(const CPubKey &a, const CPubKey &b) {
return a.vch[0] < b.vch[0] ||
(a.vch[0] == b.vch[0] && memcmp(a.vch+1, b.vch+1, a.size() - 1) < 0);
}
unsigned int GetSerializeSize(int nType, int nVersion) const {
return size() + 1;
}
template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const {
unsigned int len = size();
::Serialize(s, VARINT(len), nType, nVersion);
s.write((char*)vch, len);
}
template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) {
unsigned int len;
::Unserialize(s, VARINT(len), nType, nVersion);
if (len <= 65) {
s.read((char*)vch, len);
} else {
// invalid pubkey
vch[0] = 0xFF;
char dummy;
while (len--)
s.read(&dummy, 1);
}
}
2012-05-14 19:07:52 +02:00
CKeyID GetID() const {
2013-04-30 21:56:04 +02:00
return CKeyID(Hash160(vch, vch+size()));
2012-05-14 19:07:52 +02:00
}
uint256 GetHash() const {
2013-04-30 21:56:04 +02:00
return Hash(vch, vch+size());
2012-05-14 19:07:52 +02:00
}
bool IsValid() const {
2013-04-30 21:56:04 +02:00
return size() > 0;
2012-05-14 19:07:52 +02:00
}
bool IsCompressed() const {
2013-04-30 21:56:04 +02:00
return size() == 33;
}
2012-05-14 19:07:52 +02:00
std::vector<unsigned char> Raw() const {
2013-04-30 21:56:04 +02:00
return std::vector<unsigned char>(vch, vch+size());
2012-05-14 19:07:52 +02:00
}
};
2010-07-14 17:54:31 +02:00
// secure_allocator is defined in allocators.h
2011-11-07 00:05:42 +01:00
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
2011-11-07 00:05:42 +01:00
// CSecret is a serialization of just the secret parameter (32 bytes)
2011-06-25 14:57:32 +02:00
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
2010-07-14 17:54:31 +02:00
2012-03-26 16:48:23 +02:00
/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
2010-07-14 17:54:31 +02:00
class CKey
{
protected:
EC_KEY* pkey;
bool fSet;
bool fCompressedPubKey;
2010-07-14 17:54:31 +02:00
public:
void SetCompressedPubKey(bool fCompressed = true);
void Reset();
2010-07-14 17:54:31 +02:00
CKey();
CKey(const CKey& b);
CKey& operator=(const CKey& b);
2010-07-14 17:54:31 +02:00
~CKey();
2010-07-14 17:54:31 +02:00
bool IsNull() const;
bool IsCompressed() const;
2011-06-25 14:57:32 +02:00
void MakeNewKey(bool fCompressed);
bool SetPrivKey(const CPrivKey& vchPrivKey);
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
CSecret GetSecret(bool &fCompressed) const;
CPrivKey GetPrivKey() const;
2012-05-14 19:07:52 +02:00
bool SetPubKey(const CPubKey& vchPubKey);
CPubKey GetPubKey() const;
2011-06-25 14:57:32 +02:00
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
2010-07-14 17:54:31 +02:00
// create a compact signature (65 bytes), which allows reconstructing the used public key
2011-11-07 00:05:42 +01:00
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
// 0x1D = second key with even y, 0x1E = second key with odd y
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
// reconstruct public key from a compact signature
2011-11-07 00:05:42 +01:00
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
2011-11-07 00:05:42 +01:00
// Verify a compact signature
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
2012-01-26 19:26:34 +01:00
bool IsValid();
2010-07-14 17:54:31 +02:00
};
#endif