Skip to content

Commit b4a459b

Browse files
committed
[Refactoring] BIP38: init uint from string and use arith where needed
1 parent 948bb36 commit b4a459b

File tree

1 file changed

+39
-37
lines changed

1 file changed

+39
-37
lines changed

src/bip38.cpp

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void ComputePreFactor(std::string strPassphrase, std::string strSalt, uint256& p
4141
void ComputePassfactor(std::string ownersalt, uint256 prefactor, uint256& passfactor)
4242
{
4343
//concat prefactor and ownersalt
44-
uint512 temp(ReverseEndianString(HexStr(prefactor) + ownersalt));
44+
uint512 temp = uint512S(ReverseEndianString(HexStr(prefactor) + ownersalt));
4545
Hash(temp.begin(), 40, passfactor.begin()); //40 bytes is the length of prefactor + salt
4646
Hash(passfactor.begin(), 32, passfactor.begin());
4747
}
@@ -110,31 +110,31 @@ std::string BIP38_Encrypt(std::string strAddress, std::string strPassphrase, uin
110110
uint64_t salt = uint256S(ReverseEndianString(strAddressHash)).GetCheapHash();
111111
scrypt_hash(strPassphrase.c_str(), strPassphrase.size(), BEGIN(salt), strAddressHash.size() / 2, BEGIN(hashed), 16384, 8, 8, 64);
112112

113-
uint256 derivedHalf1(hashed.ToString().substr(64, 64));
114-
uint256 derivedHalf2(hashed.ToString().substr(0, 64));
113+
arith_uint256 derivedHalf1(hashed.ToString().substr(64, 64));
114+
arith_uint256 derivedHalf2(hashed.ToString().substr(0, 64));
115115

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

119119
//encrypt part 1
120-
uint512 encrypted1;
120+
arith_uint512 encrypted1;
121121
AES_KEY key;
122122
AES_set_encrypt_key(derivedHalf2.begin(), 256, &key);
123123
AES_encrypt(block1.begin(), encrypted1.begin(), &key);
124124

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

130130
//encrypt part 2
131-
uint512 encrypted2;
131+
arith_uint512 encrypted2;
132132
AES_encrypt(block2.begin(), encrypted2.begin(), &key);
133133

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

137-
uint512 encryptedKey(ReverseEndianString(strPrefix + strAddressHash));
137+
arith_uint512 encryptedKey(ReverseEndianString(strPrefix + strAddressHash));
138138

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

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

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

164164
//invalid prefix
165-
if (uint256(ReverseEndianString(strKey.substr(0, 2))) != uint256(0x01))
165+
if (uint256S(ReverseEndianString(strKey.substr(0, 2))) != UINT256_ONE)
166166
return false;
167167

168-
uint256 type(ReverseEndianString(strKey.substr(2, 2)));
169-
uint256 flag(ReverseEndianString(strKey.substr(4, 2)));
168+
arith_uint256 type(ReverseEndianString(strKey.substr(2, 2)));
169+
arith_uint256 flag(ReverseEndianString(strKey.substr(4, 2)));
170170
std::string strAddressHash = strKey.substr(6, 8);
171171
std::string ownersalt = strKey.substr(14, 16);
172-
uint256 encryptedPart1(ReverseEndianString(strKey.substr(30, 16)));
173-
uint256 encryptedPart2(ReverseEndianString(strKey.substr(46, 32)));
172+
uint256 encryptedPart1 = uint256S(ReverseEndianString(strKey.substr(30, 16)));
173+
uint256 encryptedPart2 = uint256S(ReverseEndianString(strKey.substr(46, 32)));
174174

175-
fCompressed = (flag & uint256(0x20)) != 0;
175+
fCompressed = (flag & 0x20) != ARITH_UINT256_ZERO;
176176

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

184-
uint256 derivedHalf1(uint256S(hashed.ToString().substr(64, 64)));
185-
uint256 derivedHalf2(uint256S(hashed.ToString().substr(0, 64)));
184+
const uint256& derivedHalf1 = uint256S(hashed.ToString().substr(64, 64));
185+
const uint256& derivedHalf2 = uint256S(hashed.ToString().substr(0, 64));
186186

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

193193
//combine decrypted parts into 64 bytes
194-
uint256 temp1 = decryptedPart2 << 128;
195-
temp1 = temp1 | decryptedPart1;
194+
arith_uint256 temp1 = UintToArith256(decryptedPart2) << 128;
195+
temp1 = temp1 | UintToArith256(decryptedPart1);
196196

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

200200
return true;
201-
} else if (type != uint256(0x43)) //invalid type
201+
} else if (type != arith_uint256(0x43)) {
202+
//invalid type
202203
return false;
204+
}
203205

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

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

226228
//get derived halfs, being mindful for endian switch
227-
uint256 derivedHalf1(uint256S(seedBPass.ToString().substr(64, 64)));
228-
uint256 derivedHalf2(uint256S(seedBPass.ToString().substr(0, 64)));
229+
const uint256 derivedHalf1 = uint256S(seedBPass.ToString().substr(64, 64));
230+
const uint256 derivedHalf2 = uint256S(seedBPass.ToString().substr(0, 64));
229231

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

234236
//xor decryptedPart2 and 2nd half of derived half 1
235-
uint256 x0 = derivedHalf1 >> 128; //drop off the first half (note: endian)
236-
uint256 x1 = decryptedPart2 ^ x0;
237-
uint256 seedbPart2 = x1 >> 64;
237+
arith_uint256 x0 = UintToArith256(derivedHalf1) >> 128; //drop off the first half (note: endian)
238+
arith_uint256 x1 = UintToArith256(decryptedPart2) ^ x0;
239+
arith_uint256 seedbPart2 = x1 >> 64;
238240

239241
/** Decrypt encryptedpart1 to yield the remainder of seedb. **/
240242
uint256 decryptedPart1;
241-
uint256 x2 = x1 & uint256("0xffffffffffffffff"); // set x2 to seedbPart1 (still encrypted)
243+
arith_uint256 x2 = x1 & arith_uint256("0xffffffffffffffff"); // set x2 to seedbPart1 (still encrypted)
242244
x2 = x2 << 64; //make room to add encryptedPart1 to the front
243-
x2 = encryptedPart1 | x2; //combine with encryptedPart1
244-
DecryptAES(x2, derivedHalf2, decryptedPart1);
245+
x2 = UintToArith256(encryptedPart1) | x2; //combine with encryptedPart1
246+
DecryptAES(ArithToUint256(x2), derivedHalf2, decryptedPart1);
245247

246248
//decrypted part 1: seedb[0..15] xor derivedhalf1[0..15]
247-
uint256 x3 = derivedHalf1 & uint256("0xffffffffffffffffffffffffffffffff");
248-
uint256 seedbPart1 = decryptedPart1 ^ x3;
249-
uint256 seedB = seedbPart1 | (seedbPart2 << 128);
249+
arith_uint256 x3 = UintToArith256(derivedHalf1) & arith_uint256("0xffffffffffffffffffffffffffffffff");
250+
arith_uint256 seedbPart1 = UintToArith256(decryptedPart1) ^ x3;
251+
arith_uint256 seedB = seedbPart1 | (seedbPart2 << 128);
250252

251253
uint256 factorB;
252-
ComputeFactorB(seedB, factorB);
254+
ComputeFactorB(ArithToUint256(seedB), factorB);
253255

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

0 commit comments

Comments
 (0)