Skip to content

Commit 4d6b532

Browse files
committed
psbt: implement hash preimages fields
1 parent ac92ab6 commit 4d6b532

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

src/psbt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ void PSBTInput::Merge(const PSBTInput& input)
153153
}
154154

155155
partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end());
156+
ripemd160_preimages.insert(input.ripemd160_preimages.begin(), input.ripemd160_preimages.end());
157+
sha256_preimages.insert(input.sha256_preimages.begin(), input.sha256_preimages.end());
158+
hash160_preimages.insert(input.hash160_preimages.begin(), input.hash160_preimages.end());
159+
hash256_preimages.insert(input.hash256_preimages.begin(), input.hash256_preimages.end());
156160
hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end());
157161
unknown.insert(input.unknown.begin(), input.unknown.end());
158162

src/psbt.h

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05;
3737
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
3838
static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
3939
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
40+
static constexpr uint8_t PSBT_IN_RIPEMD160 = 0x0A;
41+
static constexpr uint8_t PSBT_IN_SHA256 = 0x0B;
42+
static constexpr uint8_t PSBT_IN_HASH160 = 0x0C;
43+
static constexpr uint8_t PSBT_IN_HASH256 = 0x0D;
4044
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
4145

4246
// Output types
@@ -171,6 +175,10 @@ struct PSBTInput
171175
CScriptWitness final_script_witness;
172176
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
173177
std::map<CKeyID, SigPair> partial_sigs;
178+
std::map<uint160, std::vector<unsigned char>> ripemd160_preimages;
179+
std::map<uint256, std::vector<unsigned char>> sha256_preimages;
180+
std::map<uint160, std::vector<unsigned char>> hash160_preimages;
181+
std::map<uint256, std::vector<unsigned char>> hash256_preimages;
174182
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
175183
std::set<PSBTProprietary> m_proprietary;
176184
std::optional<int> sighash_type;
@@ -221,6 +229,30 @@ struct PSBTInput
221229

222230
// Write any hd keypaths
223231
SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION));
232+
233+
// Write any ripemd160 preimage
234+
for (const auto& [hash, preimage] : ripemd160_preimages) {
235+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), Span{hash});
236+
s << preimage;
237+
}
238+
239+
// Write any sha256 preimage
240+
for (const auto& [hash, preimage] : sha256_preimages) {
241+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), Span{hash});
242+
s << preimage;
243+
}
244+
245+
// Write any hash160 preimage
246+
for (const auto& [hash, preimage] : hash160_preimages) {
247+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), Span{hash});
248+
s << preimage;
249+
}
250+
251+
// Write any hash256 preimage
252+
for (const auto& [hash, preimage] : hash256_preimages) {
253+
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), Span{hash});
254+
s << preimage;
255+
}
224256
}
225257

226258
// Write script sig
@@ -373,6 +405,90 @@ struct PSBTInput
373405
UnserializeFromVector(s, final_script_witness.stack);
374406
break;
375407
}
408+
case PSBT_IN_RIPEMD160:
409+
{
410+
// Make sure that the key is the size of a ripemd160 hash + 1
411+
if (key.size() != CRIPEMD160::OUTPUT_SIZE + 1) {
412+
throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage");
413+
}
414+
// Read in the hash from key
415+
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
416+
uint160 hash(hash_vec);
417+
if (ripemd160_preimages.count(hash) > 0) {
418+
throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided");
419+
}
420+
421+
// Read in the preimage from value
422+
std::vector<unsigned char> preimage;
423+
s >> preimage;
424+
425+
// Add to preimages list
426+
ripemd160_preimages.emplace(hash, std::move(preimage));
427+
break;
428+
}
429+
case PSBT_IN_SHA256:
430+
{
431+
// Make sure that the key is the size of a sha256 hash + 1
432+
if (key.size() != CSHA256::OUTPUT_SIZE + 1) {
433+
throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage");
434+
}
435+
// Read in the hash from key
436+
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
437+
uint256 hash(hash_vec);
438+
if (sha256_preimages.count(hash) > 0) {
439+
throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided");
440+
}
441+
442+
// Read in the preimage from value
443+
std::vector<unsigned char> preimage;
444+
s >> preimage;
445+
446+
// Add to preimages list
447+
sha256_preimages.emplace(hash, std::move(preimage));
448+
break;
449+
}
450+
case PSBT_IN_HASH160:
451+
{
452+
// Make sure that the key is the size of a hash160 hash + 1
453+
if (key.size() != CHash160::OUTPUT_SIZE + 1) {
454+
throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage");
455+
}
456+
// Read in the hash from key
457+
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
458+
uint160 hash(hash_vec);
459+
if (hash160_preimages.count(hash) > 0) {
460+
throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided");
461+
}
462+
463+
// Read in the preimage from value
464+
std::vector<unsigned char> preimage;
465+
s >> preimage;
466+
467+
// Add to preimages list
468+
hash160_preimages.emplace(hash, std::move(preimage));
469+
break;
470+
}
471+
case PSBT_IN_HASH256:
472+
{
473+
// Make sure that the key is the size of a hash256 hash + 1
474+
if (key.size() != CHash256::OUTPUT_SIZE + 1) {
475+
throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage");
476+
}
477+
// Read in the hash from key
478+
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
479+
uint256 hash(hash_vec);
480+
if (hash256_preimages.count(hash) > 0) {
481+
throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided");
482+
}
483+
484+
// Read in the preimage from value
485+
std::vector<unsigned char> preimage;
486+
s >> preimage;
487+
488+
// Add to preimages list
489+
hash256_preimages.emplace(hash, std::move(preimage));
490+
break;
491+
}
376492
case PSBT_IN_PROPRIETARY:
377493
{
378494
PSBTProprietary this_prop;

0 commit comments

Comments
 (0)