Browse Source

Hex-prefix Notation for the Merkle tree.

cl-refactor
Gav Wood 11 years ago
parent
commit
3562b13f68
  1. 2
      Common.h
  2. 3
      PatriciaTree.cpp
  3. 133
      PatriciaTree.h
  4. 105
      RLP.h
  5. 39
      main.cpp
  6. 30
      sha256.cpp
  7. 40
      sha256.h

2
Common.h

@ -11,7 +11,7 @@ namespace eth
{
using byte = uint8_t;
using bytes = vector<byte>;
using bytes = std::vector<byte>;
using fBytes = foreign<byte>;
using fConstBytes = foreign<byte const>;

3
PatriciaTree.cpp

@ -2,7 +2,7 @@
#include "PatriciaTree.h"
using namespace std;
using namespace eth;
/*
PatriciaTree::PatriciaTree(RLP const& _data)
{
// Make tree based on _data
@ -20,3 +20,4 @@ PatriciaTree::PatriciaTree(RLP const& _data)
// Branch
}
}
*/

133
PatriciaTree.h

@ -2,6 +2,7 @@
#include <map>
#include "RLP.h"
#include "sha256.h"
namespace eth
{
@ -24,137 +25,49 @@ using HexMap = std::map<bytes, std::string>;
* [1,2,3,4,T] 0x201234
*/
std::string fromHex(bytes const& _hexVector, bool _forceTerminated = false)
inline std::string fromHex(bytes const& _hexVector, bool _terminated = false, int _begin = 0, int _end = -1)
{
uint begin = 0;
uint end = _hexVector.size();
bool termed = _forceTerminated;
bool odd = _hexVector.size() % 2;
uint begin = _begin;
uint end = _end < 0 ? _hexVector.size() + 1 + _end : _end;
bool termed = _terminated;
bool odd = (end - begin) % 2;
std::string ret(((termed ? 2 : 0) | (odd ? 1 : 0)) * 16, 1);
std::string ret(1, ((termed ? 2 : 0) | (odd ? 1 : 0)) * 16);
if (odd)
{
ret[0] |= _hexVector[0];
begin = 1;
++begin;
}
else if (leadingZero)
for (uint i = begin; i < end; i += 2)
ret += _hexVector[i] * 16 + _hexVector[i + 1];
return ret;
}
template <class _T, class ... _Ts> bytes encodeRLP(_T _t, _Ts ... _ts)
inline u256 hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen)
{
unsigned c = 0;
for (auto i = _begin; i != _end; ++i, ++c) {}
}
struct rlplist { rlplist(uint _count): count(_count) {} uint count; };
class RLPStream
{
public:
RLPStream() {}
void append(uint _s) { appendNumeric(_s); }
void append(u256 _s) { appendNumeric(_s); }
void append(bigint _s) { appendNumeric(_s); }
void append(std::string const& _s)
{
if (_s.size() < 0x38)
m_out.push_back(_count | 0x40);
else
pushCount(_count, 0x40);
uint os = m_out.size();
m_out.resize(m_out.size() + _s.size());
memcpy(m_out.data() + os, _s.data(), _s.size());
}
void appendList(uint _count)
{
if (_s.size() < 0x38)
m_out.push_back(_count | 0x80);
else
pushCount(_count, 0x80);
}
RLPStream operator<<(uint _t) { append(_i); }
RLPStream operator<<(u256 _t) { append(_i); }
RLPStream operator<<(bigint _t) { append(_i); }
RLPStream operator<<(std::string const& _s) { append(_s); }
RLPStream operator<<(rlplist _l) { m_lists.push_back(_l.count); appendList(_l.count); }
private:
void appendNumeric(uint _i)
assert(c > 0);
RLPStream rlp;
if (c == 1)
{
if (_i < 0x18)
m_out.push_back(_i);
else
m_out.push_back(bytesRequired(_i) + 0x17); // max 8 bytes.
// only one left - terminate with the pair.
rlp << RLPList(2) << fromHex(_begin->first, true, _preLen) << _begin->second;
}
void appendNumeric(u256 _i)
else
{
if (_i < 0x18)
m_out.push_back(_i);
else
m_out.push_back(bytesRequired(_i) + 0x17); // max 32 bytes.
}
// if they all have the same next nibble, we also want a pair.
void appendNumeric(bigint _i)
{
if (_i < 0x18)
m_out.push_back(_i);
else
// otherwise enumerate all 16+1 entries.
for (auto i = 0; i < 16; ++i)
{
uint br = bytesRequired(_i);
if (br <= 32)
m_out.push_back(bytesRequired(_i) + 0x17); // max 32 bytes.
else
m_out.push_back(0x37 + bytesRequired(br));
}
for (uint i = 0; i < )
m_out.push_back()
}
void pushCount(uint _count, byte _base)
{
m_out.push_back(bytesRequired(_i) + 0x17); // max 8 bytes.
}
template <class _T> static uint bytesRequired(_T _i)
{
_i >>= 8;
uint i = 1;
for (; _i != 0; ++i, _i >>= 8) {}
return i;
}
bytes m_out;
};
template <> bytes encodeRLP(_T _t)
{
}
u256 hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen)
{
unsigned c = 0;
for (auto i = _begin; i != _end; ++i, ++c) {}
assert(c > 0);
if (c == 1)
return sha256(encodeRLP());
for (auto i = 0; i < 16; ++i)
{
}
return sha256(rlp.out());
}
bytes toHex(std::string const& _s)
inline bytes toHex(std::string const& _s)
{
std::vector<uint8_t> ret(_s.size() * 2 + 1);
for (auto i: _s)
@ -166,7 +79,7 @@ bytes toHex(std::string const& _s)
return ret;
}
u256 hash256(StringMap const& _s)
inline u256 hash256(StringMap const& _s)
{
// build patricia tree.
if (_s.empty())

105
RLP.h

@ -156,6 +156,111 @@ private:
fConstBytes m_data;
};
struct RLPList { RLPList(uint _count): count(_count) {} uint count; };
class RLPStream
{
public:
RLPStream() {}
void append(uint _s) { appendNumeric(_s); }
void append(u256 _s) { appendNumeric(_s); }
void append(bigint _s) { appendNumeric(_s); }
void append(std::string const& _s)
{
if (_s.size() < 0x38)
m_out.push_back(_s.size() | 0x40);
else
pushCount(_s.size(), 0x40);
uint os = m_out.size();
m_out.resize(m_out.size() + _s.size());
memcpy(m_out.data() + os, _s.data(), _s.size());
}
void appendList(uint _count)
{
if (_count < 0x38)
m_out.push_back(_count | 0x80);
else
pushCount(_count, 0x80);
}
RLPStream operator<<(uint _i) { append(_i); return *this; }
RLPStream operator<<(u256 _i) { append(_i); return *this; }
RLPStream operator<<(bigint _i) { append(_i); return *this; }
RLPStream operator<<(std::string const& _s) { append(_s); return *this; }
RLPStream operator<<(RLPList _l) { appendList(_l.count); return *this; }
bytes const& out() const { return m_out; }
private:
void appendNumeric(uint _i)
{
if (_i < 0x18)
m_out.push_back(_i);
else
{
auto br = bytesRequired(_i);
m_out.push_back(br + 0x17); // max 8 bytes.
for (int i = br - 1; i >= 0; --i)
m_out.push_back((_i >> i) & 0xff);
}
}
void appendNumeric(u256 _i)
{
if (_i < 0x18)
m_out.push_back(_i);
else
{
auto br = bytesRequired(_i);
m_out.push_back(br + 0x17); // max 8 bytes.
for (int i = br - 1; i >= 0; --i)
m_out.push_back((byte)(_i >> i));
}
}
void appendNumeric(bigint _i)
{
if (_i < 0x18)
m_out.push_back((byte)_i);
else
{
uint br = bytesRequired(_i);
if (br <= 32)
m_out.push_back(bytesRequired(_i) + 0x17); // max 32 bytes.
else
{
auto brbr = bytesRequired(br);
m_out.push_back(0x37 + brbr);
for (int i = brbr - 1; i >= 0; --i)
m_out.push_back((br >> i) & 0xff);
}
for (uint i = 0; i < br; ++i)
{
bigint u = (_i >> (br - 1 - i));
m_out.push_back((uint)u);
}
}
}
void pushCount(uint _count, byte _base)
{
m_out.push_back(bytesRequired(_count) + 0x37 + _base); // max 8 bytes.
}
template <class _T> static uint bytesRequired(_T _i)
{
_i >>= 8;
uint i = 1;
for (; _i != 0; ++i, _i >>= 8) {}
return i;
}
bytes m_out;
};
}
inline std::ostream& operator<<(std::ostream& _out, eth::RLP _d)

39
main.cpp

@ -1,7 +1,17 @@
#include "RLP.h"
#include "PatriciaTree.h"
#include "VirtualMachine.h"
using namespace std;
using namespace eth;
std::string asHex(std::string const& _data)
{
std::ostringstream ret;
for (auto i: _data)
ret << hex << setfill('0') << setw(2) << (int)i;
return ret.str();
}
int main()
{
// int of value 15
@ -27,10 +37,37 @@ int main()
// 33-byte (264-bit) int
ostringstream o2;
o2 << hex << RLP("\x38\x21\x20\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f");
assert(o2.str() == "20100102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
assert(o2.str() == "2120100102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
// 56-character string.
assert(toString(RLP("\x78\x38""Lorem ipsum dolor sit amet, consectetur adipisicing elit")) == "\"Lorem ipsum dolor sit amet, consectetur adipisicing elit\"");
/*
* Hex-prefix Notation. First nibble has flags: oddness = 2^0 & termination = 2^1
* [0,0,1,2,3,4,5] 0x10012345
* [0,1,2,3,4,5] 0x00012345
* [1,2,3,4,5] 0x112345
* [0,0,1,2,3,4] 0x00001234
* [0,1,2,3,4] 0x101234
* [1,2,3,4] 0x001234
* [0,0,1,2,3,4,5,T] 0x30012345
* [0,0,1,2,3,4,T] 0x20001234
* [0,1,2,3,4,5,T] 0x20012345
* [1,2,3,4,5,T] 0x312345
* [1,2,3,4,T] 0x201234
*/
assert(asHex(fromHex({0, 0, 1, 2, 3, 4, 5}, false)) == "10012345");
assert(asHex(fromHex({0, 1, 2, 3, 4, 5}, false)) == "00012345");
assert(asHex(fromHex({1, 2, 3, 4, 5}, false)) == "112345");
assert(asHex(fromHex({0, 0, 1, 2, 3, 4}, false)) == "00001234");
assert(asHex(fromHex({0, 1, 2, 3, 4}, false)) == "101234");
assert(asHex(fromHex({1, 2, 3, 4}, false)) == "001234");
assert(asHex(fromHex({0, 0, 1, 2, 3, 4, 5}, true)) == "30012345");
assert(asHex(fromHex({0, 0, 1, 2, 3, 4}, true)) == "20001234");
assert(asHex(fromHex({0, 1, 2, 3, 4, 5}, true)) == "20012345");
assert(asHex(fromHex({1, 2, 3, 4, 5}, true)) == "312345");
assert(asHex(fromHex({1, 2, 3, 4}, true)) == "201234");
return 0;
}

30
sha256.cpp

@ -41,7 +41,7 @@
using namespace std;
using namespace eth;
const unsigned long SHA256::sha256_k[64] = //UL = uint32
const uint32_t SHA256::sha256_k[64] = //UL = uint32_t
{0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
@ -59,11 +59,11 @@ const unsigned long SHA256::sha256_k[64] = //UL = uint32
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
void SHA256::transform(const unsigned char *message, unsigned int block_nb)
void SHA256::transform(byte const* message, unsigned block_nb)
{
uint32 w[64];
uint32 wv[8];
uint32 t1, t2;
uint32_t w[64];
uint32_t wv[8];
uint32_t t1, t2;
const unsigned char *sub_block;
int i;
int j;
@ -111,7 +111,7 @@ void SHA256::init()
m_tot_len = 0;
}
void SHA256::update(const unsigned char *message, unsigned int len)
void SHA256::update(byte const* message, unsigned len)
{
unsigned int block_nb;
unsigned int new_len, rem_len, tmp_len;
@ -134,11 +134,11 @@ void SHA256::update(const unsigned char *message, unsigned int len)
m_tot_len += (block_nb + 1) << 6;
}
void SHA256::final(unsigned char *digest)
void SHA256::final(byte* digest)
{
unsigned int block_nb;
unsigned int pm_len;
unsigned int len_b;
unsigned block_nb;
unsigned pm_len;
unsigned len_b;
int i;
block_nb = (1 + ((SHA224_256_BLOCK_SIZE - 9)
< (m_len % SHA224_256_BLOCK_SIZE)));
@ -154,15 +154,15 @@ void SHA256::final(unsigned char *digest)
}
}
std::string sha256(std::string const& _input, bool _hex)
std::string eth::sha256(std::string const& _input, bool _hex)
{
if (!_hex)
{
string ret(SHA256::DIGEST_SIZE);
string ret(SHA256::DIGEST_SIZE, '\0');
SHA256 ctx = SHA256();
ctx.init();
ctx.update( (unsigned char*)_input.c_str(), _input.length());
ctx.final(ret.data());
ctx.final((byte*)ret.data());
return ret;
}
@ -181,7 +181,7 @@ std::string sha256(std::string const& _input, bool _hex)
return std::string(buf);
}
uint256_t sha256(bytes const& _input)
uint256_t eth::sha256(bytes const& _input)
{
uint256_t ret = 0;
@ -190,7 +190,7 @@ uint256_t sha256(bytes const& _input)
ctx.update(_input.data(), _input.size());
uint8_t buf[SHA256::DIGEST_SIZE];
ctx.final(buf);
for (uint i = 0; i < 32; ++i)
for (unsigned i = 0; i < 32; ++i)
ret = (ret << 8) | buf[i];
return ret;
}

40
sha256.h

@ -1,7 +1,7 @@
#pragma once
#include <string>
#incldue "Common.h"
#include "Common.h"
#include "uint256_t.h"
namespace eth
@ -10,24 +10,20 @@ namespace eth
class SHA256
{
protected:
typedef unsigned char uint8;
typedef unsigned long uint32;
typedef unsigned long long uint64;
const static uint32 sha256_k[];
static const unsigned int SHA224_256_BLOCK_SIZE = (512/8);
const static uint32_t sha256_k[];
static const unsigned SHA224_256_BLOCK_SIZE = (512/8);
public:
void init();
void update(const unsigned char *message, unsigned int len);
void final(unsigned char *digest);
void update(byte const* message, unsigned len);
void final(byte* digest);
static const unsigned int DIGEST_SIZE = ( 256 / 8);
protected:
void transform(const unsigned char *message, unsigned int block_nb);
unsigned int m_tot_len;
unsigned int m_len;
unsigned char m_block[2*SHA224_256_BLOCK_SIZE];
uint32 m_h[8];
void transform(byte const* message, unsigned block_nb);
unsigned m_tot_len;
unsigned m_len;
byte m_block[2*SHA224_256_BLOCK_SIZE];
uint32_t m_h[8];
};
std::string sha256(std::string const& input, bool _hex);
@ -44,17 +40,17 @@ uint256_t sha256(bytes const& input);
#define SHA256_F4(x) (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10))
#define SHA2_UNPACK32(x, str) \
{ \
*((str) + 3) = (uint8) ((x) ); \
*((str) + 2) = (uint8) ((x) >> 8); \
*((str) + 1) = (uint8) ((x) >> 16); \
*((str) + 0) = (uint8) ((x) >> 24); \
*((str) + 3) = (uint8_t) ((x) ); \
*((str) + 2) = (uint8_t) ((x) >> 8); \
*((str) + 1) = (uint8_t) ((x) >> 16); \
*((str) + 0) = (uint8_t) ((x) >> 24); \
}
#define SHA2_PACK32(str, x) \
{ \
*(x) = ((uint32) *((str) + 3) ) \
| ((uint32) *((str) + 2) << 8) \
| ((uint32) *((str) + 1) << 16) \
| ((uint32) *((str) + 0) << 24); \
*(x) = ((uint32_t) *((str) + 3) ) \
| ((uint32_t) *((str) + 2) << 8) \
| ((uint32_t) *((str) + 1) << 16) \
| ((uint32_t) *((str) + 0) << 24); \
}
}

Loading…
Cancel
Save