◇ BIGNUMとは?

メモリを動的確保(ヒープ)で管理しながら任意桁数を扱うことが可能な巨大整数クラスとなります。ただし「動的確保(ヒープ)」となりますので速度は遅くなります。
※ 一方でサイズ上限は256bitとなりますが固定長のuint256のメモリはスタックで処理できます。uint256は内部でstd::vectorを使わない純粋なuint8_t 32個連結のオブジェクトになります。

OpenSSLに付属する専用関数を専用の構造体を経由して処理しております。もちろんCBigNumというクラスが定義されておりました。ただ……ブロックチェーンでは上限が限られた場面が多いため、 最新のビットコイン系コアでは固定長の処理に置き換わっており(CScriptNum)、CBigNumは使われておりません。そのためこの周辺はすべてCScriptNumに置き換えて対応いたしました。しかしStakeなどで多用するmodifierが絡む処理が存在するコアでは modifierとチェックサムの計算にCBigNumの任意桁数の計算が必要ゆえ本クラスを残しております。

◇ サンプルコード

using bignum_vector = std::vector<uint8_t>;

CBigNum bnTarget1(123456789);
uint256 u256Target1(123456789);
assert(bnTarget1.getuint256()==u256Target1);

bignum_vector vch;
for (int i=1; i<33; ++i)
    vch.push_back((uint8_t)i);
assert(vch.size()==sizeof(uint256));
CBigNum bnTarget2(vch);
uint256 u256Target2(vch);
assert(bnTarget2.getuint256()==u256Target2);

bnTarget2 -= bnTarget1;
u256Target2 -= u256Target1;
assert(bnTarget2.getuint256()==u256Target2);

assert(~bnTarget2.getuint256()==~u256Target2);

bnTarget2 >>= 136;
u256Target2 >>= 136;
assert(bnTarget2.getuint256()==u256Target2);

assert(bnTarget2.getuint64()==u256Target2.GetLow64());
assert(bnTarget2.getuint<uint32_t>()==(u256Target2.GetLow64() & ((~uint64_t(0))>>32)));

uint256b u256Target3(u256Target2);
assert(bnTarget2.GetCompact()==u256Target3.GetCompact());