mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 22:45:52 +00:00
Enormous cleanup of RippleAddress et. al. into ripple_data
Start cleanup into ripple_data, split out some hash_value() instances Tidy up CBigNum into ripple_data, moving definitions to .cpp Split and clean up base58 stuff Remove unused files from VS2012 project Clean up some bignum stuff and remove unused files Partial cleanup of RFC1751 Enormous cleanup with RippleAddress and related, into ripple_data Remove unused VS project files Move ECIES stuff into CKey
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "SerializedLedger.h"
|
||||
|
||||
class AccountState
|
||||
|
||||
@@ -16,17 +16,6 @@ SETUP_LOG (STAmount)
|
||||
|
||||
uint64 STAmount::uRateOne = STAmount::getRate(STAmount(1), STAmount(1));
|
||||
|
||||
|
||||
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
#define BN_add_word64(bn, word) BN_add_word(bn, word)
|
||||
#define BN_sub_word64(bn, word) BN_sub_word(bn, word)
|
||||
#define BN_mul_word64(bn, word) BN_mul_word(bn, word)
|
||||
#define BN_div_word64(bn, word) BN_div_word(bn, word)
|
||||
#else
|
||||
#include "BigNum64.h"
|
||||
#endif
|
||||
|
||||
bool STAmount::issuerFromString(uint160& uDstIssuer, const std::string& sIssuer)
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
||||
@@ -3,15 +3,6 @@
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
#define BN_add_word64(bn, word) BN_add_word(bn, word)
|
||||
#define BN_sub_word64(bn, word) BN_sub_word(bn, word)
|
||||
#define BN_mul_word64(bn, word) BN_mul_word(bn, word)
|
||||
#define BN_div_word64(bn, word) BN_div_word(bn, word)
|
||||
#else
|
||||
#include "BigNum64.h"
|
||||
#endif
|
||||
|
||||
// CAUTION: This is early code and is *NOT* ready for real use yet.
|
||||
|
||||
static void canonicalizeRound(bool isNative, uint64& value, int& offset, bool roundUp)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "Config.h"
|
||||
#include "PeerDoor.h"
|
||||
#include "RPCDoor.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "key.h"
|
||||
|
||||
#include "../database/SqliteDatabase.h"
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
#ifndef BIGNUM64_H
|
||||
#define BIGNUM64_H
|
||||
|
||||
// Support 64-bit word operations on 32-bit platforms
|
||||
|
||||
static int BN_add_word64(BIGNUM *a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
return BN_add(a, &bn, a);
|
||||
}
|
||||
|
||||
static int BN_sub_word64(BIGNUM *a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
return BN_sub(a, &bn, a);
|
||||
}
|
||||
|
||||
static int BN_mul_word64(BIGNUM *a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
CAutoBN_CTX ctx;
|
||||
return BN_mul(a, &bn, a, ctx);
|
||||
}
|
||||
|
||||
static uint64 BN_div_word64(BIGNUM *a, uint64 w)
|
||||
{
|
||||
CBigNum bn(w);
|
||||
CAutoBN_CTX ctx;
|
||||
return (BN_div(a, NULL, a, &bn, ctx) == 1) ? 0 : ((uint64)-1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,107 +0,0 @@
|
||||
#include "BitcoinUtil.h"
|
||||
#include <cstdarg>
|
||||
#include <openssl/rand.h>
|
||||
#include <ctime>
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::string gFormatStr("v1");
|
||||
|
||||
std::string FormatFullVersion()
|
||||
{
|
||||
return(gFormatStr);
|
||||
}
|
||||
|
||||
|
||||
string strprintf(const char* format, ...)
|
||||
{
|
||||
char buffer[50000];
|
||||
char* p = buffer;
|
||||
int limit = sizeof(buffer);
|
||||
int ret;
|
||||
loop
|
||||
{
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, format);
|
||||
ret = _vsnprintf(p, limit, format, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
if (ret >= 0 && ret < limit)
|
||||
break;
|
||||
if (p != buffer)
|
||||
delete[] p;
|
||||
limit *= 2;
|
||||
p = new char[limit];
|
||||
if (p == NULL)
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
string str(p, p+ret);
|
||||
if (p != buffer)
|
||||
delete[] p;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
inline int64 GetPerformanceCounter()
|
||||
{
|
||||
int64 nCounter = 0;
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
||||
#else
|
||||
timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
nCounter = t.tv_sec * 1000000 + t.tv_usec;
|
||||
#endif
|
||||
return nCounter;
|
||||
}
|
||||
|
||||
void RandAddSeed()
|
||||
{
|
||||
// Seed with CPU performance counter
|
||||
int64 nCounter = GetPerformanceCounter();
|
||||
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
||||
memset(&nCounter, 0, sizeof(nCounter));
|
||||
}
|
||||
//
|
||||
// "Never go to sea with two chronometers; take one or three."
|
||||
// Our three time sources are:
|
||||
// - System clock
|
||||
// - Median of other nodes's clocks
|
||||
// - The user (asking the user to fix the system clock if the first two disagree)
|
||||
//
|
||||
int64 GetTime()
|
||||
{
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
void RandAddSeedPerfmon()
|
||||
{
|
||||
RandAddSeed();
|
||||
|
||||
// This can take up to 2 seconds, so only do it every 10 minutes
|
||||
static int64 nLastPerfmon;
|
||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||
return;
|
||||
nLastPerfmon = GetTime();
|
||||
|
||||
#ifdef WIN32
|
||||
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
|
||||
// Seed with the entire set of perfmon data
|
||||
unsigned char pdata[250000];
|
||||
memset(pdata, 0, sizeof(pdata));
|
||||
unsigned long nSize = sizeof(pdata);
|
||||
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
||||
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
RAND_add(pdata, nSize, nSize/100.0);
|
||||
memset(pdata, 0, nSize);
|
||||
//printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
#ifndef __BITCOIN_UTIL__
|
||||
#define __BITCOIN_UTIL__
|
||||
|
||||
// TODO: these things should all go somewhere
|
||||
|
||||
#include <string>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
std::string strprintf(const char* format, ...);
|
||||
std::string FormatFullVersion();
|
||||
void RandAddSeedPerfmon();
|
||||
|
||||
#define loop for (;;)
|
||||
#define PAIR(t1, t2) pair<t1, t2>
|
||||
|
||||
#if !defined(WIN32) && !defined(WIN64)
|
||||
#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline uint256 SHA256Hash(const T1 pbegin, const T1 pend)
|
||||
{
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline uint256 SHA256Hash(const T1 p1begin, const T1 p1end,
|
||||
const T2 p2begin, const T2 p2end)
|
||||
{
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
inline uint256 SHA256Hash(const T1 p1begin, const T1 p1end,
|
||||
const T2 p2begin, const T2 p2end,
|
||||
const T3 p3begin, const T3 p3end)
|
||||
{
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
||||
SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
|
||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
}
|
||||
|
||||
inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
uint256 hash1;
|
||||
SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
|
||||
uint160 hash2;
|
||||
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef WIN32
|
||||
// This is used to attempt to keep keying material out of swap
|
||||
// Note that VirtualLock does not provide this as a guarantee on Windows,
|
||||
// but, in practice, memory that has been VirtualLock'd almost never gets written to
|
||||
// the pagefile except in rare circumstances where memory is extremely low.
|
||||
#include <windows.h>
|
||||
#define mlock(p, n) VirtualLock((p), (n));
|
||||
#define munlock(p, n) VirtualUnlock((p), (n));
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <limits.h>
|
||||
// This comes from limits.h if it's not defined there set a sane default
|
||||
#ifndef PAGESIZE
|
||||
#include <unistd.h>
|
||||
#define PAGESIZE sysconf(_SC_PAGESIZE)
|
||||
#endif
|
||||
#define mlock(a,b) \
|
||||
mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
|
||||
(((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
|
||||
#define munlock(a,b) \
|
||||
munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
|
||||
(((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
|
||||
#endif
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "RPC.h"
|
||||
#include "RPCErr.h"
|
||||
#include "Config.h"
|
||||
#include "BitcoinUtil.h"
|
||||
|
||||
#include "CallRPC.h"
|
||||
|
||||
|
||||
@@ -80,8 +80,6 @@
|
||||
#define DEFAULT_FEE_OPERATION 1
|
||||
|
||||
Config theConfig;
|
||||
const char* ALPHABET = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
|
||||
const char* ALPHABET_BITCOIN = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
void Config::setup(const std::string& strConf, bool bTestNet, bool bQuiet)
|
||||
{
|
||||
@@ -112,7 +110,7 @@ void Config::setup(const std::string& strConf, bool bTestNet, bool bQuiet)
|
||||
SIGN_PROPOSAL = TESTNET ? sHP_TestNetProposal : sHP_Proposal;
|
||||
|
||||
if (TESTNET)
|
||||
ALPHABET = "RPShNAF39wBUDnEGHJKLM4pQrsT7VWXYZ2bcdeCg65jkm8ofqi1tuvaxyz";
|
||||
Base58::setCurrentAlphabet (Base58::getTestnetAlphabet ());
|
||||
|
||||
if (!strConf.empty())
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "ParseSection.h"
|
||||
#include "SerializedTypes.h"
|
||||
|
||||
@@ -200,8 +199,6 @@ public:
|
||||
|
||||
extern Config theConfig;
|
||||
|
||||
extern const char* ALPHABET;
|
||||
extern const char* ALPHABET_BITCOIN;
|
||||
#endif
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "Serializer.h"
|
||||
|
||||
// <-- seed
|
||||
uint128 CKey::PassPhraseToKey(const std::string& passPhrase)
|
||||
{
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include "key.h"
|
||||
|
||||
// ECIES uses elliptic curve keys to send an encrypted message.
|
||||
|
||||
// A shared secret is generated from one public key and one private key.
|
||||
// The same key results regardless of which key is public and which private.
|
||||
|
||||
// Anonymous messages can be sent by generating an ephemeral public/private
|
||||
// key pair, using that private key with the recipient's public key to
|
||||
// encrypt and publishing the ephemeral public key. Non-anonymous messages
|
||||
// can be sent by using your own private key with the recipient's public key.
|
||||
|
||||
// A random IV is used to encrypt the message and an HMAC is used to ensure
|
||||
// message integrity. If you need timestamps or need to tell the recipient
|
||||
// which key to use (his, yours, or ephemeral) you must add that data.
|
||||
// (Obviously, key information can't go in the encrypted portion anyway.)
|
||||
|
||||
// Our ciphertext is all encrypted except the IV. The encrypted data decodes as follows:
|
||||
// 1) IV (unencrypted)
|
||||
// 2) Encrypted: HMAC of original plaintext
|
||||
// 3) Encrypted: Original plaintext
|
||||
// 4) Encrypted: Rest of block/padding
|
||||
|
||||
// ECIES operations throw on any error such as a corrupt message or incorrect
|
||||
// key. They *must* be called in try/catch blocks.
|
||||
|
||||
// Algorithmic choices:
|
||||
#define ECIES_KEY_HASH SHA512 // Hash used to expand shared secret
|
||||
#define ECIES_KEY_LENGTH (512/8) // Size of expanded shared secret
|
||||
#define ECIES_MIN_SEC (128/8) // The minimum equivalent security
|
||||
#define ECIES_ENC_ALGO EVP_aes_256_cbc() // Encryption algorithm
|
||||
#define ECIES_ENC_KEY_TYPE uint256 // Type used to hold shared secret
|
||||
#define ECIES_ENC_KEY_SIZE (256/8) // Encryption key size
|
||||
#define ECIES_ENC_BLK_SIZE (128/8) // Encryption block size
|
||||
#define ECIES_ENC_IV_TYPE uint128 // Type used to hold IV
|
||||
#define ECIES_HMAC_ALGO EVP_sha256() // HMAC algorithm
|
||||
#define ECIES_HMAC_KEY_TYPE uint256 // Type used to hold HMAC key
|
||||
#define ECIES_HMAC_KEY_SIZE (256/8) // Size of HMAC key
|
||||
#define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value
|
||||
#define ECIES_HMAC_SIZE (256/8) // Size of HMAC value
|
||||
|
||||
void CKey::getECIESSecret(CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
|
||||
{ // Retrieve a secret generated from an EC key pair. At least one private key must be known.
|
||||
if (!pkey || !otherKey.pkey)
|
||||
throw std::runtime_error("missing key");
|
||||
|
||||
EC_KEY *pubkey, *privkey;
|
||||
if (EC_KEY_get0_private_key(pkey))
|
||||
{
|
||||
privkey = pkey;
|
||||
pubkey = otherKey.pkey;
|
||||
}
|
||||
else if (EC_KEY_get0_private_key(otherKey.pkey))
|
||||
{
|
||||
privkey = otherKey.pkey;
|
||||
pubkey = pkey;
|
||||
}
|
||||
else throw std::runtime_error("no private key");
|
||||
|
||||
unsigned char rawbuf[512];
|
||||
int buflen = ECDH_compute_key(rawbuf, 512, EC_KEY_get0_public_key(pubkey), privkey, NULL);
|
||||
if (buflen < ECIES_MIN_SEC)
|
||||
throw std::runtime_error("ecdh key failed");
|
||||
|
||||
unsigned char hbuf[ECIES_KEY_LENGTH];
|
||||
ECIES_KEY_HASH(rawbuf, buflen, hbuf);
|
||||
memset(rawbuf, 0, ECIES_HMAC_KEY_SIZE);
|
||||
|
||||
assert((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH);
|
||||
memcpy(enc_key.begin(), hbuf, ECIES_ENC_KEY_SIZE);
|
||||
memcpy(hmac_key.begin(), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE);
|
||||
memset(hbuf, 0, ECIES_KEY_LENGTH);
|
||||
}
|
||||
|
||||
static ECIES_HMAC_TYPE makeHMAC(const ECIES_HMAC_KEY_TYPE& secret, const std::vector<unsigned char>& data)
|
||||
{
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init(&ctx);
|
||||
|
||||
if (HMAC_Init_ex(&ctx, secret.begin(), ECIES_HMAC_KEY_SIZE, ECIES_HMAC_ALGO, NULL) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("init hmac");
|
||||
}
|
||||
|
||||
if (HMAC_Update(&ctx, &(data.front()), data.size()) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("update hmac");
|
||||
}
|
||||
|
||||
ECIES_HMAC_TYPE ret;
|
||||
unsigned int ml = ECIES_HMAC_SIZE;
|
||||
if (HMAC_Final(&ctx, ret.begin(), &ml) != 1)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("finalize hmac");
|
||||
}
|
||||
assert(ml == ECIES_HMAC_SIZE);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CKey::encryptECIES(CKey& otherKey, const std::vector<unsigned char>& plaintext)
|
||||
{
|
||||
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
getRand(static_cast<unsigned char *>(iv.begin()), ECIES_ENC_BLK_SIZE);
|
||||
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
|
||||
getECIESSecret(otherKey, secret, hmacKey);
|
||||
ECIES_HMAC_TYPE hmac = makeHMAC(hmacKey, plaintext);
|
||||
hmacKey.zero();
|
||||
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
if (EVP_EncryptInit_ex(&ctx, ECIES_ENC_ALGO, NULL, secret.begin(), iv.begin()) != 1)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
secret.zero();
|
||||
throw std::runtime_error("init cipher ctx");
|
||||
}
|
||||
secret.zero();
|
||||
|
||||
std::vector<unsigned char> out(plaintext.size() + ECIES_HMAC_SIZE + ECIES_ENC_KEY_SIZE + ECIES_ENC_BLK_SIZE, 0);
|
||||
int len = 0, bytesWritten;
|
||||
|
||||
// output IV
|
||||
memcpy(&(out.front()), iv.begin(), ECIES_ENC_BLK_SIZE);
|
||||
len = ECIES_ENC_BLK_SIZE;
|
||||
|
||||
// Encrypt/output HMAC
|
||||
bytesWritten = out.capacity() - len;
|
||||
assert(bytesWritten>0);
|
||||
if (EVP_EncryptUpdate(&ctx, &(out.front()) + len, &bytesWritten, hmac.begin(), ECIES_HMAC_SIZE) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
len += bytesWritten;
|
||||
|
||||
// encrypt/output plaintext
|
||||
bytesWritten = out.capacity() - len;
|
||||
assert(bytesWritten>0);
|
||||
if (EVP_EncryptUpdate(&ctx, &(out.front()) + len, &bytesWritten, &(plaintext.front()), plaintext.size()) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
len += bytesWritten;
|
||||
|
||||
// finalize
|
||||
bytesWritten = out.capacity() - len;
|
||||
if (EVP_EncryptFinal_ex(&ctx, &(out.front()) + len, &bytesWritten) < 0)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("encryption error");
|
||||
}
|
||||
len += bytesWritten;
|
||||
|
||||
// Output contains: IV, encrypted HMAC, encrypted data, encrypted padding
|
||||
assert(len <= (plaintext.size() + ECIES_HMAC_SIZE + (2 * ECIES_ENC_BLK_SIZE)));
|
||||
assert(len >= (plaintext.size() + ECIES_HMAC_SIZE + ECIES_ENC_BLK_SIZE)); // IV, HMAC, data
|
||||
out.resize(len);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> CKey::decryptECIES(CKey& otherKey, const std::vector<unsigned char>& ciphertext)
|
||||
{
|
||||
// minimum ciphertext = IV + HMAC + 1 block
|
||||
if (ciphertext.size() < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
|
||||
throw std::runtime_error("ciphertext too short");
|
||||
|
||||
// extract IV
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
memcpy(iv.begin(), &(ciphertext.front()), ECIES_ENC_BLK_SIZE);
|
||||
|
||||
// begin decrypting
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
ECIES_ENC_KEY_TYPE secret;
|
||||
ECIES_HMAC_KEY_TYPE hmacKey;
|
||||
getECIESSecret(otherKey, secret, hmacKey);
|
||||
|
||||
if (EVP_DecryptInit_ex(&ctx, ECIES_ENC_ALGO, NULL, secret.begin(), iv.begin()) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to init cipher");
|
||||
}
|
||||
|
||||
// decrypt mac
|
||||
ECIES_HMAC_TYPE hmac;
|
||||
int outlen = ECIES_HMAC_SIZE;
|
||||
if ( (EVP_DecryptUpdate(&ctx, hmac.begin(), &outlen,
|
||||
&(ciphertext.front()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) )
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to extract hmac");
|
||||
}
|
||||
|
||||
// decrypt plaintext (after IV and encrypted mac)
|
||||
std::vector<unsigned char> plaintext(ciphertext.size() - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE);
|
||||
outlen = plaintext.size();
|
||||
if (EVP_DecryptUpdate(&ctx, &(plaintext.front()), &outlen,
|
||||
&(ciphertext.front()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1,
|
||||
ciphertext.size() - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("unable to extract plaintext");
|
||||
}
|
||||
|
||||
// decrypt padding
|
||||
int flen = 0;
|
||||
if (EVP_DecryptFinal(&ctx, &(plaintext.front()) + outlen, &flen) != 1)
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("plaintext had bad padding");
|
||||
}
|
||||
plaintext.resize(flen + outlen);
|
||||
|
||||
// verify integrity
|
||||
if (hmac != makeHMAC(hmacKey, plaintext))
|
||||
{
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
throw std::runtime_error("plaintext had bad hmac");
|
||||
}
|
||||
secret.zero();
|
||||
hmacKey.zero();
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
bool checkECIES(void)
|
||||
{
|
||||
CKey senderPriv, recipientPriv, senderPub, recipientPub;
|
||||
|
||||
for (int i = 0; i < 30000; ++i)
|
||||
{
|
||||
if ((i % 100) == 0)
|
||||
{ // generate new keys every 100 times
|
||||
// std::cerr << "new keys" << std::endl;
|
||||
senderPriv.MakeNewKey();
|
||||
recipientPriv.MakeNewKey();
|
||||
|
||||
if (!senderPub.SetPubKey(senderPriv.GetPubKey()))
|
||||
throw std::runtime_error("key error");
|
||||
if (!recipientPub.SetPubKey(recipientPriv.GetPubKey()))
|
||||
throw std::runtime_error("key error");
|
||||
}
|
||||
|
||||
// generate message
|
||||
std::vector<unsigned char> message(4096);
|
||||
int msglen = i%3000;
|
||||
|
||||
getRand(static_cast<unsigned char *>(&message.front()), msglen);
|
||||
message.resize(msglen);
|
||||
|
||||
// encrypt message with sender's private key and recipient's public key
|
||||
std::vector<unsigned char> ciphertext = senderPriv.encryptECIES(recipientPub, message);
|
||||
|
||||
// decrypt message with recipient's private key and sender's public key
|
||||
std::vector<unsigned char> decrypt = recipientPriv.decryptECIES(senderPub, ciphertext);
|
||||
|
||||
if (decrypt != message)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
// std::cerr << "Msg(" << msglen << ") ok " << ciphertext.size() << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,132 +0,0 @@
|
||||
|
||||
#include "FieldNames.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
// These must stay at the top of this file
|
||||
std::map<int, SField::ptr> SField::codeToField;
|
||||
boost::mutex SField::mapMutex;
|
||||
int SField::num = 0;
|
||||
|
||||
SField sfInvalid(-1), sfGeneric(0);
|
||||
SField sfLedgerEntry(STI_LEDGERENTRY, 1, "LedgerEntry");
|
||||
SField sfTransaction(STI_TRANSACTION, 1, "Transaction");
|
||||
SField sfValidation(STI_VALIDATION, 1, "Validation");
|
||||
SField sfHash(STI_HASH256, 257, "hash");
|
||||
SField sfIndex(STI_HASH256, 258, "index");
|
||||
|
||||
#define FIELD(name, type, index) SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
|
||||
#define TYPE(name, type, index)
|
||||
#include "SerializeProto.h"
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
static int initFields()
|
||||
{
|
||||
sfTxnSignature.notSigningField();
|
||||
sfTxnSignatures.notSigningField();
|
||||
sfSignature.notSigningField();
|
||||
|
||||
sfIndexes.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnID.setMeta(SField::sMD_DeleteFinal);
|
||||
sfPreviousTxnLgrSeq.setMeta(SField::sMD_DeleteFinal);
|
||||
sfLedgerEntryType.setMeta(SField::sMD_Never);
|
||||
sfRootIndex.setMeta(SField::sMD_Always);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const int f = initFields();
|
||||
|
||||
|
||||
SField::SField(SerializedTypeID tid, int fv) : fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv),
|
||||
fieldMeta(sMD_Default), fieldNum(++num), signingField(true)
|
||||
{ // call with the map mutex
|
||||
fieldName = lexical_cast_i(tid) + "/" + lexical_cast_i(fv);
|
||||
codeToField[fieldCode] = this;
|
||||
assert((fv != 1) || ((tid != STI_ARRAY) && (tid!=STI_OBJECT)));
|
||||
}
|
||||
|
||||
SField::ref SField::getField(int code)
|
||||
{
|
||||
int type = code >> 16;
|
||||
int field = code % 0xffff;
|
||||
|
||||
if ((type <= 0) || (field <= 0))
|
||||
return sfInvalid;
|
||||
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
|
||||
std::map<int, SField::ptr>::iterator it = codeToField.find(code);
|
||||
if (it != codeToField.end())
|
||||
return *(it->second);
|
||||
|
||||
if (field > 255) // don't dynamically extend types that have no binary encoding
|
||||
return sfInvalid;
|
||||
|
||||
switch (type)
|
||||
{ // types we are willing to dynamically extend
|
||||
|
||||
#define FIELD(name, type, index)
|
||||
#define TYPE(name, type, index) case STI_##type:
|
||||
#include "SerializeProto.h"
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
break;
|
||||
default:
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
return *(new SField(static_cast<SerializedTypeID>(type), field));
|
||||
}
|
||||
|
||||
int SField::compare(SField::ref f1, SField::ref f2)
|
||||
{ // -1 = f1 comes before f2, 0 = illegal combination, 1 = f1 comes after f2
|
||||
if ((f1.fieldCode <= 0) || (f2.fieldCode <= 0))
|
||||
return 0;
|
||||
|
||||
if (f1.fieldCode < f2.fieldCode)
|
||||
return -1;
|
||||
|
||||
if (f2.fieldCode < f1.fieldCode)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string SField::getName() const
|
||||
{
|
||||
if (!fieldName.empty())
|
||||
return fieldName;
|
||||
if (fieldValue == 0)
|
||||
return "";
|
||||
return boost::lexical_cast<std::string>(static_cast<int>(fieldType)) + "/" +
|
||||
boost::lexical_cast<std::string>(fieldValue);
|
||||
}
|
||||
|
||||
SField::ref SField::getField(const std::string& fieldName)
|
||||
{ // OPTIMIZEME me with a map. CHECKME this is case sensitive
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
typedef std::map<int, SField::ptr>::value_type int_sfref_pair;
|
||||
BOOST_FOREACH(const int_sfref_pair& fieldPair, codeToField)
|
||||
{
|
||||
if (fieldPair.second->fieldName == fieldName)
|
||||
return *(fieldPair.second);
|
||||
}
|
||||
return sfInvalid;
|
||||
}
|
||||
|
||||
SField::~SField()
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
std::map<int, ptr>::iterator it = codeToField.find(fieldCode);
|
||||
if ((it != codeToField.end()) && (it->second == this))
|
||||
codeToField.erase(it);
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,133 +0,0 @@
|
||||
#ifndef __FIELDNAMES__
|
||||
#define __FIELDNAMES__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#define FIELD_CODE(type, index) ((static_cast<int>(type) << 16) | index)
|
||||
|
||||
enum SerializedTypeID
|
||||
{
|
||||
// special types
|
||||
STI_UNKNOWN = -2,
|
||||
STI_DONE = -1,
|
||||
STI_NOTPRESENT = 0,
|
||||
|
||||
#define TYPE(name, field, value) STI_##field = value,
|
||||
#define FIELD(name, field, value)
|
||||
#include "SerializeProto.h"
|
||||
#undef TYPE
|
||||
#undef FIELD
|
||||
|
||||
// high level types
|
||||
STI_TRANSACTION = 10001,
|
||||
STI_LEDGERENTRY = 10002,
|
||||
STI_VALIDATION = 10003,
|
||||
};
|
||||
|
||||
enum SOE_Flags
|
||||
{
|
||||
SOE_INVALID = -1,
|
||||
SOE_REQUIRED = 0, // required
|
||||
SOE_OPTIONAL = 1, // optional, may be present with default value
|
||||
SOE_DEFAULT = 2, // optional, if present, must not have default value
|
||||
};
|
||||
|
||||
class SField
|
||||
{
|
||||
public:
|
||||
typedef const SField& ref;
|
||||
typedef SField const * ptr;
|
||||
|
||||
static const int sMD_Never = 0x00;
|
||||
static const int sMD_ChangeOrig = 0x01; // original value when it changes
|
||||
static const int sMD_ChangeNew = 0x02; // new value when it changes
|
||||
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
|
||||
static const int sMD_Create = 0x08; // value when it's created
|
||||
static const int sMD_Always = 0x10; // value when node containing it is affected at all
|
||||
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal | sMD_Create;
|
||||
|
||||
protected:
|
||||
static std::map<int, ptr> codeToField;
|
||||
static boost::mutex mapMutex;
|
||||
static int num;
|
||||
|
||||
SField(SerializedTypeID id, int val);
|
||||
|
||||
public:
|
||||
|
||||
const int fieldCode; // (type<<16)|index
|
||||
const SerializedTypeID fieldType; // STI_*
|
||||
const int fieldValue; // Code number for protocol
|
||||
std::string fieldName;
|
||||
int fieldMeta;
|
||||
int fieldNum;
|
||||
bool signingField;
|
||||
|
||||
SField(int fc, SerializedTypeID tid, int fv, const char* fn) :
|
||||
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
SField(SerializedTypeID tid, int fv, const char *fn) :
|
||||
fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn),
|
||||
fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0), fieldMeta(sMD_Never), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
fieldNum = ++num;
|
||||
}
|
||||
|
||||
~SField();
|
||||
|
||||
static SField::ref getField(int fieldCode);
|
||||
static SField::ref getField(const std::string& fieldName);
|
||||
static SField::ref getField(int type, int value) { return getField(FIELD_CODE(type, value)); }
|
||||
static SField::ref getField(SerializedTypeID type, int value) { return getField(FIELD_CODE(type, value)); }
|
||||
|
||||
std::string getName() const;
|
||||
bool hasName() const { return !fieldName.empty(); }
|
||||
|
||||
bool isGeneric() const { return fieldCode == 0; }
|
||||
bool isInvalid() const { return fieldCode == -1; }
|
||||
bool isUseful() const { return fieldCode > 0; }
|
||||
bool isKnown() const { return fieldType != STI_UNKNOWN; }
|
||||
bool isBinary() const { return fieldValue < 256; }
|
||||
bool isDiscardable() const { return fieldValue > 256; }
|
||||
int getCode() const { return fieldCode; }
|
||||
int getNum() const { return fieldNum; }
|
||||
static int getNumFields() { return num; }
|
||||
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
bool shouldMeta(int c) const { return (fieldMeta & c) != 0; }
|
||||
void setMeta(int c) { fieldMeta = c; }
|
||||
|
||||
bool shouldInclude(bool withSigningField) const
|
||||
{ return (fieldValue < 256) && (withSigningField || signingField); }
|
||||
|
||||
bool operator==(const SField& f) const { return fieldCode == f.fieldCode; }
|
||||
bool operator!=(const SField& f) const { return fieldCode != f.fieldCode; }
|
||||
|
||||
static int compare(SField::ref f1, SField::ref f2);
|
||||
};
|
||||
|
||||
extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation;
|
||||
|
||||
#define FIELD(name, type, index) extern SField sf##name;
|
||||
#define TYPE(name, type, index)
|
||||
#include "SerializeProto.h"
|
||||
#undef FIELD
|
||||
#undef TYPE
|
||||
|
||||
#endif
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "../database/SqliteDatabase.h"
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "Application.h"
|
||||
|
||||
SETUP_LOG (HashedObject)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
#include "modules/ripple_main/misc/ripple_HashValue.h"
|
||||
|
||||
#include "ScopedLock.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "TransactionMeta.h"
|
||||
#include "AccountState.h"
|
||||
#include "NicknameState.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "SHAMap.h"
|
||||
#include "InstanceCounter.h"
|
||||
#include "LoadMonitor.h"
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "key.h"
|
||||
#include "Transaction.h"
|
||||
#include "LedgerAcquire.h"
|
||||
#include "LedgerProposal.h"
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "Serializer.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
DEFINE_INSTANCE(LedgerProposal);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "HashPrefixes.h"
|
||||
#include "LedgerConsensus.h"
|
||||
#include "LedgerTiming.h"
|
||||
#include "RippleAddress.h"
|
||||
|
||||
SETUP_LOG (NetworkOPs)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "SerializedTypes.h"
|
||||
#include "Pathfinder.h"
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "SerializedTypes.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "RippleCalc.h"
|
||||
#include "OrderBookDB.h"
|
||||
#include "AccountItems.h"
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "Serializer.h"
|
||||
|
||||
SETUP_LOG (ProofOfWork)
|
||||
|
||||
bool powResultInfo(POWResult powCode, std::string& strToken, std::string& strHuman)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "Application.h"
|
||||
#include "AccountItems.h"
|
||||
#include "Wallet.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "RippleCalc.h"
|
||||
#include "RPCErr.h"
|
||||
#include "AccountState.h"
|
||||
@@ -514,7 +513,7 @@ Json::Value RPCHandler::accountFromString(Ledger::ref lrLedger, RippleAddress& n
|
||||
}
|
||||
else if (bStrict)
|
||||
{
|
||||
return naAccount.setAccountID(strIdent, ALPHABET_BITCOIN)
|
||||
return naAccount.setAccountID(strIdent, Base58::getBitcoinAlphabet ())
|
||||
? rpcError(rpcACT_BITCOIN)
|
||||
: rpcError(rpcACT_MALFORMED);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "SerializedTypes.h"
|
||||
#include "Ledger.h"
|
||||
#include "NetworkOPs.h"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include "HTTPRequest.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "NetworkOPs.h"
|
||||
#include "SerializedLedger.h"
|
||||
#include "RPCHandler.h"
|
||||
|
||||
@@ -1,918 +0,0 @@
|
||||
#include <boost/asio.hpp>
|
||||
#include "RippleAddress.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "rfc1751.h"
|
||||
#include "Serializer.h"
|
||||
#include "Application.h"
|
||||
|
||||
SETUP_LOG (RippleAddress)
|
||||
|
||||
std::size_t hash_value(const CBase58Data& b58)
|
||||
{
|
||||
std::size_t seed = theApp->getNonceST() + (b58.nVersion * 0x9e3779b9);
|
||||
boost::hash_combine(seed, b58.vchData);
|
||||
return seed;
|
||||
}
|
||||
|
||||
RippleAddress::RippleAddress() : mIsValid(false)
|
||||
{
|
||||
nVersion = VER_NONE;
|
||||
}
|
||||
|
||||
void RippleAddress::clear()
|
||||
{
|
||||
nVersion = VER_NONE;
|
||||
vchData.clear();
|
||||
}
|
||||
|
||||
bool RippleAddress::isSet() const
|
||||
{
|
||||
return nVersion != VER_NONE;
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanAddressType() const
|
||||
{
|
||||
switch (nVersion)
|
||||
{
|
||||
case VER_NONE: return "VER_NONE";
|
||||
case VER_NODE_PUBLIC: return "VER_NODE_PUBLIC";
|
||||
case VER_NODE_PRIVATE: return "VER_NODE_PRIVATE";
|
||||
case VER_ACCOUNT_ID: return "VER_ACCOUNT_ID";
|
||||
case VER_ACCOUNT_PUBLIC: return "VER_ACCOUNT_PUBLIC";
|
||||
case VER_ACCOUNT_PRIVATE: return "VER_ACCOUNT_PRIVATE";
|
||||
case VER_FAMILY_GENERATOR: return "VER_FAMILY_GENERATOR";
|
||||
case VER_FAMILY_SEED: return "VER_FAMILY_SEED";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
//
|
||||
// NodePublic
|
||||
//
|
||||
|
||||
RippleAddress RippleAddress::createNodePublic(const RippleAddress& naSeed)
|
||||
{
|
||||
CKey ckSeed(naSeed.getSeed());
|
||||
RippleAddress naNew;
|
||||
|
||||
// YYY Should there be a GetPubKey() equiv that returns a uint256?
|
||||
naNew.setNodePublic(ckSeed.GetPubKey());
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createNodePublic(const std::vector<unsigned char>& vPublic)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setNodePublic(vPublic);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createNodePublic(const std::string& strPublic)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setNodePublic(strPublic);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
uint160 RippleAddress::getNodeID() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getNodeID");
|
||||
|
||||
case VER_NODE_PUBLIC:
|
||||
// Note, we are encoding the left.
|
||||
return Hash160(vchData);
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
const std::vector<unsigned char>& RippleAddress::getNodePublic() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getNodePublic");
|
||||
|
||||
case VER_NODE_PUBLIC:
|
||||
return vchData;
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanNodePublic() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanNodePublic");
|
||||
|
||||
case VER_NODE_PUBLIC:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setNodePublic(const std::string& strPublic)
|
||||
{
|
||||
mIsValid = SetString(strPublic.c_str(), VER_NODE_PUBLIC);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setNodePublic(const std::vector<unsigned char>& vPublic)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_NODE_PUBLIC, vPublic);
|
||||
}
|
||||
|
||||
bool RippleAddress::verifyNodePublic(const uint256& hash, const std::vector<unsigned char>& vchSig) const
|
||||
{
|
||||
CKey pubkey = CKey();
|
||||
bool bVerified;
|
||||
|
||||
if (!pubkey.SetPubKey(getNodePublic()))
|
||||
{
|
||||
// Failed to set public key.
|
||||
bVerified = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bVerified = pubkey.Verify(hash, vchSig);
|
||||
}
|
||||
|
||||
return bVerified;
|
||||
}
|
||||
|
||||
bool RippleAddress::verifyNodePublic(const uint256& hash, const std::string& strSig) const
|
||||
{
|
||||
std::vector<unsigned char> vchSig(strSig.begin(), strSig.end());
|
||||
|
||||
return verifyNodePublic(hash, vchSig);
|
||||
}
|
||||
|
||||
//
|
||||
// NodePrivate
|
||||
//
|
||||
|
||||
RippleAddress RippleAddress::createNodePrivate(const RippleAddress& naSeed)
|
||||
{
|
||||
uint256 uPrivKey;
|
||||
RippleAddress naNew;
|
||||
CKey ckSeed(naSeed.getSeed());
|
||||
|
||||
ckSeed.GetPrivateKeyU(uPrivKey);
|
||||
|
||||
naNew.setNodePrivate(uPrivKey);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
const std::vector<unsigned char>& RippleAddress::getNodePrivateData() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getNodePrivateData");
|
||||
|
||||
case VER_NODE_PRIVATE:
|
||||
return vchData;
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
uint256 RippleAddress::getNodePrivate() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source = getNodePrivate");
|
||||
|
||||
case VER_NODE_PRIVATE:
|
||||
return uint256(vchData);
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanNodePrivate() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanNodePrivate");
|
||||
|
||||
case VER_NODE_PRIVATE:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setNodePrivate(const std::string& strPrivate)
|
||||
{
|
||||
mIsValid = SetString(strPrivate.c_str(), VER_NODE_PRIVATE);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setNodePrivate(const std::vector<unsigned char>& vPrivate)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_NODE_PRIVATE, vPrivate);
|
||||
}
|
||||
|
||||
void RippleAddress::setNodePrivate(uint256 hash256)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_NODE_PRIVATE, hash256.begin(), 32);
|
||||
}
|
||||
|
||||
void RippleAddress::signNodePrivate(const uint256& hash, std::vector<unsigned char>& vchSig) const
|
||||
{
|
||||
CKey ckPrivKey;
|
||||
|
||||
ckPrivKey.SetPrivateKeyU(getNodePrivate());
|
||||
|
||||
if (!ckPrivKey.Sign(hash, vchSig))
|
||||
throw std::runtime_error("Signing failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// AccountID
|
||||
//
|
||||
|
||||
uint160 RippleAddress::getAccountID() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getAccountID");
|
||||
|
||||
case VER_ACCOUNT_ID:
|
||||
return uint160(vchData);
|
||||
|
||||
case VER_ACCOUNT_PUBLIC:
|
||||
// Note, we are encoding the left.
|
||||
return Hash160(vchData);
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
static boost::mutex rncLock;
|
||||
static boost::unordered_map< std::vector<unsigned char>, std::string > rncMap;
|
||||
|
||||
std::string RippleAddress::humanAccountID() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanAccountID");
|
||||
|
||||
case VER_ACCOUNT_ID:
|
||||
{
|
||||
boost::mutex::scoped_lock sl(rncLock);
|
||||
boost::unordered_map< std::vector<unsigned char>, std::string >::iterator it = rncMap.find(vchData);
|
||||
if (it != rncMap.end())
|
||||
return it->second;
|
||||
if (rncMap.size() > 10000)
|
||||
rncMap.clear();
|
||||
return rncMap[vchData] = ToString();
|
||||
}
|
||||
|
||||
case VER_ACCOUNT_PUBLIC:
|
||||
{
|
||||
RippleAddress accountID;
|
||||
|
||||
(void) accountID.setAccountID(getAccountID());
|
||||
|
||||
return accountID.ToString();
|
||||
}
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setAccountID(const std::string& strAccountID, const char* pAlphabet)
|
||||
{
|
||||
if (strAccountID.empty())
|
||||
{
|
||||
setAccountID(uint160());
|
||||
|
||||
mIsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsValid = SetString(strAccountID.c_str(), VER_ACCOUNT_ID, pAlphabet);
|
||||
}
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountID(const uint160& hash160)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_ACCOUNT_ID, hash160.begin(), 20);
|
||||
}
|
||||
|
||||
//
|
||||
// AccountPublic
|
||||
//
|
||||
|
||||
RippleAddress RippleAddress::createAccountPublic(const RippleAddress& naGenerator, int iSeq)
|
||||
{
|
||||
CKey ckPub(naGenerator, iSeq);
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPublic(ckPub.GetPubKey());
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
const std::vector<unsigned char>& RippleAddress::getAccountPublic() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getAccountPublic");
|
||||
|
||||
case VER_ACCOUNT_ID:
|
||||
throw std::runtime_error("public not available from account id");
|
||||
break;
|
||||
|
||||
case VER_ACCOUNT_PUBLIC:
|
||||
return vchData;
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanAccountPublic() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanAccountPublic");
|
||||
|
||||
case VER_ACCOUNT_ID:
|
||||
throw std::runtime_error("public not available from account id");
|
||||
|
||||
case VER_ACCOUNT_PUBLIC:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setAccountPublic(const std::string& strPublic)
|
||||
{
|
||||
mIsValid = SetString(strPublic.c_str(), VER_ACCOUNT_PUBLIC);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountPublic(const std::vector<unsigned char>& vPublic)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_ACCOUNT_PUBLIC, vPublic);
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountPublic(const RippleAddress& generator, int seq)
|
||||
{
|
||||
CKey pubkey = CKey(generator, seq);
|
||||
|
||||
setAccountPublic(pubkey.GetPubKey());
|
||||
}
|
||||
|
||||
bool RippleAddress::accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const
|
||||
{
|
||||
CKey ckPublic;
|
||||
bool bVerified;
|
||||
|
||||
if (!ckPublic.SetPubKey(getAccountPublic()))
|
||||
{
|
||||
// Bad private key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPublicVerify: Bad private key.";
|
||||
bVerified = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bVerified = ckPublic.Verify(uHash, vucSig);
|
||||
}
|
||||
|
||||
return bVerified;
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createAccountID(const uint160& uiAccountID)
|
||||
{
|
||||
RippleAddress na;
|
||||
|
||||
na.setAccountID(uiAccountID);
|
||||
|
||||
return na;
|
||||
}
|
||||
|
||||
//
|
||||
// AccountPrivate
|
||||
//
|
||||
|
||||
RippleAddress RippleAddress::createAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPrivate(naGenerator, naSeed, iSeq);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
uint256 RippleAddress::getAccountPrivate() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getAccountPrivate");
|
||||
|
||||
case VER_ACCOUNT_PRIVATE:
|
||||
return uint256(vchData);
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanAccountPrivate() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanAccountPrivate");
|
||||
|
||||
case VER_ACCOUNT_PRIVATE:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setAccountPrivate(const std::string& strPrivate)
|
||||
{
|
||||
mIsValid = SetString(strPrivate.c_str(), VER_ACCOUNT_PRIVATE);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountPrivate(const std::vector<unsigned char>& vPrivate)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_ACCOUNT_PRIVATE, vPrivate);
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountPrivate(uint256 hash256)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_ACCOUNT_PRIVATE, hash256.begin(), 32);
|
||||
}
|
||||
|
||||
void RippleAddress::setAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq)
|
||||
{
|
||||
CKey ckPubkey = CKey(naSeed.getSeed());
|
||||
CKey ckPrivkey = CKey(naGenerator, ckPubkey.GetSecretBN(), seq);
|
||||
uint256 uPrivKey;
|
||||
|
||||
ckPrivkey.GetPrivateKeyU(uPrivKey);
|
||||
|
||||
setAccountPrivate(uPrivKey);
|
||||
}
|
||||
|
||||
bool RippleAddress::accountPrivateSign(const uint256& uHash, std::vector<unsigned char>& vucSig) const
|
||||
{
|
||||
CKey ckPrivate;
|
||||
bool bResult;
|
||||
|
||||
if (!ckPrivate.SetPrivateKeyU(getAccountPrivate()))
|
||||
{
|
||||
// Bad private key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateSign: Bad private key.";
|
||||
bResult = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bResult = ckPrivate.Sign(uHash, vucSig);
|
||||
CondLog (!bResult, lsWARNING, RippleAddress) << "accountPrivateSign: Signing failed.";
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool RippleAddress::accountPrivateVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const
|
||||
{
|
||||
CKey ckPrivate;
|
||||
bool bVerified;
|
||||
|
||||
if (!ckPrivate.SetPrivateKeyU(getAccountPrivate()))
|
||||
{
|
||||
// Bad private key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateVerify: Bad private key.";
|
||||
bVerified = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bVerified = ckPrivate.Verify(uHash, vucSig);
|
||||
}
|
||||
|
||||
return bVerified;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<unsigned char> RippleAddress::accountPrivateEncrypt(const RippleAddress& naPublicTo, const std::vector<unsigned char>& vucPlainText) const
|
||||
{
|
||||
CKey ckPrivate;
|
||||
CKey ckPublic;
|
||||
std::vector<unsigned char> vucCipherText;
|
||||
|
||||
if (!ckPublic.SetPubKey(naPublicTo.getAccountPublic()))
|
||||
{
|
||||
// Bad public key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateEncrypt: Bad public key.";
|
||||
}
|
||||
else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate()))
|
||||
{
|
||||
// Bad private key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateEncrypt: Bad private key.";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
vucCipherText = ckPrivate.encryptECIES(ckPublic, vucPlainText);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
}
|
||||
|
||||
return vucCipherText;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> RippleAddress::accountPrivateDecrypt(const RippleAddress& naPublicFrom, const std::vector<unsigned char>& vucCipherText) const
|
||||
{
|
||||
CKey ckPrivate;
|
||||
CKey ckPublic;
|
||||
std::vector<unsigned char> vucPlainText;
|
||||
|
||||
if (!ckPublic.SetPubKey(naPublicFrom.getAccountPublic()))
|
||||
{
|
||||
// Bad public key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateDecrypt: Bad public key.";
|
||||
}
|
||||
else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate()))
|
||||
{
|
||||
// Bad private key.
|
||||
WriteLog (lsWARNING, RippleAddress) << "accountPrivateDecrypt: Bad private key.";
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
vucPlainText = ckPrivate.decryptECIES(ckPublic, vucCipherText);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
}
|
||||
|
||||
return vucPlainText;
|
||||
}
|
||||
|
||||
//
|
||||
// Generators
|
||||
//
|
||||
|
||||
BIGNUM* RippleAddress::getGeneratorBN() const
|
||||
{ // returns the public generator
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getGeneratorBN");
|
||||
|
||||
case VER_FAMILY_GENERATOR:
|
||||
// Do nothing.
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
|
||||
BIGNUM* ret = BN_bin2bn(&vchData[0], vchData.size(), NULL);
|
||||
assert(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::vector<unsigned char>& RippleAddress::getGenerator() const
|
||||
{ // returns the public generator
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getGenerator");
|
||||
|
||||
case VER_FAMILY_GENERATOR:
|
||||
// Do nothing.
|
||||
return vchData;
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanGenerator() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanGenerator");
|
||||
|
||||
case VER_FAMILY_GENERATOR:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
bool RippleAddress::setGenerator(const std::string& strGenerator)
|
||||
{
|
||||
mIsValid = SetString(strGenerator.c_str(), VER_FAMILY_GENERATOR);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
void RippleAddress::setGenerator(const std::vector<unsigned char>& vPublic)
|
||||
{
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_FAMILY_GENERATOR, vPublic);
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createGeneratorPublic(const RippleAddress& naSeed)
|
||||
{
|
||||
CKey ckSeed(naSeed.getSeed());
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setGenerator(ckSeed.GetPubKey());
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
//
|
||||
// Seed
|
||||
//
|
||||
|
||||
uint128 RippleAddress::getSeed() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - getSeed");
|
||||
|
||||
case VER_FAMILY_SEED:
|
||||
return uint128(vchData);
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanSeed1751() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanSeed1751");
|
||||
|
||||
case VER_FAMILY_SEED:
|
||||
{
|
||||
std::string strHuman;
|
||||
std::string strLittle;
|
||||
std::string strBig;
|
||||
uint128 uSeed = getSeed();
|
||||
|
||||
strLittle.assign(uSeed.begin(), uSeed.end());
|
||||
|
||||
strBig.assign(strLittle.rbegin(), strLittle.rend());
|
||||
|
||||
key2eng(strHuman, strBig);
|
||||
|
||||
return strHuman;
|
||||
}
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string RippleAddress::humanSeed() const
|
||||
{
|
||||
switch (nVersion) {
|
||||
case VER_NONE:
|
||||
throw std::runtime_error("unset source - humanSeed");
|
||||
|
||||
case VER_FAMILY_SEED:
|
||||
return ToString();
|
||||
|
||||
default:
|
||||
throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion)));
|
||||
}
|
||||
}
|
||||
|
||||
int RippleAddress::setSeed1751(const std::string& strHuman1751)
|
||||
{
|
||||
std::string strKey;
|
||||
int iResult = eng2key(strKey, strHuman1751);
|
||||
|
||||
if (1 == iResult)
|
||||
{
|
||||
std::vector<unsigned char> vchLittle(strKey.rbegin(), strKey.rend());
|
||||
uint128 uSeed(vchLittle);
|
||||
|
||||
setSeed(uSeed);
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
bool RippleAddress::setSeed(const std::string& strSeed)
|
||||
{
|
||||
mIsValid = SetString(strSeed.c_str(), VER_FAMILY_SEED);
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
extern const char *ALPHABET;
|
||||
|
||||
bool RippleAddress::setSeedGeneric(const std::string& strText)
|
||||
{
|
||||
RippleAddress naTemp;
|
||||
bool bResult = true;
|
||||
uint128 uSeed;
|
||||
|
||||
if (strText.empty()
|
||||
|| naTemp.setAccountID(strText)
|
||||
|| naTemp.setAccountPublic(strText)
|
||||
|| naTemp.setAccountPrivate(strText)
|
||||
|| naTemp.setNodePublic(strText)
|
||||
|| naTemp.setNodePrivate(strText))
|
||||
{
|
||||
bResult = false;
|
||||
}
|
||||
else if (strText.length() == 32 && uSeed.SetHex(strText, true))
|
||||
{
|
||||
setSeed(uSeed);
|
||||
}
|
||||
else if (setSeed(strText))
|
||||
{
|
||||
// std::cerr << "Recognized seed." << std::endl;
|
||||
nothing();
|
||||
}
|
||||
else if (1 == setSeed1751(strText))
|
||||
{
|
||||
// std::cerr << "Recognized 1751 seed." << std::endl;
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cerr << "Creating seed from pass phrase." << std::endl;
|
||||
setSeed(CKey::PassPhraseToKey(strText));
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void RippleAddress::setSeed(uint128 hash128) {
|
||||
mIsValid = true;
|
||||
|
||||
SetData(VER_FAMILY_SEED, hash128.begin(), 16);
|
||||
}
|
||||
|
||||
void RippleAddress::setSeedRandom()
|
||||
{
|
||||
// XXX Maybe we should call MakeNewKey
|
||||
uint128 key;
|
||||
|
||||
getRand(key.begin(), key.size());
|
||||
|
||||
RippleAddress::setSeed(key);
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createSeedRandom()
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setSeedRandom();
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
RippleAddress RippleAddress::createSeedGeneric(const std::string& strText)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setSeedGeneric(strText);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ripple_address)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( check_crypto )
|
||||
{
|
||||
// Construct a seed.
|
||||
RippleAddress naSeed;
|
||||
|
||||
BOOST_CHECK(naSeed.setSeedGeneric("masterpassphrase"));
|
||||
BOOST_CHECK_MESSAGE(naSeed.humanSeed() == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", naSeed.humanSeed());
|
||||
|
||||
// Create node public/private key pair
|
||||
RippleAddress naNodePublic = RippleAddress::createNodePublic(naSeed);
|
||||
RippleAddress naNodePrivate = RippleAddress::createNodePrivate(naSeed);
|
||||
|
||||
BOOST_CHECK_MESSAGE(naNodePublic.humanNodePublic() == "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", naNodePublic.humanNodePublic());
|
||||
BOOST_CHECK_MESSAGE(naNodePrivate.humanNodePrivate() == "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate());
|
||||
|
||||
// Check node signing.
|
||||
std::vector<unsigned char> vucTextSrc = strCopy("Hello, nurse!");
|
||||
uint256 uHash = Serializer::getSHA512Half(vucTextSrc);
|
||||
std::vector<unsigned char> vucTextSig;
|
||||
|
||||
naNodePrivate.signNodePrivate(uHash, vucTextSig);
|
||||
BOOST_CHECK_MESSAGE(naNodePublic.verifyNodePublic(uHash, vucTextSig), "Verify failed.");
|
||||
|
||||
// Construct a public generator from the seed.
|
||||
RippleAddress naGenerator = RippleAddress::createGeneratorPublic(naSeed);
|
||||
|
||||
BOOST_CHECK_MESSAGE(naGenerator.humanGenerator() == "fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt", naGenerator.humanGenerator());
|
||||
|
||||
// Create account #0 public/private key pair.
|
||||
RippleAddress naAccountPublic0 = RippleAddress::createAccountPublic(naGenerator, 0);
|
||||
RippleAddress naAccountPrivate0 = RippleAddress::createAccountPrivate(naGenerator, naSeed, 0);
|
||||
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic0.humanAccountID() == "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", naAccountPublic0.humanAccountID());
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic0.humanAccountPublic() == "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw", naAccountPublic0.humanAccountPublic());
|
||||
BOOST_CHECK_MESSAGE(naAccountPrivate0.humanAccountPrivate() == "p9JfM6HHi64m6mvB6v5k7G2b1cXzGmYiCNJf6GHPKvFTWdeRVjh", naAccountPrivate0.humanAccountPrivate());
|
||||
|
||||
// Create account #1 public/private key pair.
|
||||
RippleAddress naAccountPublic1 = RippleAddress::createAccountPublic(naGenerator, 1);
|
||||
RippleAddress naAccountPrivate1 = RippleAddress::createAccountPrivate(naGenerator, naSeed, 1);
|
||||
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic1.humanAccountID() == "r4bYF7SLUMD7QgSLLpgJx38WJSY12ViRjP", naAccountPublic1.humanAccountID());
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic1.humanAccountPublic() == "aBPXpTfuLy1Bhk3HnGTTAqnovpKWQ23NpFMNkAF6F1Atg5vDyPrw", naAccountPublic1.humanAccountPublic());
|
||||
BOOST_CHECK_MESSAGE(naAccountPrivate1.humanAccountPrivate() == "p9JEm822LMrzJii1k7TvdphfENTp6G5jr253Xa5rkzUWVr8ogQt", naAccountPrivate1.humanAccountPrivate());
|
||||
|
||||
// Check account signing.
|
||||
BOOST_CHECK_MESSAGE(naAccountPrivate0.accountPrivateSign(uHash, vucTextSig), "Signing failed.");
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic0.accountPublicVerify(uHash, vucTextSig), "Verify failed.");
|
||||
BOOST_CHECK_MESSAGE(!naAccountPublic1.accountPublicVerify(uHash, vucTextSig), "Anti-verify failed.");
|
||||
|
||||
BOOST_CHECK_MESSAGE(naAccountPrivate1.accountPrivateSign(uHash, vucTextSig), "Signing failed.");
|
||||
BOOST_CHECK_MESSAGE(naAccountPublic1.accountPublicVerify(uHash, vucTextSig), "Verify failed.");
|
||||
BOOST_CHECK_MESSAGE(!naAccountPublic0.accountPublicVerify(uHash, vucTextSig), "Anti-verify failed.");
|
||||
|
||||
// Check account encryption.
|
||||
std::vector<unsigned char> vucTextCipher
|
||||
= naAccountPrivate0.accountPrivateEncrypt(naAccountPublic1, vucTextSrc);
|
||||
std::vector<unsigned char> vucTextRecovered
|
||||
= naAccountPrivate1.accountPrivateDecrypt(naAccountPublic0, vucTextCipher);
|
||||
|
||||
BOOST_CHECK_MESSAGE(vucTextSrc == vucTextRecovered, "Encrypt-decrypt failed.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,190 +0,0 @@
|
||||
#ifndef __RIPPLE_ADDRESS__
|
||||
#define __RIPPLE_ADDRESS__
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
//
|
||||
// Used to hold addresses and parse and produce human formats.
|
||||
//
|
||||
// XXX This needs to be reworked to store data in uint160 and uint256. Conversion to CBase58Data should happen as needed.
|
||||
class RippleAddress : public CBase58Data
|
||||
{
|
||||
private:
|
||||
typedef enum {
|
||||
VER_NONE = 1,
|
||||
VER_NODE_PUBLIC = 28,
|
||||
VER_NODE_PRIVATE = 32,
|
||||
VER_ACCOUNT_ID = 0,
|
||||
VER_ACCOUNT_PUBLIC = 35,
|
||||
VER_ACCOUNT_PRIVATE = 34,
|
||||
VER_FAMILY_GENERATOR = 41,
|
||||
VER_FAMILY_SEED = 33,
|
||||
} VersionEncoding;
|
||||
|
||||
bool mIsValid;
|
||||
|
||||
public:
|
||||
RippleAddress();
|
||||
|
||||
// For public and private key, checks if they are legal.
|
||||
bool isValid() const { return mIsValid; }
|
||||
|
||||
void clear();
|
||||
bool isSet() const;
|
||||
|
||||
std::string humanAddressType() const;
|
||||
|
||||
//
|
||||
// Node Public - Also used for Validators
|
||||
//
|
||||
uint160 getNodeID() const;
|
||||
const std::vector<unsigned char>& getNodePublic() const;
|
||||
|
||||
std::string humanNodePublic() const;
|
||||
|
||||
bool setNodePublic(const std::string& strPublic);
|
||||
void setNodePublic(const std::vector<unsigned char>& vPublic);
|
||||
bool verifyNodePublic(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
|
||||
bool verifyNodePublic(const uint256& hash, const std::string& strSig) const;
|
||||
|
||||
static RippleAddress createNodePublic(const RippleAddress& naSeed);
|
||||
static RippleAddress createNodePublic(const std::vector<unsigned char>& vPublic);
|
||||
static RippleAddress createNodePublic(const std::string& strPublic);
|
||||
|
||||
//
|
||||
// Node Private
|
||||
//
|
||||
const std::vector<unsigned char>& getNodePrivateData() const;
|
||||
uint256 getNodePrivate() const;
|
||||
|
||||
std::string humanNodePrivate() const;
|
||||
|
||||
bool setNodePrivate(const std::string& strPrivate);
|
||||
void setNodePrivate(const std::vector<unsigned char>& vPrivate);
|
||||
void setNodePrivate(uint256 hash256);
|
||||
void signNodePrivate(const uint256& hash, std::vector<unsigned char>& vchSig) const;
|
||||
|
||||
static RippleAddress createNodePrivate(const RippleAddress& naSeed);
|
||||
|
||||
//
|
||||
// Accounts IDs
|
||||
//
|
||||
uint160 getAccountID() const;
|
||||
|
||||
std::string humanAccountID() const;
|
||||
|
||||
bool setAccountID(const std::string& strAccountID, const char* pAlphabet=0);
|
||||
void setAccountID(const uint160& hash160In);
|
||||
|
||||
static RippleAddress createAccountID(const std::string& strAccountID)
|
||||
{ RippleAddress na; na.setAccountID(strAccountID); return na; }
|
||||
|
||||
static RippleAddress createAccountID(const uint160& uiAccountID);
|
||||
|
||||
static std::string createHumanAccountID(const uint160& uiAccountID)
|
||||
{ return createAccountID(uiAccountID).humanAccountID(); }
|
||||
|
||||
static std::string createHumanAccountID(const std::vector<unsigned char>& vPrivate)
|
||||
{ return createAccountPrivate(vPrivate).humanAccountID(); }
|
||||
|
||||
//
|
||||
// Accounts Public
|
||||
//
|
||||
const std::vector<unsigned char>& getAccountPublic() const;
|
||||
|
||||
std::string humanAccountPublic() const;
|
||||
|
||||
bool setAccountPublic(const std::string& strPublic);
|
||||
void setAccountPublic(const std::vector<unsigned char>& vPublic);
|
||||
void setAccountPublic(const RippleAddress& generator, int seq);
|
||||
|
||||
bool accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const;
|
||||
|
||||
static RippleAddress createAccountPublic(const std::vector<unsigned char>& vPublic)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPublic(vPublic);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
static std::string createHumanAccountPublic(const std::vector<unsigned char>& vPublic) {
|
||||
return createAccountPublic(vPublic).humanAccountPublic();
|
||||
}
|
||||
|
||||
// Create a deterministic public key from a public generator.
|
||||
static RippleAddress createAccountPublic(const RippleAddress& naGenerator, int iSeq);
|
||||
|
||||
//
|
||||
// Accounts Private
|
||||
//
|
||||
uint256 getAccountPrivate() const;
|
||||
|
||||
std::string humanAccountPrivate() const;
|
||||
|
||||
bool setAccountPrivate(const std::string& strPrivate);
|
||||
void setAccountPrivate(const std::vector<unsigned char>& vPrivate);
|
||||
void setAccountPrivate(uint256 hash256);
|
||||
void setAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int seq);
|
||||
|
||||
bool accountPrivateSign(const uint256& uHash, std::vector<unsigned char>& vucSig) const;
|
||||
// bool accountPrivateVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const;
|
||||
|
||||
// Encrypt a message.
|
||||
std::vector<unsigned char> accountPrivateEncrypt(const RippleAddress& naPublicTo, const std::vector<unsigned char>& vucPlainText) const;
|
||||
|
||||
// Decrypt a message.
|
||||
std::vector<unsigned char> accountPrivateDecrypt(const RippleAddress& naPublicFrom, const std::vector<unsigned char>& vucCipherText) const;
|
||||
|
||||
static RippleAddress createAccountPrivate(const RippleAddress& naGenerator, const RippleAddress& naSeed, int iSeq);
|
||||
|
||||
static RippleAddress createAccountPrivate(const std::vector<unsigned char>& vPrivate)
|
||||
{
|
||||
RippleAddress naNew;
|
||||
|
||||
naNew.setAccountPrivate(vPrivate);
|
||||
|
||||
return naNew;
|
||||
}
|
||||
|
||||
static std::string createHumanAccountPrivate(const std::vector<unsigned char>& vPrivate) {
|
||||
return createAccountPrivate(vPrivate).humanAccountPrivate();
|
||||
}
|
||||
|
||||
//
|
||||
// Generators
|
||||
// Use to generate a master or regular family.
|
||||
//
|
||||
BIGNUM* getGeneratorBN() const; // DEPRECATED
|
||||
const std::vector<unsigned char>& getGenerator() const;
|
||||
|
||||
std::string humanGenerator() const;
|
||||
|
||||
bool setGenerator(const std::string& strGenerator);
|
||||
void setGenerator(const std::vector<unsigned char>& vPublic);
|
||||
// void setGenerator(const RippleAddress& seed);
|
||||
|
||||
// Create generator for making public deterministic keys.
|
||||
static RippleAddress createGeneratorPublic(const RippleAddress& naSeed);
|
||||
|
||||
//
|
||||
// Seeds
|
||||
// Clients must disallow reconizable entries from being seeds.
|
||||
uint128 getSeed() const;
|
||||
|
||||
std::string humanSeed() const;
|
||||
std::string humanSeed1751() const;
|
||||
|
||||
bool setSeed(const std::string& strSeed);
|
||||
int setSeed1751(const std::string& strHuman1751);
|
||||
bool setSeedGeneric(const std::string& strText);
|
||||
void setSeed(uint128 hash128);
|
||||
void setSeedRandom();
|
||||
|
||||
static RippleAddress createSeedRandom();
|
||||
static RippleAddress createSeedGeneric(const std::string& strText);
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "SHAMap.h"
|
||||
#include "Application.h"
|
||||
|
||||
@@ -38,20 +36,6 @@ std::size_t hash_value(const SHAMapNode& mn)
|
||||
return mn.getMHash();
|
||||
}
|
||||
|
||||
std::size_t hash_value(const uint256& u)
|
||||
{
|
||||
std::size_t seed = theApp->getNonceST();
|
||||
|
||||
return u.hash_combine(seed);
|
||||
}
|
||||
|
||||
std::size_t hash_value(const uint160& u)
|
||||
{
|
||||
std::size_t seed = theApp->getNonceST();
|
||||
|
||||
return u.hash_combine(seed);
|
||||
}
|
||||
|
||||
|
||||
SHAMap::SHAMap(SHAMapType t, uint32 seq) : mSeq(seq), mLedgerSeq(0), mState(smsModifying), mType(t)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "ScopedLock.h"
|
||||
#include "Serializer.h"
|
||||
#include "HashedObject.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "HashPrefixes.h"
|
||||
|
||||
SETUP_LOG (SHAMapNode)
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
// This is not really a header file, but it can be used as one with
|
||||
// appropriate #define statements.
|
||||
|
||||
// types (common)
|
||||
TYPE(Int16, UINT16, 1)
|
||||
TYPE(Int32, UINT32, 2)
|
||||
TYPE(Int64, UINT64, 3)
|
||||
TYPE(Hash128, HASH128, 4)
|
||||
TYPE(Hash256, HASH256, 5)
|
||||
TYPE(Amount, AMOUNT, 6)
|
||||
TYPE(VariableLength, VL, 7)
|
||||
TYPE(Account, ACCOUNT, 8)
|
||||
// 9-13 are reserved
|
||||
TYPE(Object, OBJECT, 14)
|
||||
TYPE(Array, ARRAY, 15)
|
||||
|
||||
// types (uncommon)
|
||||
TYPE(Int8, UINT8, 16)
|
||||
TYPE(Hash160, HASH160, 17)
|
||||
TYPE(PathSet, PATHSET, 18)
|
||||
TYPE(Vector256, VECTOR256, 19)
|
||||
|
||||
|
||||
|
||||
// 8-bit integers
|
||||
FIELD(CloseResolution, UINT8, 1)
|
||||
FIELD(TemplateEntryType, UINT8, 2)
|
||||
FIELD(TransactionResult, UINT8, 3)
|
||||
|
||||
// 16-bit integers
|
||||
FIELD(LedgerEntryType, UINT16, 1)
|
||||
FIELD(TransactionType, UINT16, 2)
|
||||
|
||||
// 32-bit integers (common)
|
||||
FIELD(Flags, UINT32, 2)
|
||||
FIELD(SourceTag, UINT32, 3)
|
||||
FIELD(Sequence, UINT32, 4)
|
||||
FIELD(PreviousTxnLgrSeq, UINT32, 5)
|
||||
FIELD(LedgerSequence, UINT32, 6)
|
||||
FIELD(CloseTime, UINT32, 7)
|
||||
FIELD(ParentCloseTime, UINT32, 8)
|
||||
FIELD(SigningTime, UINT32, 9)
|
||||
FIELD(Expiration, UINT32, 10)
|
||||
FIELD(TransferRate, UINT32, 11)
|
||||
FIELD(WalletSize, UINT32, 12)
|
||||
FIELD(OwnerCount, UINT32, 13)
|
||||
FIELD(DestinationTag, UINT32, 14)
|
||||
|
||||
// 32-bit integers (uncommon)
|
||||
FIELD(HighQualityIn, UINT32, 16)
|
||||
FIELD(HighQualityOut, UINT32, 17)
|
||||
FIELD(LowQualityIn, UINT32, 18)
|
||||
FIELD(LowQualityOut, UINT32, 19)
|
||||
FIELD(QualityIn, UINT32, 20)
|
||||
FIELD(QualityOut, UINT32, 21)
|
||||
FIELD(StampEscrow, UINT32, 22)
|
||||
FIELD(BondAmount, UINT32, 23)
|
||||
FIELD(LoadFee, UINT32, 24)
|
||||
FIELD(OfferSequence, UINT32, 25)
|
||||
FIELD(FirstLedgerSequence, UINT32, 26) // Deprecated: do not use
|
||||
FIELD(LastLedgerSequence, UINT32, 27)
|
||||
FIELD(TransactionIndex, UINT32, 28)
|
||||
FIELD(OperationLimit, UINT32, 29)
|
||||
FIELD(ReferenceFeeUnits, UINT32, 30)
|
||||
FIELD(ReserveBase, UINT32, 31)
|
||||
FIELD(ReserveIncrement, UINT32, 32)
|
||||
|
||||
// 64-bit integers
|
||||
FIELD(IndexNext, UINT64, 1)
|
||||
FIELD(IndexPrevious, UINT64, 2)
|
||||
FIELD(BookNode, UINT64, 3)
|
||||
FIELD(OwnerNode, UINT64, 4)
|
||||
FIELD(BaseFee, UINT64, 5)
|
||||
FIELD(ExchangeRate, UINT64, 6)
|
||||
FIELD(LowNode, UINT64, 7)
|
||||
FIELD(HighNode, UINT64, 8)
|
||||
|
||||
|
||||
// 128-bit
|
||||
FIELD(EmailHash, HASH128, 1)
|
||||
|
||||
// 256-bit (common)
|
||||
FIELD(LedgerHash, HASH256, 1)
|
||||
FIELD(ParentHash, HASH256, 2)
|
||||
FIELD(TransactionHash, HASH256, 3)
|
||||
FIELD(AccountHash, HASH256, 4)
|
||||
FIELD(PreviousTxnID, HASH256, 5)
|
||||
FIELD(LedgerIndex, HASH256, 6)
|
||||
FIELD(WalletLocator, HASH256, 7)
|
||||
FIELD(RootIndex, HASH256, 8)
|
||||
|
||||
// 256-bit (uncommon)
|
||||
FIELD(BookDirectory, HASH256, 16)
|
||||
FIELD(InvoiceID, HASH256, 17)
|
||||
FIELD(Nickname, HASH256, 18)
|
||||
FIELD(Feature, HASH256, 19)
|
||||
|
||||
// 160-bit (common)
|
||||
FIELD(TakerPaysCurrency, HASH160, 1)
|
||||
FIELD(TakerPaysIssuer, HASH160, 2)
|
||||
FIELD(TakerGetsCurrency, HASH160, 3)
|
||||
FIELD(TakerGetsIssuer, HASH160, 4)
|
||||
|
||||
// currency amount (common)
|
||||
FIELD(Amount, AMOUNT, 1)
|
||||
FIELD(Balance, AMOUNT, 2)
|
||||
FIELD(LimitAmount, AMOUNT, 3)
|
||||
FIELD(TakerPays, AMOUNT, 4)
|
||||
FIELD(TakerGets, AMOUNT, 5)
|
||||
FIELD(LowLimit, AMOUNT, 6)
|
||||
FIELD(HighLimit, AMOUNT, 7)
|
||||
FIELD(Fee, AMOUNT, 8)
|
||||
FIELD(SendMax, AMOUNT, 9)
|
||||
|
||||
// currency amount (uncommon)
|
||||
FIELD(MinimumOffer, AMOUNT, 16)
|
||||
FIELD(RippleEscrow, AMOUNT, 17)
|
||||
|
||||
// variable length
|
||||
FIELD(PublicKey, VL, 1)
|
||||
FIELD(MessageKey, VL, 2)
|
||||
FIELD(SigningPubKey, VL, 3)
|
||||
FIELD(TxnSignature, VL, 4)
|
||||
FIELD(Generator, VL, 5)
|
||||
FIELD(Signature, VL, 6)
|
||||
FIELD(Domain, VL, 7)
|
||||
FIELD(FundCode, VL, 8)
|
||||
FIELD(RemoveCode, VL, 9)
|
||||
FIELD(ExpireCode, VL, 10)
|
||||
FIELD(CreateCode, VL, 11)
|
||||
|
||||
// account
|
||||
FIELD(Account, ACCOUNT, 1)
|
||||
FIELD(Owner, ACCOUNT, 2)
|
||||
FIELD(Destination, ACCOUNT, 3)
|
||||
FIELD(Issuer, ACCOUNT, 4)
|
||||
FIELD(Target, ACCOUNT, 7)
|
||||
FIELD(RegularKey, ACCOUNT, 8)
|
||||
|
||||
// path set
|
||||
FIELD(Paths, PATHSET, 1)
|
||||
|
||||
// vector of 256-bit
|
||||
FIELD(Indexes, VECTOR256, 1)
|
||||
FIELD(Hashes, VECTOR256, 2)
|
||||
|
||||
// inner object
|
||||
// OBJECT/1 is reserved for end of object
|
||||
FIELD(TransactionMetaData, OBJECT, 2)
|
||||
FIELD(CreatedNode, OBJECT, 3)
|
||||
FIELD(DeletedNode, OBJECT, 4)
|
||||
FIELD(ModifiedNode, OBJECT, 5)
|
||||
FIELD(PreviousFields, OBJECT, 6)
|
||||
FIELD(FinalFields, OBJECT, 7)
|
||||
FIELD(NewFields, OBJECT, 8)
|
||||
FIELD(TemplateEntry, OBJECT, 9)
|
||||
|
||||
// array of objects
|
||||
// ARRAY/1 is reserved for end of array
|
||||
FIELD(SigningAccounts, ARRAY, 2)
|
||||
FIELD(TxnSignatures, ARRAY, 3)
|
||||
FIELD(Signatures, ARRAY, 4)
|
||||
FIELD(Template, ARRAY, 5)
|
||||
FIELD(Necessary, ARRAY, 6)
|
||||
FIELD(Sufficient, ARRAY, 7)
|
||||
FIELD(AffectedNodes, ARRAY, 8)
|
||||
FIELD(Features, ARRAY, 9)
|
||||
|
||||
// vim:ts=4
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "LedgerFormats.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
DEFINE_INSTANCE(SerializedLedgerEntry);
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "TransactionFormats.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
#define TXN_SQL_NEW 'N'
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "FieldNames.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
// CAUTION: Do not create a vector (or similar container) of any object derived from
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define __VALIDATION__
|
||||
|
||||
#include "SerializedObject.h"
|
||||
#include "RippleAddress.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
DEFINE_INSTANCE(SerializedValidation);
|
||||
|
||||
@@ -1,613 +0,0 @@
|
||||
|
||||
SETUP_LOG (Serializer)
|
||||
|
||||
int Serializer::addZeros(size_t uBytes)
|
||||
{
|
||||
int ret = mData.size();
|
||||
|
||||
while (uBytes--)
|
||||
mData.push_back(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add16(uint16 i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(static_cast<unsigned char>(i >> 8));
|
||||
mData.push_back(static_cast<unsigned char>(i & 0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add32(uint32 i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(static_cast<unsigned char>(i >> 24));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>(i & 0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add64(uint64 i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(static_cast<unsigned char>(i >> 56));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 48) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 40) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 32) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>(i & 0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add128(const uint128& i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), i.begin(), i.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add160(const uint160& i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), i.begin(), i.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::add256(const uint256& i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), i.begin(), i.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addRaw(const std::vector<unsigned char> &vector)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), vector.begin(), vector.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addRaw(const Serializer &s)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), s.begin(), s.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addRaw(const void *ptr, int len)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.insert(mData.end(), (const char *) ptr, ((const char *)ptr)+len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::get16(uint16& o, int offset) const
|
||||
{
|
||||
if ((offset + 2) > mData.size()) return false;
|
||||
const unsigned char *ptr = &mData[offset];
|
||||
o = *ptr++; o <<= 8; o |= *ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::get32(uint32& o, int offset) const
|
||||
{
|
||||
if ((offset + 4) > mData.size()) return false;
|
||||
const unsigned char *ptr = &mData[offset];
|
||||
o = *ptr++;
|
||||
o <<= 8; o |= *ptr++;
|
||||
o <<= 8; o |= *ptr++;
|
||||
o <<= 8; o |= *ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::get64(uint64& o, int offset) const
|
||||
{
|
||||
if ((offset + 8) > mData.size()) return false;
|
||||
const unsigned char *ptr = &mData[offset];
|
||||
o = *ptr++;
|
||||
o <<= 8; o |= *ptr++; o <<= 8; o |= *ptr++;
|
||||
o <<= 8; o |= *ptr++; o <<= 8; o |= *ptr++;
|
||||
o <<= 8; o |= *ptr++; o <<= 8; o |= *ptr++;
|
||||
o <<= 8; o |= *ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::get128(uint128& o, int offset) const
|
||||
{
|
||||
if ((offset + (128 / 8)) > mData.size()) return false;
|
||||
memcpy(o.begin(), &(mData.front()) + offset, (128 / 8));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::get160(uint160& o, int offset) const
|
||||
{
|
||||
if ((offset + (160 / 8)) > mData.size()) return false;
|
||||
memcpy(o.begin(), &(mData.front()) + offset, (160 / 8));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::get256(uint256& o, int offset) const
|
||||
{
|
||||
if ((offset + (256 / 8)) > mData.size()) return false;
|
||||
memcpy(o.begin(), &(mData.front()) + offset, (256 / 8));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint256 Serializer::get256(int offset) const
|
||||
{
|
||||
uint256 ret;
|
||||
if ((offset + (256 / 8)) > mData.size()) return ret;
|
||||
memcpy(ret.begin(), &(mData.front()) + offset, (256 / 8));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addFieldID(int type, int name)
|
||||
{
|
||||
int ret = mData.size();
|
||||
assert((type > 0) && (type < 256) && (name > 0) && (name < 256));
|
||||
if (type < 16)
|
||||
{
|
||||
if (name < 16) // common type, common name
|
||||
mData.push_back(static_cast<unsigned char>((type << 4) | name));
|
||||
else
|
||||
{ // common type, uncommon name
|
||||
mData.push_back(static_cast<unsigned char>(type << 4));
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
}
|
||||
}
|
||||
else if (name < 16)
|
||||
{ // uncommon type, common name
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
mData.push_back(static_cast<unsigned char>(type));
|
||||
}
|
||||
else
|
||||
{ // uncommon type, uncommon name
|
||||
mData.push_back(static_cast<unsigned char>(0));
|
||||
mData.push_back(static_cast<unsigned char>(type));
|
||||
mData.push_back(static_cast<unsigned char>(name));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::getFieldID(int& type, int& name, int offset) const
|
||||
{
|
||||
if (!get8(type, offset))
|
||||
{
|
||||
WriteLog (lsWARNING, Serializer) << "gFID: unable to get type";
|
||||
return false;
|
||||
}
|
||||
name = type & 15;
|
||||
type >>= 4;
|
||||
if (type == 0)
|
||||
{ // uncommon type
|
||||
if (!get8(type, ++offset))
|
||||
return false;
|
||||
if ((type == 0) || (type < 16))
|
||||
{
|
||||
WriteLog (lsWARNING, Serializer) << "gFID: uncommon type out of range " << type;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (name == 0)
|
||||
{ // uncommon name
|
||||
if (!get8(name, ++offset))
|
||||
return false;
|
||||
if ((name == 0) || (name < 16))
|
||||
{
|
||||
WriteLog (lsWARNING, Serializer) << "gFID: uncommon name out of range " << name;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Serializer::add8(unsigned char byte)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(byte);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::get8(int& byte, int offset) const
|
||||
{
|
||||
if (offset >= mData.size()) return false;
|
||||
byte = mData[offset];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::chop(int bytes)
|
||||
{
|
||||
if (bytes > mData.size()) return false;
|
||||
mData.resize(mData.size() - bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Serializer::removeLastByte()
|
||||
{
|
||||
int size = mData.size()-1;
|
||||
if (size < 0)
|
||||
{
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
int ret = mData[size];
|
||||
mData.resize(size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::getRaw(std::vector<unsigned char>& o, int offset, int length) const
|
||||
{
|
||||
if ((offset + length) > mData.size()) return false;
|
||||
o.assign(mData.begin() + offset, mData.begin() + offset + length);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Serializer::getRaw(int offset, int length) const
|
||||
{
|
||||
std::vector<unsigned char> o;
|
||||
if ((offset + length) > mData.size()) return o;
|
||||
o.assign(mData.begin() + offset, mData.begin() + offset + length);
|
||||
return o;
|
||||
}
|
||||
|
||||
uint160 Serializer::getRIPEMD160(int size) const
|
||||
{
|
||||
uint160 ret;
|
||||
if ((size < 0) || (size>mData.size())) size = mData.size();
|
||||
RIPEMD160(&(mData.front()), size, (unsigned char *) &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint256 Serializer::getSHA256(int size) const
|
||||
{
|
||||
uint256 ret;
|
||||
if ((size < 0) || (size > mData.size())) size = mData.size();
|
||||
SHA256(&(mData.front()), size, (unsigned char *) &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint256 Serializer::getSHA512Half(int size) const
|
||||
{
|
||||
return getSHA512Half(mData, size);
|
||||
}
|
||||
|
||||
uint256 Serializer::getSHA512Half(const std::vector<unsigned char>& data, int size)
|
||||
{
|
||||
uint256 j[2];
|
||||
if ((size < 0) || (size > data.size())) size = data.size();
|
||||
SHA512(&(data.front()), size, (unsigned char *) j);
|
||||
return j[0];
|
||||
}
|
||||
|
||||
uint256 Serializer::getSHA512Half(const unsigned char *data, int len)
|
||||
{
|
||||
uint256 j[2];
|
||||
SHA512(data, len, (unsigned char *) j);
|
||||
return j[0];
|
||||
}
|
||||
|
||||
uint256 Serializer::getSHA512Half(const std::string& strData)
|
||||
{
|
||||
return getSHA512Half(reinterpret_cast<const unsigned char*>(strData.data()), strData.size());
|
||||
}
|
||||
|
||||
uint256 Serializer::getPrefixHash(uint32 prefix, const unsigned char *data, int len)
|
||||
{
|
||||
char be_prefix[4];
|
||||
be_prefix[0] = static_cast<unsigned char>(prefix >> 24);
|
||||
be_prefix[1] = static_cast<unsigned char>((prefix >> 16) & 0xff);
|
||||
be_prefix[2] = static_cast<unsigned char>((prefix >> 8) & 0xff);
|
||||
be_prefix[3] = static_cast<unsigned char>(prefix & 0xff);
|
||||
|
||||
uint256 j[2];
|
||||
SHA512_CTX ctx;
|
||||
SHA512_Init(&ctx);
|
||||
SHA512_Update(&ctx, &be_prefix[0], 4);
|
||||
SHA512_Update(&ctx, data, len);
|
||||
SHA512_Final(reinterpret_cast<unsigned char *>(&j[0]), &ctx);
|
||||
|
||||
return j[0];
|
||||
}
|
||||
|
||||
bool Serializer::checkSignature(int pubkeyOffset, int signatureOffset) const
|
||||
{
|
||||
std::vector<unsigned char> pubkey, signature;
|
||||
if (!getRaw(pubkey, pubkeyOffset, 65)) return false;
|
||||
if (!getRaw(signature, signatureOffset, 72)) return false;
|
||||
|
||||
CKey pubCKey;
|
||||
if (!pubCKey.SetPubKey(pubkey)) return false;
|
||||
return pubCKey.Verify(getSHA512Half(signatureOffset), signature);
|
||||
}
|
||||
|
||||
bool Serializer::checkSignature(const std::vector<unsigned char> &signature, CKey& key) const
|
||||
{
|
||||
return key.Verify(getSHA512Half(), signature);
|
||||
}
|
||||
|
||||
bool Serializer::makeSignature(std::vector<unsigned char> &signature, CKey& key) const
|
||||
{
|
||||
return key.Sign(getSHA512Half(), signature);
|
||||
}
|
||||
|
||||
bool Serializer::addSignature(CKey& key)
|
||||
{
|
||||
std::vector<unsigned char> signature;
|
||||
if (!key.Sign(getSHA512Half(), signature)) return false;
|
||||
assert(signature.size() == 72);
|
||||
addRaw(signature);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Serializer::addVL(const std::vector<unsigned char>& vector)
|
||||
{
|
||||
int ret = addRaw(encodeVL(vector.size()));
|
||||
addRaw(vector);
|
||||
assert(mData.size() == (ret + vector.size() + encodeLengthLength(vector.size())));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addVL(const void *ptr, int len)
|
||||
{
|
||||
int ret = addRaw(encodeVL(len));
|
||||
if (len)
|
||||
addRaw(ptr, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Serializer::addVL(const std::string& string)
|
||||
{
|
||||
int ret = addRaw(string.size());
|
||||
if (!string.empty())
|
||||
addRaw(string.data(), string.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Serializer::getVL(std::vector<unsigned char>& objectVL, int offset, int& length) const
|
||||
{
|
||||
int b1;
|
||||
if (!get8(b1, offset++)) return false;
|
||||
|
||||
int datLen, lenLen = decodeLengthLength(b1);
|
||||
try
|
||||
{
|
||||
if (lenLen == 1)
|
||||
datLen = decodeVLLength(b1);
|
||||
else if (lenLen == 2)
|
||||
{
|
||||
int b2;
|
||||
if (!get8(b2, offset++)) return false;
|
||||
datLen = decodeVLLength(b1, b2);
|
||||
}
|
||||
else if (lenLen == 3)
|
||||
{
|
||||
int b2, b3;
|
||||
if (!get8(b2, offset++)) return false;
|
||||
if (!get8(b3, offset++)) return false;
|
||||
datLen = decodeVLLength(b1, b2, b3);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
length = lenLen + datLen;
|
||||
return getRaw(objectVL, offset, datLen);
|
||||
}
|
||||
|
||||
bool Serializer::getVLLength(int& length, int offset) const
|
||||
{
|
||||
int b1;
|
||||
if (!get8(b1, offset++)) return false;
|
||||
|
||||
int lenLen = decodeLengthLength(b1);
|
||||
try
|
||||
{
|
||||
if (lenLen == 1)
|
||||
length = decodeVLLength(b1);
|
||||
else if (lenLen == 2)
|
||||
{
|
||||
int b2;
|
||||
if (!get8(b2, offset++)) return false;
|
||||
length = decodeVLLength(b1, b2);
|
||||
}
|
||||
else if (lenLen == 3)
|
||||
{
|
||||
int b2, b3;
|
||||
if (!get8(b2, offset++)) return false;
|
||||
if (!get8(b3, offset++)) return false;
|
||||
length = decodeVLLength(b1, b2, b3);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Serializer::encodeVL(int length)
|
||||
{
|
||||
unsigned char lenBytes[4];
|
||||
if (length <= 192)
|
||||
{
|
||||
lenBytes[0] = static_cast<unsigned char>(length);
|
||||
return std::vector<unsigned char>(&lenBytes[0], &lenBytes[1]);
|
||||
}
|
||||
else if (length <= 12480)
|
||||
{
|
||||
length -= 193;
|
||||
lenBytes[0] = 193 + static_cast<unsigned char>(length >> 8);
|
||||
lenBytes[1] = static_cast<unsigned char>(length & 0xff);
|
||||
return std::vector<unsigned char>(&lenBytes[0], &lenBytes[2]);
|
||||
}
|
||||
else if (length <= 918744)
|
||||
{
|
||||
length -= 12481;
|
||||
lenBytes[0] = 241 + static_cast<unsigned char>(length >> 16);
|
||||
lenBytes[1] = static_cast<unsigned char>((length >> 8) & 0xff);
|
||||
lenBytes[2] = static_cast<unsigned char>(length & 0xff);
|
||||
return std::vector<unsigned char>(&lenBytes[0], &lenBytes[3]);
|
||||
}
|
||||
else throw std::overflow_error("lenlen");
|
||||
}
|
||||
|
||||
int Serializer::encodeLengthLength(int length)
|
||||
{
|
||||
if (length < 0) throw std::overflow_error("len<0");
|
||||
if (length <= 192) return 1;
|
||||
if (length <= 12480) return 2;
|
||||
if (length <= 918744) return 3;
|
||||
throw std::overflow_error("len>918744");
|
||||
}
|
||||
|
||||
int Serializer::decodeLengthLength(int b1)
|
||||
{
|
||||
if (b1 < 0) throw std::overflow_error("b1<0");
|
||||
if (b1 <= 192) return 1;
|
||||
if (b1 <= 240) return 2;
|
||||
if (b1 <= 254) return 3;
|
||||
throw std::overflow_error("b1>254");
|
||||
}
|
||||
|
||||
int Serializer::decodeVLLength(int b1)
|
||||
{
|
||||
if (b1 < 0) throw std::overflow_error("b1<0");
|
||||
if (b1 > 254) throw std::overflow_error("b1>254");
|
||||
return b1;
|
||||
}
|
||||
|
||||
int Serializer::decodeVLLength(int b1, int b2)
|
||||
{
|
||||
if (b1 < 193) throw std::overflow_error("b1<193");
|
||||
if (b1 > 240) throw std::overflow_error("b1>240");
|
||||
return 193 + (b1 - 193) * 256 + b2;
|
||||
}
|
||||
|
||||
int Serializer::decodeVLLength(int b1, int b2, int b3)
|
||||
{
|
||||
if (b1 < 241) throw std::overflow_error("b1<241");
|
||||
if (b1 > 254) throw std::overflow_error("b1>254");
|
||||
return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
|
||||
}
|
||||
|
||||
void Serializer::TestSerializer()
|
||||
{
|
||||
Serializer s(64);
|
||||
}
|
||||
|
||||
int SerializerIterator::getBytesLeft()
|
||||
{
|
||||
return mSerializer.size() - mPos;
|
||||
}
|
||||
|
||||
void SerializerIterator::getFieldID(int& type, int& field)
|
||||
{
|
||||
if (!mSerializer.getFieldID(type, field, mPos))
|
||||
throw std::runtime_error("invalid serializer getFieldID");
|
||||
++mPos;
|
||||
if (type >= 16)
|
||||
++mPos;
|
||||
if (field >= 16)
|
||||
++mPos;
|
||||
}
|
||||
|
||||
unsigned char SerializerIterator::get8()
|
||||
{
|
||||
int val;
|
||||
if (!mSerializer.get8(val, mPos)) throw std::runtime_error("invalid serializer get8");
|
||||
++mPos;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16 SerializerIterator::get16()
|
||||
{
|
||||
uint16 val;
|
||||
if (!mSerializer.get16(val, mPos)) throw std::runtime_error("invalid serializer get16");
|
||||
mPos += 16 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32 SerializerIterator::get32()
|
||||
{
|
||||
uint32 val;
|
||||
if (!mSerializer.get32(val, mPos)) throw std::runtime_error("invalid serializer get32");
|
||||
mPos += 32 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint64 SerializerIterator::get64()
|
||||
{
|
||||
uint64 val;
|
||||
if (!mSerializer.get64(val, mPos)) throw std::runtime_error("invalid serializer get64");
|
||||
mPos += 64 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint128 SerializerIterator::get128()
|
||||
{
|
||||
uint128 val;
|
||||
if (!mSerializer.get128(val, mPos)) throw std::runtime_error("invalid serializer get128");
|
||||
mPos += 128 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint160 SerializerIterator::get160()
|
||||
{
|
||||
uint160 val;
|
||||
if (!mSerializer.get160(val, mPos)) throw std::runtime_error("invalid serializer get160");
|
||||
mPos += 160 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint256 SerializerIterator::get256()
|
||||
{
|
||||
uint256 val;
|
||||
if (!mSerializer.get256(val, mPos)) throw std::runtime_error("invalid serializer get256");
|
||||
mPos += 256 / 8;
|
||||
return val;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> SerializerIterator::getVL()
|
||||
{
|
||||
int length;
|
||||
std::vector<unsigned char> vl;
|
||||
if (!mSerializer.getVL(vl, mPos, length)) throw std::runtime_error("invalid serializer getVL");
|
||||
mPos += length;
|
||||
return vl;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> SerializerIterator::getRaw(int iLength)
|
||||
{
|
||||
int iPos = mPos;
|
||||
mPos += iLength;
|
||||
|
||||
return mSerializer.getRaw(iPos, iLength);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Serializer_suite)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( Serializer_PrefixHash_test )
|
||||
{
|
||||
Serializer s1;
|
||||
s1.add32(3);
|
||||
s1.add256(uint256());
|
||||
|
||||
Serializer s2;
|
||||
s2.add32(0x12345600);
|
||||
s2.addRaw(s1.peekData());
|
||||
|
||||
if (s1.getPrefixHash(0x12345600) != s2.getSHA512Half())
|
||||
BOOST_FAIL("Prefix hash does not work");
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,168 +0,0 @@
|
||||
#ifndef __SERIALIZER__
|
||||
#define __SERIALIZER__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "key.h"
|
||||
#include "FieldNames.h"
|
||||
|
||||
class Serializer
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<Serializer> pointer;
|
||||
|
||||
protected:
|
||||
std::vector<unsigned char> mData;
|
||||
|
||||
public:
|
||||
Serializer(int n = 256) { mData.reserve(n); }
|
||||
Serializer(const std::vector<unsigned char> &data) : mData(data) { ; }
|
||||
Serializer(const std::string& data) : mData(data.data(), (data.data()) + data.size()) { ; }
|
||||
Serializer(std::vector<unsigned char>::iterator begin, std::vector<unsigned char>::iterator end) :
|
||||
mData(begin, end) { ; }
|
||||
Serializer(std::vector<unsigned char>::const_iterator begin, std::vector<unsigned char>::const_iterator end) :
|
||||
mData(begin, end) { ; }
|
||||
|
||||
// assemble functions
|
||||
int add8(unsigned char byte);
|
||||
int add16(uint16);
|
||||
int add32(uint32); // ledger indexes, account sequence, timestamps
|
||||
int add64(uint64); // native currency amounts
|
||||
int add128(const uint128&); // private key generators
|
||||
int add160(const uint160&); // account names, hankos
|
||||
int add256(const uint256&); // transaction and ledger hashes
|
||||
int addRaw(const std::vector<unsigned char> &vector);
|
||||
int addRaw(const void *ptr, int len);
|
||||
int addRaw(const Serializer& s);
|
||||
int addZeros(size_t uBytes);
|
||||
|
||||
int addVL(const std::vector<unsigned char> &vector);
|
||||
int addVL(const std::string& string);
|
||||
int addVL(const void *ptr, int len);
|
||||
|
||||
// disassemble functions
|
||||
bool get8(int&, int offset) const;
|
||||
bool get8(unsigned char&, int offset) const;
|
||||
bool get16(uint16&, int offset) const;
|
||||
bool get32(uint32&, int offset) const;
|
||||
bool get64(uint64&, int offset) const;
|
||||
bool get128(uint128&, int offset) const;
|
||||
bool get160(uint160&, int offset) const;
|
||||
bool get256(uint256&, int offset) const;
|
||||
uint256 get256(int offset) const;
|
||||
bool getRaw(std::vector<unsigned char>&, int offset, int length) const;
|
||||
std::vector<unsigned char> getRaw(int offset, int length) const;
|
||||
|
||||
bool getVL(std::vector<unsigned char>& objectVL, int offset, int& length) const;
|
||||
bool getVLLength(int& length, int offset) const;
|
||||
|
||||
bool getFieldID(int& type, int& name, int offset) const;
|
||||
int addFieldID(int type, int name);
|
||||
int addFieldID(SerializedTypeID type, int name) { return addFieldID(static_cast<int>(type), name); }
|
||||
|
||||
// normal hash functions
|
||||
uint160 getRIPEMD160(int size=-1) const;
|
||||
uint256 getSHA256(int size=-1) const;
|
||||
uint256 getSHA512Half(int size=-1) const;
|
||||
static uint256 getSHA512Half(const std::vector<unsigned char>& data, int size=-1);
|
||||
static uint256 getSHA512Half(const unsigned char *data, int len);
|
||||
static uint256 getSHA512Half(const std::string& strData);
|
||||
|
||||
// prefix hash functions
|
||||
static uint256 getPrefixHash(uint32 prefix, const unsigned char *data, int len);
|
||||
uint256 getPrefixHash(uint32 prefix) const
|
||||
{ return getPrefixHash(prefix, &(mData.front()), mData.size()); }
|
||||
static uint256 getPrefixHash(uint32 prefix, const std::vector<unsigned char>& data)
|
||||
{ return getPrefixHash(prefix, &(data.front()), data.size()); }
|
||||
static uint256 getPrefixHash(uint32 prefix, const std::string& strData)
|
||||
{ return getPrefixHash(prefix, reinterpret_cast<const unsigned char *>(strData.data()), strData.size()); }
|
||||
|
||||
// totality functions
|
||||
const std::vector<unsigned char>& peekData() const { return mData; }
|
||||
std::vector<unsigned char> getData() const { return mData; }
|
||||
std::vector<unsigned char>& modData() { return mData; }
|
||||
int getCapacity() const { return mData.capacity(); }
|
||||
int getDataLength() const { return mData.size(); }
|
||||
const void* getDataPtr() const { return &mData.front(); }
|
||||
void* getDataPtr() { return &mData.front(); }
|
||||
int getLength() const { return mData.size(); }
|
||||
std::string getString() const { return std::string(static_cast<const char *>(getDataPtr()), size()); }
|
||||
void secureErase() { memset(&(mData.front()), 0, mData.size()); erase(); }
|
||||
void erase() { mData.clear(); }
|
||||
int removeLastByte();
|
||||
bool chop(int num);
|
||||
|
||||
// vector-like functions
|
||||
std::vector<unsigned char>::iterator begin() { return mData.begin(); }
|
||||
std::vector<unsigned char>::iterator end() { return mData.end(); }
|
||||
std::vector<unsigned char>::const_iterator begin() const { return mData.begin(); }
|
||||
std::vector<unsigned char>::const_iterator end() const { return mData.end(); }
|
||||
std::vector<unsigned char>::size_type size() const { return mData.size(); }
|
||||
void reserve(size_t n) { mData.reserve(n); }
|
||||
void resize(size_t n) { mData.resize(n); }
|
||||
size_t capacity() const { return mData.capacity(); }
|
||||
|
||||
bool operator==(const std::vector<unsigned char>& v) { return v == mData; }
|
||||
bool operator!=(const std::vector<unsigned char>& v) { return v != mData; }
|
||||
bool operator==(const Serializer& v) { return v.mData == mData; }
|
||||
bool operator!=(const Serializer& v) { return v.mData != mData; }
|
||||
|
||||
// signature functions
|
||||
bool checkSignature(int pubkeyOffset, int signatureOffset) const;
|
||||
bool checkSignature(const std::vector<unsigned char>& signature, CKey& rkey) const;
|
||||
bool makeSignature(std::vector<unsigned char>& signature, CKey& rkey) const;
|
||||
bool addSignature(CKey& rkey);
|
||||
|
||||
// low-level VL length encode/decode functions
|
||||
static std::vector<unsigned char> encodeVL(int length);
|
||||
static int lengthVL(int length) { return length + encodeLengthLength(length); }
|
||||
static int encodeLengthLength(int length); // length to encode length
|
||||
static int decodeLengthLength(int b1);
|
||||
static int decodeVLLength(int b1);
|
||||
static int decodeVLLength(int b1, int b2);
|
||||
static int decodeVLLength(int b1, int b2, int b3);
|
||||
|
||||
static void TestSerializer();
|
||||
};
|
||||
|
||||
class SerializerIterator
|
||||
{
|
||||
protected:
|
||||
const Serializer& mSerializer;
|
||||
int mPos;
|
||||
|
||||
public:
|
||||
|
||||
// Reference is not const because we don't want to bind to a temporary
|
||||
SerializerIterator(Serializer& s) : mSerializer(s), mPos(0) { ; }
|
||||
|
||||
const Serializer& operator*(void) { return mSerializer; }
|
||||
void reset(void) { mPos = 0; }
|
||||
void setPos(int p) { mPos = p; }
|
||||
|
||||
int getPos(void) { return mPos; }
|
||||
bool empty() { return mPos == mSerializer.getLength(); }
|
||||
int getBytesLeft();
|
||||
|
||||
// get functions throw on error
|
||||
unsigned char get8();
|
||||
uint16 get16();
|
||||
uint32 get32();
|
||||
uint64 get64();
|
||||
uint128 get128();
|
||||
uint160 get160();
|
||||
uint256 get256();
|
||||
|
||||
void getFieldID(int& type, int& field);
|
||||
|
||||
std::vector<unsigned char> getRaw(int iLength);
|
||||
|
||||
std::vector<unsigned char> getVL();
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -11,9 +11,7 @@
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "key.h"
|
||||
#include "ripple.pb.h"
|
||||
#include "Serializer.h"
|
||||
#include "SHAMap.h"
|
||||
#include "SerializedTransaction.h"
|
||||
#include "TransactionErr.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "SerializedTypes.h"
|
||||
#include "SerializedObject.h"
|
||||
#include "SerializedLedger.h"
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Application.h"
|
||||
#include "HttpsClient.h"
|
||||
#include "ParseSection.h"
|
||||
#include "Serializer.h"
|
||||
|
||||
#define VALIDATORS_FETCH_SECONDS 30
|
||||
#define VALIDATORS_FILE_BYTES_MAX (50 << 10)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
#include "Config.h"
|
||||
#include "HttpsClient.h"
|
||||
#include "ParseSection.h"
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "openssl/ec.h"
|
||||
#include "openssl/dh.h"
|
||||
|
||||
#include "Serializer.h"
|
||||
|
||||
class Ledger;
|
||||
|
||||
class Wallet
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin Developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
//
|
||||
// Why base-58 instead of standard base-64 encoding?
|
||||
// - Don't want 0OIl characters that look the same in some fonts and
|
||||
// could be used to create visually identical looking account numbers.
|
||||
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
// - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
#ifndef BITCOIN_BASE58_H
|
||||
#define BITCOIN_BASE58_H
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include "bignum.h"
|
||||
#include "BitcoinUtil.h"
|
||||
|
||||
extern const char* ALPHABET;
|
||||
|
||||
inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn0 = 0;
|
||||
|
||||
// Convert big endian data to little endian
|
||||
// Extra zero at the end make sure bignum will interpret as a positive number
|
||||
std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
|
||||
std::reverse_copy(pbegin, pend, vchTmp.begin());
|
||||
|
||||
// Convert little endian data to bignum
|
||||
CBigNum bn(vchTmp);
|
||||
|
||||
// Convert bignum to std::string
|
||||
std::string str;
|
||||
// Expected size increase from base58 conversion is approximately 137%
|
||||
// use 138% to be safe
|
||||
str.reserve((pend - pbegin) * 138 / 100 + 1);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
while (bn > bn0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
|
||||
throw bignum_error("EncodeBase58 : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint();
|
||||
str += ALPHABET[c];
|
||||
}
|
||||
|
||||
// Leading zeroes encoded as base58 zeros
|
||||
for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
|
||||
str += ALPHABET[0];
|
||||
|
||||
// Convert little endian std::string to big endian
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
return EncodeBase58(&vch[0], &vch[0] + vch.size());
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet, const char* pAlphabet=0)
|
||||
{
|
||||
const char* pAlpha = pAlphabet ? pAlphabet : ALPHABET;
|
||||
|
||||
CAutoBN_CTX pctx;
|
||||
vchRet.clear();
|
||||
CBigNum bn58 = 58;
|
||||
CBigNum bn = 0;
|
||||
CBigNum bnChar;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// Convert big endian string to bignum
|
||||
for (const char* p = psz; *p; p++)
|
||||
{
|
||||
const char* p1 = strchr(pAlpha, *p);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
bnChar.setuint(p1 - pAlpha);
|
||||
if (!BN_mul(&bn, &bn, &bn58, pctx))
|
||||
throw bignum_error("DecodeBase58 : BN_mul failed");
|
||||
bn += bnChar;
|
||||
}
|
||||
|
||||
// Get bignum as little endian data
|
||||
std::vector<unsigned char> vchTmp = bn.getvch();
|
||||
|
||||
// Trim off sign byte if present
|
||||
if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
|
||||
vchTmp.erase(vchTmp.end()-1);
|
||||
|
||||
// Restore leading zeros
|
||||
int nLeadingZeros = 0;
|
||||
for (const char* p = psz; *p == pAlpha[0]; p++)
|
||||
nLeadingZeros++;
|
||||
vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
|
||||
|
||||
// Convert little endian data to big endian
|
||||
std::reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
|
||||
{
|
||||
return DecodeBase58(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
|
||||
{
|
||||
// add 4-byte hash check to the end
|
||||
std::vector<unsigned char> vch(vchIn);
|
||||
uint256 hash = SHA256Hash(vch.begin(), vch.end());
|
||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
||||
return EncodeBase58(vch);
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet, const char* pAlphabet=0)
|
||||
{
|
||||
if (!DecodeBase58(psz, vchRet, pAlphabet))
|
||||
return false;
|
||||
if (vchRet.size() < 4)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
uint256 hash = SHA256Hash(vchRet.begin(), vchRet.end()-4);
|
||||
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
|
||||
{
|
||||
vchRet.clear();
|
||||
return false;
|
||||
}
|
||||
vchRet.resize(vchRet.size()-4);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet, const char* pAlphabet)
|
||||
{
|
||||
return DecodeBase58Check(str.c_str(), vchRet, pAlphabet);
|
||||
}
|
||||
|
||||
|
||||
class CBase58Data
|
||||
{
|
||||
protected:
|
||||
unsigned char nVersion;
|
||||
std::vector<unsigned char> vchData;
|
||||
|
||||
CBase58Data() : nVersion(1)
|
||||
{ ; }
|
||||
|
||||
~CBase58Data()
|
||||
{
|
||||
if (!vchData.empty())
|
||||
memset(&vchData[0], 0, vchData.size());
|
||||
}
|
||||
|
||||
void SetData(int nVersionIn, const std::vector<unsigned char>& vchDataIn)
|
||||
{
|
||||
nVersion = nVersionIn;
|
||||
vchData = vchDataIn;
|
||||
}
|
||||
|
||||
void SetData(int nVersionIn, const void* pdata, size_t nSize)
|
||||
{
|
||||
nVersion = nVersionIn;
|
||||
vchData.resize(nSize);
|
||||
if (nSize)
|
||||
memcpy(&vchData[0], pdata, nSize);
|
||||
}
|
||||
|
||||
void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
|
||||
{
|
||||
SetData(nVersionIn, (void*)pbegin, pend - pbegin);
|
||||
}
|
||||
|
||||
public:
|
||||
bool SetString(const char* psz, unsigned char version, const char* pAlphabet = 0)
|
||||
{
|
||||
std::vector<unsigned char> vchTemp;
|
||||
DecodeBase58Check(psz, vchTemp, pAlphabet);
|
||||
if (vchTemp.empty() || vchTemp[0] != version)
|
||||
{
|
||||
vchData.clear();
|
||||
nVersion = 1;
|
||||
return false;
|
||||
}
|
||||
nVersion = vchTemp[0];
|
||||
vchData.resize(vchTemp.size() - 1);
|
||||
if (!vchData.empty())
|
||||
memcpy(&vchData[0], &vchTemp[1], vchData.size());
|
||||
memset(&vchTemp[0], 0, vchTemp.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetString(const std::string& str, unsigned char version)
|
||||
{
|
||||
return SetString(str.c_str(), version);
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
std::vector<unsigned char> vch(1, nVersion);
|
||||
|
||||
vch.insert(vch.end(), vchData.begin(), vchData.end());
|
||||
|
||||
return EncodeBase58Check(vch);
|
||||
}
|
||||
|
||||
int CompareTo(const CBase58Data& b58) const
|
||||
{
|
||||
if (nVersion < b58.nVersion) return -1;
|
||||
if (nVersion > b58.nVersion) return 1;
|
||||
if (vchData < b58.vchData) return -1;
|
||||
if (vchData > b58.vchData) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
|
||||
bool operator!=(const CBase58Data& b58) const { return CompareTo(b58) != 0; }
|
||||
bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
|
||||
bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
|
||||
friend std::size_t hash_value(const CBase58Data& b58);
|
||||
};
|
||||
|
||||
extern std::size_t hash_value(const CBase58Data& b58);
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -1,536 +0,0 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_BIGNUM_H
|
||||
#define BITCOIN_BIGNUM_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "BitcoinUtil.h"
|
||||
|
||||
class bignum_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CAutoBN_CTX
|
||||
{
|
||||
private:
|
||||
CAutoBN_CTX(const CAutoBN_CTX&); // no implementation
|
||||
CAutoBN_CTX& operator=(const CAutoBN_CTX&); // no implementation
|
||||
|
||||
protected:
|
||||
BN_CTX* pctx;
|
||||
CAutoBN_CTX& operator=(BN_CTX* pnew) { pctx = pnew; return *this; }
|
||||
|
||||
public:
|
||||
CAutoBN_CTX()
|
||||
{
|
||||
pctx = BN_CTX_new();
|
||||
if (pctx == NULL)
|
||||
throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
|
||||
}
|
||||
|
||||
~CAutoBN_CTX()
|
||||
{
|
||||
if (pctx != NULL)
|
||||
BN_CTX_free(pctx);
|
||||
}
|
||||
|
||||
operator BN_CTX*() { return pctx; }
|
||||
BN_CTX& operator*() { return *pctx; }
|
||||
BN_CTX** operator&() { return &pctx; }
|
||||
bool operator!() { return (pctx == NULL); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBigNum : public BIGNUM
|
||||
{
|
||||
public:
|
||||
CBigNum()
|
||||
{
|
||||
BN_init(this);
|
||||
}
|
||||
|
||||
CBigNum(const CBigNum& b)
|
||||
{
|
||||
BN_init(this);
|
||||
if (!BN_copy(this, &b))
|
||||
{
|
||||
BN_clear_free(this);
|
||||
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
|
||||
}
|
||||
}
|
||||
|
||||
CBigNum& operator=(const CBigNum& b)
|
||||
{
|
||||
if (!BN_copy(this, &b))
|
||||
throw bignum_error("CBigNum::operator= : BN_copy failed");
|
||||
return (*this);
|
||||
}
|
||||
|
||||
~CBigNum()
|
||||
{
|
||||
BN_clear_free(this);
|
||||
}
|
||||
|
||||
CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
|
||||
CBigNum(int64 n) { BN_init(this); setint64(n); }
|
||||
CBigNum(unsigned char n) { BN_init(this); setulong(n); }
|
||||
CBigNum(unsigned short n) { BN_init(this); setulong(n); }
|
||||
CBigNum(unsigned int n) { BN_init(this); setulong(n); }
|
||||
CBigNum(uint64 n) { BN_init(this); setuint64(n); }
|
||||
explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
|
||||
|
||||
explicit CBigNum(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
BN_init(this);
|
||||
setvch(vch);
|
||||
}
|
||||
|
||||
void setuint(unsigned int n)
|
||||
{
|
||||
setulong(static_cast<unsigned long>(n));
|
||||
}
|
||||
|
||||
unsigned int getuint() const
|
||||
{
|
||||
return BN_get_word(this);
|
||||
}
|
||||
|
||||
int getint() const
|
||||
{
|
||||
unsigned long n = BN_get_word(this);
|
||||
if (!BN_is_negative(this))
|
||||
return (n > INT_MAX ? INT_MAX : n);
|
||||
else
|
||||
return (n > INT_MAX ? INT_MIN : -(int)n);
|
||||
}
|
||||
|
||||
void setint64(int64 n)
|
||||
{
|
||||
unsigned char pch[sizeof(n) + 6];
|
||||
unsigned char* p = pch + 4;
|
||||
bool fNegative = false;
|
||||
if (n < (int64)0)
|
||||
{
|
||||
n = -n;
|
||||
fNegative = true;
|
||||
}
|
||||
bool fLeadingZeroes = true;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
unsigned char c = (n >> 56) & 0xff;
|
||||
n <<= 8;
|
||||
if (fLeadingZeroes)
|
||||
{
|
||||
if (c == 0)
|
||||
continue;
|
||||
if (c & 0x80)
|
||||
*p++ = (fNegative ? 0x80 : 0);
|
||||
else if (fNegative)
|
||||
c |= 0x80;
|
||||
fLeadingZeroes = false;
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
unsigned int nSize = p - (pch + 4);
|
||||
pch[0] = (nSize >> 24) & 0xff;
|
||||
pch[1] = (nSize >> 16) & 0xff;
|
||||
pch[2] = (nSize >> 8) & 0xff;
|
||||
pch[3] = (nSize) & 0xff;
|
||||
BN_mpi2bn(pch, p - pch, this);
|
||||
}
|
||||
|
||||
uint64 getuint64() const
|
||||
{
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
return static_cast<uint64>(getulong());
|
||||
#else
|
||||
int len = BN_num_bytes(this);
|
||||
if (len > 8)
|
||||
throw std::runtime_error("BN getuint64 overflow");
|
||||
|
||||
unsigned char buf[8];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
BN_bn2bin(this, buf + 8 - len);
|
||||
return
|
||||
static_cast<uint64>(buf[0]) << 56 | static_cast<uint64>(buf[1]) << 48 |
|
||||
static_cast<uint64>(buf[2]) << 40 | static_cast<uint64>(buf[3]) << 32 |
|
||||
static_cast<uint64>(buf[4]) << 24 | static_cast<uint64>(buf[5]) << 16 |
|
||||
static_cast<uint64>(buf[6]) << 8 | static_cast<uint64>(buf[7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setuint64(uint64 n)
|
||||
{
|
||||
#if (ULONG_MAX > UINT_MAX)
|
||||
setulong(static_cast<unsigned long>(n));
|
||||
#else
|
||||
unsigned char buf[8];
|
||||
buf[0] = static_cast<unsigned char>((n >> 56) & 0xff);
|
||||
buf[1] = static_cast<unsigned char>((n >> 48) & 0xff);
|
||||
buf[2] = static_cast<unsigned char>((n >> 40) & 0xff);
|
||||
buf[3] = static_cast<unsigned char>((n >> 32) & 0xff);
|
||||
buf[4] = static_cast<unsigned char>((n >> 24) & 0xff);
|
||||
buf[5] = static_cast<unsigned char>((n >> 16) & 0xff);
|
||||
buf[6] = static_cast<unsigned char>((n >> 8) & 0xff);
|
||||
buf[7] = static_cast<unsigned char>((n) & 0xff);
|
||||
BN_bin2bn(buf, 8, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void setuint256(const uint256& n)
|
||||
{
|
||||
BN_bin2bn(n.begin(), n.size(), NULL);
|
||||
}
|
||||
|
||||
uint256 getuint256()
|
||||
{
|
||||
uint256 ret;
|
||||
unsigned int size = BN_num_bytes(this);
|
||||
if (size > ret.size())
|
||||
return ret;
|
||||
BN_bn2bin(this, ret.begin() + (ret.size() - BN_num_bytes(this)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setvch(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
std::vector<unsigned char> vch2(vch.size() + 4);
|
||||
unsigned int nSize = vch.size();
|
||||
// BIGNUM's byte stream format expects 4 bytes of
|
||||
// big endian size data info at the front
|
||||
vch2[0] = (nSize >> 24) & 0xff;
|
||||
vch2[1] = (nSize >> 16) & 0xff;
|
||||
vch2[2] = (nSize >> 8) & 0xff;
|
||||
vch2[3] = (nSize >> 0) & 0xff;
|
||||
// swap data to big endian
|
||||
std::reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
|
||||
BN_mpi2bn(&vch2[0], vch2.size(), this);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> getvch() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||
if (nSize < 4)
|
||||
return std::vector<unsigned char>();
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
BN_bn2mpi(this, &vch[0]);
|
||||
vch.erase(vch.begin(), vch.begin() + 4);
|
||||
reverse(vch.begin(), vch.end());
|
||||
return vch;
|
||||
}
|
||||
|
||||
CBigNum& SetCompact(unsigned int nCompact)
|
||||
{
|
||||
unsigned int nSize = nCompact >> 24;
|
||||
std::vector<unsigned char> vch(4 + nSize);
|
||||
vch[3] = nSize;
|
||||
if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
|
||||
if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
|
||||
if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
|
||||
BN_mpi2bn(&vch[0], vch.size(), this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned int GetCompact() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
nSize -= 4;
|
||||
BN_bn2mpi(this, &vch[0]);
|
||||
unsigned int nCompact = nSize << 24;
|
||||
if (nSize >= 1) nCompact |= (vch[4] << 16);
|
||||
if (nSize >= 2) nCompact |= (vch[5] << 8);
|
||||
if (nSize >= 3) nCompact |= (vch[6] << 0);
|
||||
return nCompact;
|
||||
}
|
||||
|
||||
void SetHex(const std::string& str)
|
||||
{
|
||||
// skip 0x
|
||||
const char* psz = str.c_str();
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
bool fNegative = false;
|
||||
if (*psz == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
psz++;
|
||||
}
|
||||
if (psz[0] == '0' && tolower(psz[1]) == 'x')
|
||||
psz += 2;
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// hex string to bignum
|
||||
static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
|
||||
*this = 0;
|
||||
while (isxdigit(*psz))
|
||||
{
|
||||
*this <<= 4;
|
||||
int n = phexdigit[(int) *psz++];
|
||||
*this += n;
|
||||
}
|
||||
if (fNegative)
|
||||
*this = 0 - *this;
|
||||
}
|
||||
|
||||
std::string ToString(int nBase=10) const
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum bnBase = nBase;
|
||||
CBigNum bn0 = 0;
|
||||
std::string str;
|
||||
CBigNum bn = *this;
|
||||
BN_set_negative(&bn, false);
|
||||
CBigNum dv;
|
||||
CBigNum rem;
|
||||
if (BN_cmp(&bn, &bn0) == 0)
|
||||
return "0";
|
||||
while (BN_cmp(&bn, &bn0) > 0)
|
||||
{
|
||||
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
|
||||
throw bignum_error("CBigNum::ToString() : BN_div failed");
|
||||
bn = dv;
|
||||
unsigned int c = rem.getuint();
|
||||
str += "0123456789abcdef"[c];
|
||||
}
|
||||
if (BN_is_negative(this))
|
||||
str += "-";
|
||||
reverse(str.begin(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string GetHex() const
|
||||
{
|
||||
return ToString(16);
|
||||
}
|
||||
/* JED
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
|
||||
{
|
||||
return ::GetSerializeSize(getvch(), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
|
||||
{
|
||||
::Serialize(s, getvch(), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
|
||||
{
|
||||
std::vector<unsigned char> vch;
|
||||
::Unserialize(s, vch, nType, nVersion);
|
||||
setvch(vch);
|
||||
}*/
|
||||
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return BN_is_zero(this);
|
||||
}
|
||||
|
||||
CBigNum& operator+=(const CBigNum& b)
|
||||
{
|
||||
if (!BN_add(this, this, &b))
|
||||
throw bignum_error("CBigNum::operator+= : BN_add failed");
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator-=(const CBigNum& b)
|
||||
{
|
||||
*this = *this - b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator*=(const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
if (!BN_mul(this, this, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator*= : BN_mul failed");
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator/=(const CBigNum& b)
|
||||
{
|
||||
*this = *this / b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator%=(const CBigNum& b)
|
||||
{
|
||||
*this = *this % b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator<<=(unsigned int shift)
|
||||
{
|
||||
if (!BN_lshift(this, this, shift))
|
||||
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
|
||||
return *this;
|
||||
}
|
||||
|
||||
CBigNum& operator>>=(unsigned int shift)
|
||||
{
|
||||
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
|
||||
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
|
||||
CBigNum a = 1;
|
||||
a <<= shift;
|
||||
if (BN_cmp(&a, this) > 0)
|
||||
{
|
||||
*this = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (!BN_rshift(this, this, shift))
|
||||
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
CBigNum& operator++()
|
||||
{
|
||||
// prefix operator
|
||||
if (!BN_add(this, this, BN_value_one()))
|
||||
throw bignum_error("CBigNum::operator++ : BN_add failed");
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBigNum operator++(int)
|
||||
{
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
++(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBigNum& operator--()
|
||||
{
|
||||
// prefix operator
|
||||
CBigNum r;
|
||||
if (!BN_sub(&r, this, BN_value_one()))
|
||||
throw bignum_error("CBigNum::operator-- : BN_sub failed");
|
||||
*this = r;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBigNum operator--(int)
|
||||
{
|
||||
// postfix operator
|
||||
const CBigNum ret = *this;
|
||||
--(*this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
|
||||
friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
|
||||
|
||||
private:
|
||||
|
||||
// private because the size of an unsigned long varies by platform
|
||||
|
||||
void setulong(unsigned long n)
|
||||
{
|
||||
if (!BN_set_word(this, n))
|
||||
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
|
||||
}
|
||||
|
||||
unsigned long getulong() const
|
||||
{
|
||||
return BN_get_word(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_add(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator+ : BN_add failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_sub(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator- : BN_sub failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator-(const CBigNum& a)
|
||||
{
|
||||
CBigNum r(a);
|
||||
BN_set_negative(&r, !BN_is_negative(&r));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_mul(&r, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator* : BN_mul failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_div(&r, NULL, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator/ : BN_div failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_mod(&r, &a, &b, pctx))
|
||||
throw bignum_error("CBigNum::operator% : BN_div failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_lshift(&r, &a, shift))
|
||||
throw bignum_error("CBigNum:operator<< : BN_lshift failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
|
||||
{
|
||||
CBigNum r = a;
|
||||
r >>= shift;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
|
||||
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
|
||||
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
|
||||
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
|
||||
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
|
||||
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
|
||||
|
||||
#endif
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,294 +0,0 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_KEY_H
|
||||
#define BITCOIN_KEY_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "RippleAddress.h"
|
||||
|
||||
// secp256k1:
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 279;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 65; // but we don't use full keys
|
||||
// const unsigned int COMPUB_KEY_SIZE = 33;
|
||||
// const unsigned int SIGNATURE_SIZE = 72;
|
||||
//
|
||||
// see www.keylength.com
|
||||
// script supports up to 75 for single byte push
|
||||
|
||||
int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
{
|
||||
int okay = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey) return 0;
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
|
||||
if (pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
goto err;
|
||||
|
||||
EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
|
||||
EC_KEY_set_private_key(eckey, priv_key);
|
||||
EC_KEY_set_public_key(eckey, pub_key);
|
||||
|
||||
okay = 1;
|
||||
|
||||
err:
|
||||
|
||||
if (pub_key)
|
||||
EC_POINT_free(pub_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return (okay);
|
||||
}
|
||||
|
||||
|
||||
class key_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
//JED: typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
||||
//typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
|
||||
|
||||
typedef std::vector<unsigned char> CPrivKey;
|
||||
typedef std::vector<unsigned char> CSecret;
|
||||
class CKey
|
||||
{
|
||||
protected:
|
||||
EC_KEY* pkey;
|
||||
bool fSet;
|
||||
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<CKey> pointer;
|
||||
|
||||
CKey()
|
||||
{
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
|
||||
CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
|
||||
CKey& operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
|
||||
|
||||
static uint128 PassPhraseToKey(const std::string& passPhrase);
|
||||
static EC_KEY* GenerateRootDeterministicKey(const uint128& passPhrase);
|
||||
static EC_KEY* GenerateRootPubKey(BIGNUM* pubGenerator);
|
||||
static EC_KEY* GeneratePublicDeterministicKey(const RippleAddress& generator, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey(const RippleAddress& family, const BIGNUM* rootPriv, int n);
|
||||
static EC_KEY* GeneratePrivateDeterministicKey(const RippleAddress& family, const uint256& rootPriv, int n);
|
||||
|
||||
CKey(const uint128& passPhrase) : fSet(false)
|
||||
{
|
||||
pkey = GenerateRootDeterministicKey(passPhrase);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
|
||||
CKey(const RippleAddress& generator, int n) : fSet(false)
|
||||
{ // public deterministic key
|
||||
pkey = GeneratePublicDeterministicKey(generator, n);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
|
||||
CKey(const RippleAddress& base, const BIGNUM* rootPrivKey, int n) : fSet(false)
|
||||
{ // private deterministic key
|
||||
pkey = GeneratePrivateDeterministicKey(base, rootPrivKey, n);
|
||||
fSet = true;
|
||||
assert(pkey);
|
||||
}
|
||||
|
||||
CKey(const uint256& privateKey) : pkey(NULL), fSet(false)
|
||||
{
|
||||
// XXX Broken pkey is null.
|
||||
SetPrivateKeyU(privateKey);
|
||||
}
|
||||
|
||||
#if 0
|
||||
CKey(const RippleAddress& masterKey, int keyNum, bool isPublic) : pkey(NULL), fSet(false)
|
||||
{
|
||||
if (isPublic)
|
||||
SetPubSeq(masterKey, keyNum);
|
||||
else
|
||||
SetPrivSeq(masterKey, keyNum); // broken, need seed
|
||||
fSet = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
|
||||
void MakeNewKey()
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
// XXX Still used!
|
||||
BIGNUM* GetSecretBN() const
|
||||
{ // DEPRECATED
|
||||
return BN_dup(EC_KEY_get0_private_key(pkey));
|
||||
}
|
||||
|
||||
void GetPrivateKeyU(uint256& privKey)
|
||||
{
|
||||
const BIGNUM* bn = EC_KEY_get0_private_key(pkey);
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::GetPrivateKeyU: EC_KEY_get0_private_key failed");
|
||||
privKey.zero();
|
||||
BN_bn2bin(bn, privKey.begin() + (privKey.size() - BN_num_bytes(bn)));
|
||||
}
|
||||
|
||||
bool SetPrivateKeyU(const uint256& key, bool bThrow=false)
|
||||
{
|
||||
// XXX Broken if pkey is not set.
|
||||
BIGNUM* bn = BN_bin2bn(key.begin(), key.size(), NULL);
|
||||
bool bSuccess = !!EC_KEY_set_private_key(pkey, bn);
|
||||
|
||||
BN_clear_free(bn);
|
||||
|
||||
if (bSuccess)
|
||||
{
|
||||
fSet = true;
|
||||
}
|
||||
else if (bThrow)
|
||||
{
|
||||
throw key_error("CKey::SetPrivateKeyU: EC_KEY_set_private_key failed");
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool SetPubKey(const void *ptr, size_t len)
|
||||
{
|
||||
const unsigned char* pbegin = static_cast<const unsigned char *>(ptr);
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, len))
|
||||
return false;
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
|
||||
{
|
||||
return SetPubKey(&vchPubKey[0], vchPubKey.size());
|
||||
}
|
||||
|
||||
bool SetPubKey(const std::string& pubKey)
|
||||
{
|
||||
return SetPubKey(pubKey.data(), pubKey.size());
|
||||
}
|
||||
|
||||
std::vector<unsigned char> GetPubKey() const
|
||||
{
|
||||
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
assert(nSize<=33);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
std::vector<unsigned char> vchPubKey(33, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
assert(vchPubKey.size()<=33);
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
unsigned char pchSig[10000];
|
||||
unsigned int nSize = 0;
|
||||
|
||||
vchSig.clear();
|
||||
|
||||
if (!ECDSA_sign(0, (unsigned char*)hash.begin(), hash.size(), pchSig, &nSize, pkey))
|
||||
return false;
|
||||
|
||||
vchSig.resize(nSize);
|
||||
memcpy(&vchSig[0], pchSig, nSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify(const uint256& hash, const void *sig, size_t sigLen) const
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, hash.begin(), hash.size(), (const unsigned char *) sig, sigLen, pkey) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const
|
||||
{
|
||||
return Verify(hash, &vchSig[0], vchSig.size());
|
||||
}
|
||||
|
||||
bool Verify(const uint256& hash, const std::string& sig) const
|
||||
{
|
||||
return Verify(hash, sig.data(), sig.size());
|
||||
}
|
||||
|
||||
// ECIES functions. These throw on failure
|
||||
|
||||
// returns a 32-byte secret unique to these two keys. At least one private key must be known.
|
||||
void getECIESSecret(CKey& otherKey, uint256& enc_key, uint256& hmac_key);
|
||||
|
||||
// encrypt/decrypt functions with integrity checking.
|
||||
// Note that the other side must somehow know what keys to use
|
||||
std::vector<unsigned char> encryptECIES(CKey& otherKey, const std::vector<unsigned char>& plaintext);
|
||||
std::vector<unsigned char> decryptECIES(CKey& otherKey, const std::vector<unsigned char>& ciphertext);
|
||||
};
|
||||
|
||||
#endif
|
||||
// vim:ts=4
|
||||
@@ -1,465 +0,0 @@
|
||||
//
|
||||
// RFC 1751 code converted to C++/Boost.
|
||||
//
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/range/adaptor/copied.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
static const char* pcDict[2048] = {
|
||||
"A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
|
||||
"AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
|
||||
"ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
|
||||
"AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
|
||||
"BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
|
||||
"BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
|
||||
"BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
|
||||
"CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
|
||||
"DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
|
||||
"DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
|
||||
"ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
|
||||
"EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
|
||||
"FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
|
||||
"GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
|
||||
"GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
|
||||
"HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
|
||||
"HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
|
||||
"HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
|
||||
"INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS",
|
||||
"IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG",
|
||||
"JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY",
|
||||
"KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC",
|
||||
"LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG",
|
||||
"LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO",
|
||||
"LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE",
|
||||
"MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY",
|
||||
"ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB",
|
||||
"MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM",
|
||||
"MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE",
|
||||
"NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON",
|
||||
"NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK",
|
||||
"OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK",
|
||||
"OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR",
|
||||
"OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL",
|
||||
"PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN",
|
||||
"PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY",
|
||||
"PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG",
|
||||
"PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW",
|
||||
"RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO",
|
||||
"RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE",
|
||||
"RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN",
|
||||
"SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW",
|
||||
"SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY",
|
||||
"SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB",
|
||||
"SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP",
|
||||
"TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM",
|
||||
"TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW",
|
||||
"TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US",
|
||||
"USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY",
|
||||
"WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK",
|
||||
"WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA",
|
||||
"YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE",
|
||||
"ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR",
|
||||
"AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR",
|
||||
"AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO",
|
||||
"ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS",
|
||||
"AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB",
|
||||
"ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
||||
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
|
||||
"AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT",
|
||||
"BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE",
|
||||
"BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE",
|
||||
"BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK",
|
||||
"BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER",
|
||||
"BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT",
|
||||
"BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
||||
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT",
|
||||
"BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR",
|
||||
"BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL",
|
||||
"BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN",
|
||||
"BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE",
|
||||
"BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
|
||||
"BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF",
|
||||
"BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
||||
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY",
|
||||
"CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE",
|
||||
"CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK",
|
||||
"CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT",
|
||||
"CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB",
|
||||
"CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
|
||||
"CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK",
|
||||
"COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
||||
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT",
|
||||
"CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG",
|
||||
"CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF",
|
||||
"CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS",
|
||||
"DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK",
|
||||
"DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
|
||||
"DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM",
|
||||
"DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
||||
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC",
|
||||
"DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME",
|
||||
"DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE",
|
||||
"DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM",
|
||||
"DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE",
|
||||
"DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
|
||||
"EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA",
|
||||
"EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
||||
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE",
|
||||
"FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST",
|
||||
"FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT",
|
||||
"FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM",
|
||||
"FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS",
|
||||
"FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
|
||||
"FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY",
|
||||
"FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
||||
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU",
|
||||
"FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL",
|
||||
"FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL",
|
||||
"GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB",
|
||||
"GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD",
|
||||
"GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
|
||||
"GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB",
|
||||
"GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
||||
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE",
|
||||
"GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW",
|
||||
"GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL",
|
||||
"GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK",
|
||||
"HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG",
|
||||
"HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
|
||||
"HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT",
|
||||
"HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
||||
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH",
|
||||
"HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO",
|
||||
"HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK",
|
||||
"HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE",
|
||||
"HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO",
|
||||
"HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
|
||||
"HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO",
|
||||
"IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
||||
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF",
|
||||
"JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS",
|
||||
"JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD",
|
||||
"JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO",
|
||||
"JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE",
|
||||
"KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
|
||||
"KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT",
|
||||
"KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
||||
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB",
|
||||
"LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE",
|
||||
"LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN",
|
||||
"LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK",
|
||||
"LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES",
|
||||
"LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
|
||||
"LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE",
|
||||
"LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
||||
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS",
|
||||
"LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU",
|
||||
"LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN",
|
||||
"LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE",
|
||||
"MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE",
|
||||
"MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
|
||||
"MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET",
|
||||
"MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
||||
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE",
|
||||
"MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN",
|
||||
"MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK",
|
||||
"MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS",
|
||||
"MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL",
|
||||
"MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
|
||||
"NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT",
|
||||
"NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
||||
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE",
|
||||
"NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN",
|
||||
"NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO",
|
||||
"OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN",
|
||||
"OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO",
|
||||
"OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
|
||||
"OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE",
|
||||
"RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
||||
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF",
|
||||
"REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE",
|
||||
"RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE",
|
||||
"RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL",
|
||||
"ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE",
|
||||
"ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
|
||||
"RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH",
|
||||
"RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
||||
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA",
|
||||
"SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM",
|
||||
"SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL",
|
||||
"SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED",
|
||||
"SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK",
|
||||
"SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
|
||||
"SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID",
|
||||
"SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
||||
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM",
|
||||
"SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK",
|
||||
"SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG",
|
||||
"SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG",
|
||||
"STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN",
|
||||
"SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
|
||||
"SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK",
|
||||
"TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
||||
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL",
|
||||
"TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE",
|
||||
"THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE",
|
||||
"TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE",
|
||||
"TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE",
|
||||
"TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
|
||||
"TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM",
|
||||
"TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
||||
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT",
|
||||
"ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN",
|
||||
"VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND",
|
||||
"VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID",
|
||||
"VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE",
|
||||
"WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
|
||||
"WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS",
|
||||
"WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
||||
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN",
|
||||
"WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE",
|
||||
"WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT",
|
||||
"WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT",
|
||||
"WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH",
|
||||
"YEAR", "YELL", "YOGA", "YOKE"
|
||||
};
|
||||
|
||||
/* Extract 'length' bits from the char array 's'
|
||||
starting with bit 'start' */
|
||||
static unsigned long extract(char *s, int start, int length)
|
||||
{
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long x;
|
||||
|
||||
assert(length <= 11);
|
||||
assert(start >= 0);
|
||||
assert(length >= 0);
|
||||
assert(start+length <= 66);
|
||||
|
||||
cl = s[start/8]; // get components
|
||||
cc = s[start/8 +1];
|
||||
cr = s[start/8 +2];
|
||||
|
||||
x = ((long)(cl<<8 | cc) <<8 | cr) ; // Put bits together
|
||||
x = x >> (24 - (length + (start%8))); // Right justify number
|
||||
x = ( x & (0xffff >> (16-length) ) ); // Trim extra bits.
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Encode 8 bytes in 'c' as a string of English words.
|
||||
// Returns a pointer to a static buffer
|
||||
static void btoe(std::string& strHuman, const std::string& strData)
|
||||
{
|
||||
char caBuffer[9]; /* add in room for the parity 2 bits*/
|
||||
int p, i;
|
||||
|
||||
memcpy(caBuffer, strData.c_str(), 8);
|
||||
|
||||
// compute parity: merely add groups of two bits.
|
||||
for(p = 0, i = 0; i < 64; i += 2)
|
||||
p += extract(caBuffer, i, 2);
|
||||
|
||||
caBuffer[8] = char(p) << 6;
|
||||
|
||||
strHuman = std::string()
|
||||
+ pcDict[extract(caBuffer, 0, 11)] + " "
|
||||
+ pcDict[extract(caBuffer, 11, 11)] + " "
|
||||
+ pcDict[extract(caBuffer, 22, 11)] + " "
|
||||
+ pcDict[extract(caBuffer, 33, 11)] + " "
|
||||
+ pcDict[extract(caBuffer, 44, 11)] + " "
|
||||
+ pcDict[extract(caBuffer, 55, 11)];
|
||||
}
|
||||
|
||||
static void insert(char *s, int x, int start, int length)
|
||||
{
|
||||
unsigned char cl;
|
||||
unsigned char cc;
|
||||
unsigned char cr;
|
||||
unsigned long y;
|
||||
int shift;
|
||||
|
||||
assert(length <= 11);
|
||||
assert(start >= 0);
|
||||
assert(length >= 0);
|
||||
assert(start+length <= 66);
|
||||
|
||||
shift = ((8 -(( start + length) % 8))%8);
|
||||
y = (long) x << shift;
|
||||
cl = (y >> 16) & 0xff;
|
||||
cc = (y >> 8) & 0xff;
|
||||
cr = y & 0xff;
|
||||
if(shift + length > 16){
|
||||
s[start /8] |= cl;
|
||||
s[start/8 +1] |= cc;
|
||||
s[start/8 +2] |= cr;
|
||||
} else if(shift +length > 8){
|
||||
s[start/8] |= cc;
|
||||
s[start/8 + 1] |= cr;
|
||||
} else {
|
||||
s[start/8] |= cr;
|
||||
}
|
||||
}
|
||||
|
||||
static void standard(std::string& strWord)
|
||||
{
|
||||
BOOST_FOREACH(char cLetter, strWord)
|
||||
{
|
||||
if(!isascii(cLetter))
|
||||
{
|
||||
; // nothing
|
||||
}
|
||||
else if(islower(cLetter))
|
||||
{
|
||||
cLetter = toupper(cLetter);
|
||||
}
|
||||
else if(cLetter == '1')
|
||||
{
|
||||
cLetter = 'L';
|
||||
}
|
||||
else if(cLetter == '0')
|
||||
{
|
||||
cLetter = 'O';
|
||||
}
|
||||
else if(cLetter == '5')
|
||||
{
|
||||
cLetter = 'S';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Binary search of dictionary.
|
||||
static int wsrch(const std::string& strWord, int iMin, int iMax)
|
||||
{
|
||||
int iResult = -1;
|
||||
|
||||
while (iResult < 0 && iMin != iMax)
|
||||
{
|
||||
// Have a range to search.
|
||||
int iMid = iMin+(iMax-iMin)/2;
|
||||
int iDir = strWord.compare(pcDict[iMid]);
|
||||
|
||||
if (!iDir)
|
||||
{
|
||||
iResult = iMid; // Found it.
|
||||
}
|
||||
else if (iDir < 0)
|
||||
{
|
||||
iMax = iMid; // key < middle, middle is new max.
|
||||
}
|
||||
else
|
||||
{
|
||||
iMin = iMid+1; // key > middle, new min is past the middle.
|
||||
}
|
||||
}
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
// Convert 6 words to binary.
|
||||
//
|
||||
// Returns 1 OK - all good words and parity is OK
|
||||
// 0 word not in data base
|
||||
// -1 badly formed in put ie > 4 char word
|
||||
// -2 words OK but parity is wrong
|
||||
static int etob(std::string& strData, std::vector<std::string> vsHuman)
|
||||
{
|
||||
int i, p, v,l;
|
||||
char b[9];
|
||||
|
||||
if (6 != vsHuman.size())
|
||||
return -1;
|
||||
|
||||
memset(b, 0, sizeof(b));
|
||||
|
||||
p=0;
|
||||
BOOST_FOREACH(std::string& strWord, vsHuman)
|
||||
{
|
||||
l = strWord.length();
|
||||
if(l > 4 || l < 1)
|
||||
return -1;
|
||||
|
||||
standard(strWord);
|
||||
|
||||
v = wsrch(strWord,
|
||||
l < 4 ? 0 : 571,
|
||||
l < 4 ? 570 : 2048);
|
||||
|
||||
if(v < 0 )
|
||||
return 0;
|
||||
|
||||
insert(b, v, p, 11);
|
||||
p +=11;
|
||||
}
|
||||
|
||||
/* now check the parity of what we got */
|
||||
for(p = 0, i = 0; i < 64; i +=2)
|
||||
p += extract(b, i, 2);
|
||||
|
||||
if( (p & 3) != extract(b, 64,2) )
|
||||
return -2;
|
||||
|
||||
strData.assign(b, 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// eng2key() convert words seperated by spaces into a 128 bit key in big-endian format.
|
||||
// eng2key() returns
|
||||
// 1 if succeeded
|
||||
// 0 if word not in dictionary
|
||||
// -1 if badly formed string
|
||||
// -2 if words are okay but parity is wrong.
|
||||
int eng2key(std::string& strKey, const std::string& strHuman)
|
||||
{
|
||||
std::vector<std::string> vWords;
|
||||
std::string strFirst, strSecond;
|
||||
int rc=0;
|
||||
|
||||
std::string strTrimmed(strHuman);
|
||||
|
||||
boost::algorithm::trim(strTrimmed);
|
||||
|
||||
boost::algorithm::split(vWords, strTrimmed,
|
||||
boost::algorithm::is_space(), boost::algorithm::token_compress_on);
|
||||
|
||||
rc = 12 == vWords.size() ? 1 : -1;
|
||||
|
||||
if (1 == rc)
|
||||
rc = etob(strFirst, vWords | boost::adaptors::copied(0, 6));
|
||||
|
||||
if (1 == rc)
|
||||
rc = etob(strSecond, vWords | boost::adaptors::copied(6, 12));
|
||||
|
||||
if (1 == rc)
|
||||
strKey = strFirst + strSecond;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// key2eng() given a 128 bit key in big-endian format, convert to human.
|
||||
void key2eng(std::string& strHuman, const std::string& strKey)
|
||||
{
|
||||
std::string strFirst, strSecond;
|
||||
|
||||
btoe(strFirst, strKey.substr(0, 8));
|
||||
btoe(strSecond, strKey.substr(8, 8));
|
||||
|
||||
strHuman = strFirst + " " + strSecond;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef _RFC_1751_
|
||||
#define _RFC_1751_
|
||||
|
||||
int eng2key(std::string& strKey, const std::string& strHuman);
|
||||
void key2eng(std::string& strHuman, const std::string& strKey);
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "RPC.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "Config.h"
|
||||
#include "Version.h"
|
||||
|
||||
@@ -25,6 +24,15 @@ using namespace boost::asio;
|
||||
|
||||
unsigned int const gMaxHTTPHeaderSize = 0x02000000;
|
||||
|
||||
std::string gFormatStr("v1");
|
||||
|
||||
// VFALCO: TODO, clean up this nonsense
|
||||
std::string FormatFullVersion()
|
||||
{
|
||||
return(gFormatStr);
|
||||
}
|
||||
|
||||
|
||||
Json::Value JSONRPCError(int code, const std::string& message)
|
||||
{
|
||||
Json::Value error(Json::objectValue);
|
||||
@@ -142,7 +150,7 @@ int ReadHTTPStatus(std::basic_istream<char>& stream)
|
||||
int ReadHTTPHeader(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet)
|
||||
{
|
||||
int nLen = 0;
|
||||
loop
|
||||
for (;;)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(stream, str);
|
||||
|
||||
Reference in New Issue
Block a user