Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactoring] Completed migration of uint* classes to blob #2314

Merged
merged 17 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b4a459b
[Refactoring] BIP38: init uint from string and use arith where needed
random-zebra Apr 14, 2021
86e177b
[Tests] Replace uint256 tests with blob_uint256 tests
random-zebra Apr 14, 2021
6488f24
[Tests] Fix arith in pedersen_hash_/skiplist_/pmt_/transaction_tests
random-zebra Apr 14, 2021
bce0583
[Refactor] zc ParamGeneration: pass big args by ref and use arith_uint
random-zebra Apr 14, 2021
f8c41ca
[Refactor] zerocoin: use arith_uint256 where needed
random-zebra Apr 14, 2021
990072e
[Refactor] Move trim256 and use arith_uint512 for HashQuark calculations
random-zebra Apr 14, 2021
b02a67b
[Refactor] Use arith_uint256 for masternode ranking computations
random-zebra Apr 14, 2021
9663d99
[Refactoring] GUI/RPC: use uint256S() to construct uint256 from string
random-zebra Apr 14, 2021
957f529
[Refactor] pow/pos: use arith_uint256 for difficulty targets
random-zebra Apr 14, 2021
22213ff
[Refactor] Migrate uint256.h/.cpp to blob_uint implementation
random-zebra Apr 14, 2021
8fe19b1
[Refactor] uint256 add missing explicit instantiation for base_blob<512>
random-zebra Apr 14, 2021
ddf0dcb
[arith_uint256] Do not destroy *this content if passed-in operator may
kallewoof Feb 26, 2018
b1c0afb
[Trivial] Log stake modifier and timeBlockFrom in CheckKernelHash()
random-zebra Apr 15, 2021
4ddd8f1
[BUG] Use arith_uint256 for old modifier's block sorting
random-zebra Apr 15, 2021
bce58ac
[Refactor] uint256: raname data --> m_data and make it protected
random-zebra Apr 14, 2021
a640051
[Refactor] uint256: update GetHex() and SetHex()
random-zebra Apr 14, 2021
722759d
[Refactor] Remove arith_uint256::GetCheapHash() and fix uint256 implem.
random-zebra Apr 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ set(UTIL_SOURCES
./src/rpc/protocol.cpp
./src/sync.cpp
./src/threadinterrupt.cpp
./src/blob_uint256.cpp
./src/arith_uint256.cpp
./src/uint256.cpp
./src/util/threadnames.cpp
Expand Down
4 changes: 0 additions & 4 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,6 @@ BITCOIN_CORE_H = \
guiinterface.h \
guiinterfaceutil.h \
uint256.h \
uint512.h \
blob_uint256.h \
undo.h \
util/memory.h \
util.h \
Expand Down Expand Up @@ -547,7 +545,6 @@ libbitcoin_util_a_SOURCES = \
sync.cpp \
threadinterrupt.cpp \
uint256.cpp \
blob_uint256.cpp \
util.cpp \
utilmoneystr.cpp \
util/threadnames.cpp \
Expand Down Expand Up @@ -689,7 +686,6 @@ libbitcoinconsensus_la_SOURCES = \
script/interpreter.cpp \
script/bitcoinconsensus.cpp \
uint256.cpp \
blob_uint256.cpp \
utilstrencodings.cpp

if GLIBC_BACK_COMPAT
Expand Down
50 changes: 46 additions & 4 deletions src/arith_uint256.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "arith_uint256.h"

#include "crypto/common.h"
#include "uint256.h"
#include "utilstrencodings.h"

#include <stdio.h>
Expand Down Expand Up @@ -74,16 +75,16 @@ base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
template <unsigned int BITS>
base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
{
base_uint<BITS> a = *this;
*this = 0;
base_uint<BITS> a;
for (int j = 0; j < WIDTH; j++) {
uint64_t carry = 0;
for (int i = 0; i + j < WIDTH; i++) {
uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
pn[i + j] = n & 0xffffffff;
uint64_t n = carry + a.pn[i + j] + (uint64_t)pn[j] * b.pn[i];
a.pn[i + j] = n & 0xffffffff;
carry = n >> 32;
}
}
*this = a;
return *this;
}

Expand Down Expand Up @@ -312,3 +313,44 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
return nCompact;
}

uint256 arith_uint512::trim256() const
{
std::vector<unsigned char> vch;
const unsigned char* p = this->begin();
for (unsigned int i = 0; i < 32; i++) {
vch.push_back(*p++);
}
return uint256(vch);
}

uint256 ArithToUint256(const arith_uint256 &a)
{
uint256 b;
for(int x=0; x<a.WIDTH; ++x)
WriteLE32(b.begin() + x*4, a.pn[x]);
return b;
}
arith_uint256 UintToArith256(const uint256 &a)
{
arith_uint256 b;
for(int x=0; x<b.WIDTH; ++x)
b.pn[x] = ReadLE32(a.begin() + x*4);
return b;
}

uint512 ArithToUint512(const arith_uint512 &a)
{
uint512 b;
for(int x=0; x<a.WIDTH; ++x)
WriteLE32(b.begin() + x*4, a.pn[x]);
return b;
}
arith_uint512 UintToArith512(const uint512 &a)
{
arith_uint512 b;
for(int x=0; x<b.WIDTH; ++x)
b.pn[x] = ReadLE32(a.begin() + x*4);
return b;
}

27 changes: 13 additions & 14 deletions src/arith_uint256.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
#ifndef BITCOIN_ARITH_UINT256_H
#define BITCOIN_ARITH_UINT256_H

#include "blob_uint256.h"
#include "uint512.h"
#include <assert.h>
#include <cstring>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>

class blob_uint512;
class blob_uint256;
class uint256;
class uint512;

Expand Down Expand Up @@ -295,15 +291,11 @@ class base_uint
s.read((char*)pn, sizeof(pn));
}

// Temporary for migration to blob160/256
uint64_t GetCheapHash() const
{
return GetLow64();
}
void SetNull()
{
memset(pn, 0, sizeof(pn));
}

bool IsNull() const
{
for (int i = 0; i < WIDTH; i++)
Expand Down Expand Up @@ -363,6 +355,9 @@ class arith_uint256 : public base_uint<256> {
arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
uint32_t GetCompact(bool fNegative = false) const;
uint32_t Get32(int n = 0) const { return pn[2 * n]; }

friend arith_uint256 UintToArith256(const uint256 &a);
friend uint256 ArithToUint256(const arith_uint256 &a);
};

/** 512-bit unsigned big integer. */
Expand All @@ -374,15 +369,19 @@ class arith_uint512 : public base_uint<512> {
explicit arith_uint512(const std::string& str) : base_uint<512>(str) {}
explicit arith_uint512(const std::vector<unsigned char>& vch) : base_uint<512>(vch) {}

//friend arith_uint512 UintToArith512(const blob_uint512 &a);
//friend blob_uint512 ArithToUint512(const arith_uint512 &a);
uint256 trim256() const;

};
friend arith_uint512 UintToArith512(const uint512 &a);
friend uint512 ArithToUint512(const arith_uint512 &a);

/** Old classes definitions */
};

/** End classes definitions */
uint256 ArithToUint256(const arith_uint256 &);
arith_uint256 UintToArith256(const uint256 &);
uint512 ArithToUint512(const arith_uint512 &);
arith_uint512 UintToArith512(const uint512 &);

const arith_uint256 ARITH_UINT256_ZERO = arith_uint256();
const arith_uint256 ARITH_UINT256_ONE = arith_uint256(1);

#endif // BITCOIN_UINT256_H
76 changes: 39 additions & 37 deletions src/bip38.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void ComputePreFactor(std::string strPassphrase, std::string strSalt, uint256& p
void ComputePassfactor(std::string ownersalt, uint256 prefactor, uint256& passfactor)
{
//concat prefactor and ownersalt
uint512 temp(ReverseEndianString(HexStr(prefactor) + ownersalt));
uint512 temp = uint512S(ReverseEndianString(HexStr(prefactor) + ownersalt));
Hash(temp.begin(), 40, passfactor.begin()); //40 bytes is the length of prefactor + salt
Hash(passfactor.begin(), 32, passfactor.begin());
}
Expand Down Expand Up @@ -110,31 +110,31 @@ std::string BIP38_Encrypt(std::string strAddress, std::string strPassphrase, uin
uint64_t salt = uint256S(ReverseEndianString(strAddressHash)).GetCheapHash();
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(salt), strAddressHash.size() / 2, BEGIN(hashed), 16384, 8, 8, 64);

uint256 derivedHalf1(hashed.ToString().substr(64, 64));
uint256 derivedHalf2(hashed.ToString().substr(0, 64));
arith_uint256 derivedHalf1(hashed.ToString().substr(64, 64));
arith_uint256 derivedHalf2(hashed.ToString().substr(0, 64));

//block1 = (pointb[1...16] xor derivedhalf1[0...15])
uint256 block1 = uint256((privKey << 128) ^ (derivedHalf1 << 128)) >> 128;
arith_uint256 block1 = ((UintToArith256(privKey) << 128) ^ (derivedHalf1 << 128)) >> 128;

//encrypt part 1
uint512 encrypted1;
arith_uint512 encrypted1;
AES_KEY key;
AES_set_encrypt_key(derivedHalf2.begin(), 256, &key);
AES_encrypt(block1.begin(), encrypted1.begin(), &key);

//block2 = (pointb[17...32] xor derivedhalf1[16...31]
uint256 p2 = privKey >> 128;
uint256 dh12 = derivedHalf1 >> 128;
uint256 block2 = uint256(p2 ^ dh12);
arith_uint256 p2 = UintToArith256(privKey) >> 128;
arith_uint256 dh12 = derivedHalf1 >> 128;
arith_uint256 block2 = p2 ^ dh12;

//encrypt part 2
uint512 encrypted2;
arith_uint512 encrypted2;
AES_encrypt(block2.begin(), encrypted2.begin(), &key);

std::string strPrefix = "0142";
strPrefix += (fCompressed ? "E0" : "C0");

uint512 encryptedKey(ReverseEndianString(strPrefix + strAddressHash));
arith_uint512 encryptedKey(ReverseEndianString(strPrefix + strAddressHash));

//add encrypted1 to the end of encryptedKey
encryptedKey = encryptedKey | (encrypted1 << 56);
Expand All @@ -144,7 +144,7 @@ std::string BIP38_Encrypt(std::string strAddress, std::string strPassphrase, uin

//Base58 checksum is the 4 bytes of dSHA256 hash of the encrypted key
uint256 hashChecksum = Hash(encryptedKey.begin(), encryptedKey.begin() + 39);
uint512 b58Checksum(hashChecksum.ToString().substr(64 - 8, 8));
arith_uint512 b58Checksum(hashChecksum.ToString().substr(64 - 8, 8));

// append the encrypted key with checksum (currently occupies 312 bits)
encryptedKey = encryptedKey | (b58Checksum << 312);
Expand All @@ -162,27 +162,27 @@ bool BIP38_Decrypt(std::string strPassphrase, std::string strEncryptedKey, uint2
return false;

//invalid prefix
if (uint256(ReverseEndianString(strKey.substr(0, 2))) != uint256(0x01))
if (uint256S(ReverseEndianString(strKey.substr(0, 2))) != UINT256_ONE)
return false;

uint256 type(ReverseEndianString(strKey.substr(2, 2)));
uint256 flag(ReverseEndianString(strKey.substr(4, 2)));
arith_uint256 type(ReverseEndianString(strKey.substr(2, 2)));
arith_uint256 flag(ReverseEndianString(strKey.substr(4, 2)));
std::string strAddressHash = strKey.substr(6, 8);
std::string ownersalt = strKey.substr(14, 16);
uint256 encryptedPart1(ReverseEndianString(strKey.substr(30, 16)));
uint256 encryptedPart2(ReverseEndianString(strKey.substr(46, 32)));
uint256 encryptedPart1 = uint256S(ReverseEndianString(strKey.substr(30, 16)));
uint256 encryptedPart2 = uint256S(ReverseEndianString(strKey.substr(46, 32)));

fCompressed = (flag & uint256(0x20)) != 0;
fCompressed = (flag & 0x20) != ARITH_UINT256_ZERO;

//not ec multiplied
if (type == uint256(0x42)) {
if (type == arith_uint256(0x42)) {
uint512 hashed;
encryptedPart1 = uint256(ReverseEndianString(strKey.substr(14, 32)));
encryptedPart1 = uint256S(ReverseEndianString(strKey.substr(14, 32)));
uint64_t salt = uint256S(ReverseEndianString(strAddressHash)).GetCheapHash();
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(salt), strAddressHash.size() / 2, BEGIN(hashed), 16384, 8, 8, 64);

uint256 derivedHalf1(uint256S(hashed.ToString().substr(64, 64)));
uint256 derivedHalf2(uint256S(hashed.ToString().substr(0, 64)));
const uint256& derivedHalf1 = uint256S(hashed.ToString().substr(64, 64));
const uint256& derivedHalf2 = uint256S(hashed.ToString().substr(0, 64));

uint256 decryptedPart1;
DecryptAES(encryptedPart1, derivedHalf2, decryptedPart1);
Expand All @@ -191,15 +191,17 @@ bool BIP38_Decrypt(std::string strPassphrase, std::string strEncryptedKey, uint2
DecryptAES(encryptedPart2, derivedHalf2, decryptedPart2);

//combine decrypted parts into 64 bytes
uint256 temp1 = decryptedPart2 << 128;
temp1 = temp1 | decryptedPart1;
arith_uint256 temp1 = UintToArith256(decryptedPart2) << 128;
temp1 = temp1 | UintToArith256(decryptedPart1);

//xor the decryption with the derived half 1 for the final key
privKey = temp1 ^ derivedHalf1;
privKey = ArithToUint256(temp1 ^ UintToArith256(derivedHalf1));

return true;
} else if (type != uint256(0x43)) //invalid type
} else if (type != arith_uint256(0x43)) {
//invalid type
return false;
}

bool fLotSequence = (flag & 0x04) != 0;

Expand All @@ -224,32 +226,32 @@ bool BIP38_Decrypt(std::string strPassphrase, std::string strEncryptedKey, uint2
ComputeSeedBPass(passpoint, strAddressHash, ownersalt, seedBPass);

//get derived halfs, being mindful for endian switch
uint256 derivedHalf1(uint256S(seedBPass.ToString().substr(64, 64)));
uint256 derivedHalf2(uint256S(seedBPass.ToString().substr(0, 64)));
const uint256 derivedHalf1 = uint256S(seedBPass.ToString().substr(64, 64));
const uint256 derivedHalf2 = uint256S(seedBPass.ToString().substr(0, 64));

/** Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1. **/
uint256 decryptedPart2;
DecryptAES(encryptedPart2, derivedHalf2, decryptedPart2);

//xor decryptedPart2 and 2nd half of derived half 1
uint256 x0 = derivedHalf1 >> 128; //drop off the first half (note: endian)
uint256 x1 = decryptedPart2 ^ x0;
uint256 seedbPart2 = x1 >> 64;
arith_uint256 x0 = UintToArith256(derivedHalf1) >> 128; //drop off the first half (note: endian)
arith_uint256 x1 = UintToArith256(decryptedPart2) ^ x0;
arith_uint256 seedbPart2 = x1 >> 64;

/** Decrypt encryptedpart1 to yield the remainder of seedb. **/
uint256 decryptedPart1;
uint256 x2 = x1 & uint256("0xffffffffffffffff"); // set x2 to seedbPart1 (still encrypted)
arith_uint256 x2 = x1 & arith_uint256("0xffffffffffffffff"); // set x2 to seedbPart1 (still encrypted)
x2 = x2 << 64; //make room to add encryptedPart1 to the front
x2 = encryptedPart1 | x2; //combine with encryptedPart1
DecryptAES(x2, derivedHalf2, decryptedPart1);
x2 = UintToArith256(encryptedPart1) | x2; //combine with encryptedPart1
DecryptAES(ArithToUint256(x2), derivedHalf2, decryptedPart1);

//decrypted part 1: seedb[0..15] xor derivedhalf1[0..15]
uint256 x3 = derivedHalf1 & uint256("0xffffffffffffffffffffffffffffffff");
uint256 seedbPart1 = decryptedPart1 ^ x3;
uint256 seedB = seedbPart1 | (seedbPart2 << 128);
arith_uint256 x3 = UintToArith256(derivedHalf1) & arith_uint256("0xffffffffffffffffffffffffffffffff");
arith_uint256 seedbPart1 = UintToArith256(decryptedPart1) ^ x3;
arith_uint256 seedB = seedbPart1 | (seedbPart2 << 128);

uint256 factorB;
ComputeFactorB(seedB, factorB);
ComputeFactorB(ArithToUint256(seedB), factorB);

//multiply passfactor by factorb mod N to yield the priv key
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
Expand Down
Loading