Files
Peya/tests/unit_tests/bulletproofs.cpp
2025-03-31 10:49:39 +03:00

314 lines
59 KiB
C++

// Copyright (c) 2017-2022, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "gtest/gtest.h"
#include "string_tools.h"
#include "ringct/rctOps.h"
#include "ringct/rctSigs.h"
#include "ringct/bulletproofs.h"
#include "cryptonote_basic/blobdatatype.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "device/device.hpp"
#include "misc_log_ex.h"
TEST(bulletproofs, valid_zero)
{
rct::Bulletproof proof = bulletproof_PROVE(0, rct::skGen());
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
}
TEST(bulletproofs, valid_max)
{
rct::Bulletproof proof = bulletproof_PROVE(0xffffffffffffffff, rct::skGen());
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
}
TEST(bulletproofs, valid_random)
{
for (int n = 0; n < 8; ++n)
{
rct::Bulletproof proof = bulletproof_PROVE(crypto::rand<uint64_t>(), rct::skGen());
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
}
}
TEST(bulletproofs, valid_multi_random)
{
for (int n = 0; n < 8; ++n)
{
size_t outputs = 2 + n;
std::vector<uint64_t> amounts;
rct::keyV gamma;
for (size_t i = 0; i < outputs; ++i)
{
amounts.push_back(crypto::rand<uint64_t>());
gamma.push_back(rct::skGen());
}
rct::Bulletproof proof = bulletproof_PROVE(amounts, gamma);
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
}
}
TEST(bulletproofs, multi_splitting)
{
rct::ctkeyV sc, pc;
rct::ctkey sctmp, pctmp;
std::vector<unsigned int> index;
std::vector<uint64_t> inamounts, outamounts;
std::tie(sctmp, pctmp) = rct::ctskpkGen(6000);
sc.push_back(sctmp);
pc.push_back(pctmp);
inamounts.push_back(6000);
index.push_back(1);
std::tie(sctmp, pctmp) = rct::ctskpkGen(7000);
sc.push_back(sctmp);
pc.push_back(pctmp);
inamounts.push_back(7000);
index.push_back(1);
const int mixin = 3, max_outputs = 16;
for (int n_outputs = 1; n_outputs <= max_outputs; ++n_outputs)
{
std::vector<uint64_t> outamounts;
rct::keyV amount_keys;
rct::keyV destinations;
rct::key Sk, Pk;
uint64_t available = 6000 + 7000;
uint64_t amount;
rct::ctkeyM mixRing(sc.size());
//add output
for (size_t i = 0; i < n_outputs; ++i)
{
amount = rct::randXmrAmount(available);
outamounts.push_back(amount);
amount_keys.push_back(rct::hash_to_scalar(rct::zero()));
rct::skpkGen(Sk, Pk);
destinations.push_back(Pk);
available -= amount;
}
for (size_t i = 0; i < sc.size(); ++i)
{
for (size_t j = 0; j <= mixin; ++j)
{
if (j == 1)
mixRing[i].push_back(pc[i]);
else
mixRing[i].push_back({rct::scalarmultBase(rct::skGen()), rct::scalarmultBase(rct::skGen())});
}
}
rct::ctkeyV outSk;
rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 4 };
cryptonote::transaction_type tx_type = cryptonote::transaction_type::TRANSFER;
std::string in_asset_type = "SAL";
std::vector<std::string> destination_asset_types;
for (size_t i = 0; i < destinations.size(); ++i)
destination_asset_types.push_back("SAL");
rct::salvium_data_t salvium_data;
rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, available, mixRing, amount_keys, index, outSk, rct_config, hw::get_device("default"), salvium_data);
ASSERT_TRUE(rct::verRctSimple(s));
for (size_t i = 0; i < n_outputs; ++i)
{
rct::key mask;
rct::decodeRctSimple(s, amount_keys[i], i, mask, hw::get_device("default"));
ASSERT_TRUE(mask == outSk[i].mask);
}
}
}
TEST(bulletproofs, valid_aggregated)
{
static const size_t N_PROOFS = 8;
std::vector<rct::Bulletproof> proofs(N_PROOFS);
for (size_t n = 0; n < N_PROOFS; ++n)
{
size_t outputs = 2 + n;
std::vector<uint64_t> amounts;
rct::keyV gamma;
for (size_t i = 0; i < outputs; ++i)
{
amounts.push_back(crypto::rand<uint64_t>());
gamma.push_back(rct::skGen());
}
proofs[n] = bulletproof_PROVE(amounts, gamma);
}
ASSERT_TRUE(rct::bulletproof_VERIFY(proofs));
}
TEST(bulletproofs, invalid_8)
{
rct::key invalid_amount = rct::zero();
invalid_amount[8] = 1;
rct::Bulletproof proof = bulletproof_PROVE(invalid_amount, rct::skGen());
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
}
TEST(bulletproofs, invalid_31)
{
rct::key invalid_amount = rct::zero();
invalid_amount[31] = 1;
rct::Bulletproof proof = bulletproof_PROVE(invalid_amount, rct::skGen());
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
}
static const char * const torsion_elements[] =
{
"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa",
"0000000000000000000000000000000000000000000000000000000000000000",
"26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85",
"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
"26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05",
"0000000000000000000000000000000000000000000000000000000000000080",
"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a",
};
TEST(bulletproofs, invalid_torsion)
{
rct::Bulletproof proof = bulletproof_PROVE(7329838943733, rct::skGen());
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
for (const auto &xs: torsion_elements)
{
rct::key x;
ASSERT_TRUE(epee::string_tools::hex_to_pod(xs, x));
ASSERT_FALSE(rct::isInMainSubgroup(x));
for (auto &k: proof.V)
{
const rct::key org_k = k;
rct::addKeys(k, org_k, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
k = org_k;
}
for (auto &k: proof.L)
{
const rct::key org_k = k;
rct::addKeys(k, org_k, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
k = org_k;
}
for (auto &k: proof.R)
{
const rct::key org_k = k;
rct::addKeys(k, org_k, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
k = org_k;
}
const rct::key org_A = proof.A;
rct::addKeys(proof.A, org_A, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
proof.A = org_A;
const rct::key org_S = proof.S;
rct::addKeys(proof.S, org_S, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
proof.S = org_S;
const rct::key org_T1 = proof.T1;
rct::addKeys(proof.T1, org_T1, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
proof.T1 = org_T1;
const rct::key org_T2 = proof.T2;
rct::addKeys(proof.T2, org_T2, x);
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
proof.T2 = org_T2;
}
}
TEST(bulletproof, weight_equal)
{
static const char *tx_hex = "03000102000353414c109b0228460a108b012b0b222a070809051f07ae107e5e48256044e3e8b71d1e0fd6194d13695bd4fbd454ebb296b451bb3c2302000337b3183a3fcf3be80bd933a97b06f9222b05adad1a2db7c70f1f688889cbcb200353414c00c400036a1958fc465756119598e91880bf9b4b2dfa5ec3bce0bb7b9647827ed78b3ccf0353414c009d2c014cc167aff402f99b1e435e035745d73fcb396d176d38a2f3135b757bc3f0755b0209011568baaf30dbfed10300029af771773dcd73dd7f447b2f0b38357b76df6781adb41efab5f0f0aa588d6b968c3505354384e6f5dad2cef9c880f333de53f9a473af0ac268dcc3a947840e4002c94f0353414c0353414c000780f2390077d8e8ba53e2b1f8e890fcecbaa600f98915ebcdd7e9bd716002ce232120f4d725dff0c7b0530dfffbb7d9640730de923bebd5b8bdd7dbd0f93c0e2d99657afe6a559e52312672fa658577c3b083624b74735ec153f124c09989f69803de66070937293199aa63b92ef7435d06017420edafa6366d7fe1017c99521efc6d624741649aaf7ffc69818e323677021af9a7e40d0328b0e0029d9de4f11209795419518ba17c084ce0adc579d2fb7e2803000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d616aff200f1dfb71a4a445b57c310e36c96715673e2cd0f272e740c7e0dd33eb5bd0f0d0a912d93508a0e42f6c8052045a237d3a38a7490698e3d644102db5a5eb6d34c1bf38afdb315e2a3058e572bd8dc82ee44d2efb5dd5c334a2056499404840d9855daa80fab147587109f83ce27e1e77c2e0a93eed20759426a4ced0b7af18666b2fe55ed61045315b7c76655002496c1135581dade6c5d152ae72404b9a822a223d17acbe13a32befb8509610d4d7d454497f3b565e5cb0e2b12f500076f1dee958772b8254a3b8d8a3b29476f9aaae4aaa54556160b1ec4f05aa4fa18eb104b32a449ee98092e82d175270418779c3d988f17a8629c6a0dfc73dc31ffa92caef528ae2fd98024eed2380d8cfe3b3875cb72222202ce8de21c57191d49aec613bb88a63e1322793ccdb753f3c5daa62c1644e3b4f4084c506d00fe9ef81753a174803b9359cff01ac18bdbec03f1e8a4379e01d9efcbb134453b83f13c7cf75dd0a1eb3580859f0964dc68e0d97402b677611490b24031254636d60b7dfb267c1062eca784b217ae40c266ea2e42458993102f366c1145eb460aba87a807eb307b69c332a24de1801c231f3fe2cafa6f4ceda119b2557a00174510ba312f4ca1445bb8576db71027da0a0f60f8fd1c2cccbae4db960465abeec927ca4273b5ba371cce01115adda7d128ec758065df14bf37565b0e89e712ab51891096a9ffa726a29c150fb8affe19afd4e569ad759623358e99c1073f7dec0715f59a6f42182cfffebf99e925612d1c335df476aaa7156edd26c7154e4cd337347dbd3c153b88fefce883f9d3efccd995e517058b38460d121b6c90b3e01b916f5ba2b88c450e346cdf2cfc549e004ccbebf7bd84b819281203141d2749538252ab03ff72d75cb637796420dceef3fefce392b92c31acc9ee5c7612fc1e3768a35b290b027a16fb274396841349a5aa6769e9858cfad9e3c5e6e1ae13c298297e5eea0b6219209be0b881140488ed2028ab8060384de2be37728208429eac3d62d10501ca5a95be599df2bc70a8db1019e0971688e1c3b859231f79bf35ac3bec180c0c2e5ddf1efd0482a1864b5524457611120060e5976393d5a710e7a5770250ff08b8d8fa0fac937095d4bf4aaec09b5482e7499e0e25fd7d536e449e7918239c07b77eecca0fffc2af2b004292d8c2797832e5bc833cc2628377f4d534b9d0d90c0f09683b8a3cff0a6bb05ee3f03a9ea3568f1e4b60c15776e09e848c7e440b0bd3e29dd1d892ef31eacf162cad0865487407102d1ac6ee1eef46edb0ed864f0dc29b78dee96d9b740fcf2f330e67c0b961feab53b93ee4fee84e2f8557f4e9050f1facffe67af38ade44b43cc8730178d557781b293bb3fb7c84ff08865c140a6d8065ce1143135f27690c4dc4a737c21bce411a13e4caeb9a02433430416e0eb815fb05cc56f30d5d4ed62941ae66443f9f5bda1bf0633997acad171d1058064d18e012fa297609bf76742bf43d5c1b82c3075860497d0a1a2ce7b469613e0dc3461ef5d818d61e4cafabada94f1da2352f8474d132d57d0f967e097c67be09537d30d615dd456622317866bbc781503fbd06623995328bdddcea50ff4ec00e7b7d6f5ccea111938b83b4c4c7403cb7f093022997123fed1e721753aced7d08ad6984cc31d8f3f9519a1ea59915f52388df494294ac632932ee6fd69e2c55c87b2687b4de8b1ea36742ebb335b8b7970655ee337ad07a230e460a6de6b2784e";
cryptonote::blobdata bd;
ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(std::string(tx_hex), bd));
cryptonote::transaction tx;
crypto::hash tx_hash, tx_prefix_hash;
ASSERT_TRUE(parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash));
ASSERT_TRUE(tx.version == 3); // >=2
ASSERT_TRUE(rct::is_rct_bulletproof_plus(tx.rct_signatures.type)); // salvium started with bulletproof+
const uint64_t tx_size = bd.size();
const uint64_t tx_weight = cryptonote::get_transaction_weight(tx);
ASSERT_TRUE(tx_weight == tx_size); // it has two outputs, <= 2 makes weight == size
}
TEST(bulletproof, weight_more)
{
static const char *tx_hex = "03000102000353414c1084011b3a5862762804340e2c051008290192eabd619159292e5ee0c5db6f1aa08bd8f0b6f8841a1438be230e342e8dd81a040003dfefaebbbf67ab663d33843c0a3cdfd16a4b1c7c1a0b5d2513f28d18074eb8d50353414c008c0003dea84cb300eb5e78f206d2032e035e9b82b00e292a2ccf0ae5320bf7cf4f913e0353414c00ae0003c822a8022a4a75bfcf18e5157e276fe36ae6ed8e711cc487dfbcdc699ab287010353414c0083000379d7c5b3d9783ad6071ce85f20f5c1a5bec667d207865b516d3c3f43665a82160353414c004421011164d4ef7508481ae0c484ad3aa1b5cc94841ea369c63b8bc80512bfce0a4ce7030004398065f6a6f4f8570653ceb9d4d9d23c6c93f8f412470fc61b2f964cc43cd01637dae7b49ccd40ca74ce410d489ac253c298e85a10891ebc880447db1c7dc3ecdca42b7d0184af000b1ede6bc246383bb0a60398ee35d0f8a5db53bb25d170f76eeb4d8358e5f4e3d54bd548d215495fe92984ec5b81a8e10f6c1257947a5f57045a8b87d30353414c0353414c000790a8516619d79602a51808c3985156d14e91b10975bd8307a7f717489336d76c2b9d4f83378e4bc1e02eadb3dc11cfc13ca8910fc427f677aae64b8fea10cd6f55cfc343cf53a55db77a00086326e02342cea331ef39eb0dbcb0841c75bf612f23e07785e992c95dab2d4b6637809f385458ef34ae05755c2041087dd5afc22ae19f935249cdd06f99fe8ac6d58041616157c9177052b2d8866c30b4c797288a60f9e00e1619a8038197863961eb4801a3149b35cec3d34f59cd50c4e7e497967e788fa47ae6b7e67e46729a255e98600a87d19b48ad3b6d651f53114a3ed8104899be6929ccaa1805ebea6710845afb073c01c7e464a9af6793840a9bad72f7219b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b489302476e2e85796f1e83c0fe386b65bb0b8b82fe772a69bf3377de2caa320a39771c14d3c9d5996c5f3cc9d2d58da813a77891e20c9033a245eb29ef77e8db5ab6b9574034e226a7db5c898e92165be2cf7525bb6d8279073d67b20fca12c24f0fd926be97c5a8fd491b1f41e0299cd757f80d8dfcbaae20a55a7263830f619f6dcda5efd1724952d9a6a988f1b809d40cb0d17fce96ea056b46a8da8b02753244327091fc8a8e5bfe32edc03c21125a033b1dfc37ee89243aa1be8fcd0b08e195681eddd5840f51a7d3b766e56af84f9b92eb47e7542f869a758e325e24476e79fa43b65cdcbd3abcce4ddaa3541d139f354ac6ec6bba9f7272bdc1a623f3fa830446270a990a204af425227db62b18ce9820f0ebacbbb3d8f1c5a96b2bc6506267a777bd66a5f58dd3d62cffe3389d331cf67148b324ba0d72f05875e143f0354163fe662452720a0e206250ae6ce3fde71d657bc46fd3ef288f725fc85575bcea27e91040c63691b3e658720c13df590e51354485ca758288933d7ef30acd4339c238fd50654f9905e049c9b17d3665fb1e0189e617f060f7d80f5e829f6566b0a349eff8a6562b57baa44c4a73c302ecf54cbd07416c0d969a80f67ce9084f61b45ae1d44ecd5d2534091edbb45bd034dea556d561cce1dff81634814e6f2c2ba47bbe6f23987250996e16ed32ba15df3e94f16174486796bfc5cd1189e9dec983b208e201518c909041d7b36342e1bc9c5751f3c19b5cdd7c6cd79f9ba237b0a7819e8090e5c99bd78a31f3587e06eb7eae7f664d0a909c989ec6bb083ce063d883da00f8336b7e8582932532a28139e6c3bd2cc7c5376d02bf50a418eb80931b91b2253e1190e0f84d637e2bec7fb97f4706be1d5c606da5e44c1cc593037d1e25362af7c60d5e2f23046136663a2adb711e3f5da82168ea6c97cdc25eabab310303ab1563a3615972806cb35f6b8e94818faec30ba12979106704aef932d98c2d3bbfc4aac54dbef188ba15ae76e584cd9f74e544be828a5f91643e098e28076958b812c69402b2aaaa01094bb39be8ceab32b472f2cda9f601069f010bfb41290f01dceac14cc470f920bc29d105a37d31a96fe6979f8e0144e0240079fb43bc601977fbc21a3eefb5a2614eb0299b4fed94ef23efeee974dfd05a0d54667e6bb5c5a27486a2890a9bfd5caf1091152ee699a4a39cf6d19fb7710a0b696d3be3f89b36c1a7bd51f0fa81c88a6757e5ffedd92633d552f0de3d520e074ca7c7794067d514708b88764a322771a1b049b352a3ef2658dd58042d93dc0382c7b3701954c99479be3d776b92fa4860b3d24d83d2d29efb6f2e58044e2f0a3d534ed8381672cafb5910fcfff0fb74a96ef31db67baa3f93c89f229aa2e909296624968e2e63ab9a7f587db729644df4ae54c8f8b729b25cd43005775eb20a8b9678cabbe29dca9194dede24f61cffd352733ca07d62e09668f0b5c15aed0bae7111aa745d32c00c9841de0175095e65cda92f11aef73587801422c2c0180c7c8212fb1971fcfeb45044c1064a7c84d7b6dbb7bd360fa7ff33e9a94bb95e0a951c08048f42f5613697277f2cec86c7a6ee069ae260d5454ccfef495394dd0e4fa30f1f428e22bef27d3416ece8e011b371eef86bdb96407af7dde372eff90779ca5b89499b9c396ddd168cc0cfcb42836efa7aa58cc1ab577301853e9b1e099caadeb22e4308a3f0f0d989969a0cc9c1b9a55e5f31b44cdca18cef2492e90a10601d7644bf319d53beda6b6fb08a73ecf65498d116a581fec1bd042fdab040aa0a4167c5be9cebca12008807459c31f14acf6614f73d7e92aecfd51b6dbb93";
cryptonote::blobdata bd;
ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(std::string(tx_hex), bd));
cryptonote::transaction tx;
crypto::hash tx_hash, tx_prefix_hash;
ASSERT_TRUE(parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash));
ASSERT_TRUE(tx.version == 3); // >=2
ASSERT_TRUE(rct::is_rct_bulletproof_plus(tx.rct_signatures.type)); // salvium started with bulletproof+
const uint64_t tx_size = bd.size();
const uint64_t tx_weight = cryptonote::get_transaction_weight(tx);
ASSERT_TRUE(tx_weight > tx_size); // it has four outputs, > 2 makes weight > size
}
TEST(bulletproof, weight_pruned)
{
static const char * const txs_hex[] =
{
// 2->2 (typical)
"03000202000353414c100d9b0180018602041218014b09121b0302010baeae79dfbbee96ddcb5c04dc44fefd4fcbee927ad79c22ad5e90077b6ad6354502000353414c103eda031b211f140c0812130d0e0604010f92eabd619159292e5ee0c5db6f1aa08bd8f0b6f8841a1438be230e342e8dd81a020003285314f5e5c734535bdba4b221a1274654243ca25f2bbd4d552f65ef936b15e40353414c003f0003bcb4d3adfe3c5bcf87eb163384aef3727f630a1d7112531bb1ef4ad50bda51080353414c00402c01eea85df7526c2df4d22df8faac0fc0782206c9511b98ba3cbf2e844739c9c192020901c719d5d54e855499030002c578dad2e274d40f75f4aacb6b50b01a22a65f29b6485236ad1c1a50065bc324899db191b42a13b7e005159606240298dc240fd0e5c880bde4cdd1d5b195473302dd060353414c0353414c0007c8ff4eabf73c328f7f2361ed6980e137c65ce58acb065cede75577346bccf5b9f30aeb40e8ffcb7383d2d0a6c762d0ea876d2de70fbe4dbeb1e5138320c9e073c7596e569456ec191dba4992ac685eee8a16d41078173732aa144c39cd0c3f7e8f6349fa29ef129026a63d0dd65ec804c40fb42222cdb458aea6414bc36ae3fe3a67e3785ebab080da51dc818f7ff8fa6abc5892bc94d6a1e836d438e97a50a7179e5b92bae4bf13f8a7d81f29f804042cc709000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b419ff1ce834ee64e6f5b9ed62773082cae70bb072ec867a2465de9afefacc9d88f4c12bbd66b63aad076073cb6c6789e103ca8681b87a4584995a251e0c1ab2048c74f98f55cfd30a8d9518644985d7fb62aa565e3b880ac7dbf34db76f190d49baf320a007c8fa77c0c7f642611d65de92575d7fff450a8eb3d2932f13bc054656d89660dcacbc266aa9ec85de6fdfab25685d301592f57d2b4cca402af405177ff97ca184c1d43b92b6b5a7b3a4716cd3c6dda3cfd29c5fbe528ef6c2c808072658e5102becd5323c81e234f29673ce1a1a8e61ac118706fa269f3b1bbca62b9d2630a7ce7f981b4e97563a4883ccb9ec594386275b8f753e295c4ee2f1d03f8bf3c3c517dd554c8117b2d3b29078efc95eac69a4fe295dedc96ace5176a561de554b1b7d56920a44fcf203efdac97d69cd3c17e447f4f7658b3987c22efb2899d837af2282014c3fa5d7e121523b3973fbe9d582b3cc330c40b991eb99b54aa59cd7a61a5343079a5a04f1a33bf2e6a29b92471633103b41b672d36c35044e360241309feb9428e3801e6d0413a05cdf8bcdb1bb23d4e3e864f133fe49ec690755e79e434d7ffce722f7214d461548421d40ee6c65f92fa58162e800b6ef229e845c45cdb55013d4ddbb2aa208afd38257d53f36576e020c746823bdd5e0ed8edcc6e706ccb77c9b8f567e20a402b73cfbf1c0d958de6962c3679c0ff1e90cfd6911d11c6b6eaeb26e8756a779e0f574c5c0976847e79dc2f1d467dbf53f0f479001ae59e4414b57402a2849c4037000ec077c9364ecd06bce62047fb1150f021082a38f221f858511143c27fad44abb3df6ebe8f9448e63d285405ab81f68619b54f2178cc6c8f146b7f8a486ff272b3059d5aa23332f17a9c044bd372d2ed67280d04b25409ac2040725a200dc4dc864b4109e192c53c7b0e035c19378e204e28523d31fcd45e9770f0ec91d213fc6999b5eea04d82c132ad23bab11d2bb0390fe34ce185f7e5c870b542030da317a0b88b2a2a308871ca653d091d8685607d8ed312d789715978095d4c9673fd7fe494da22c80a1bf7044590af027972407f533a8402c4cea5e7e540c1c07a8e10204c197f0fa1db7261ad22d75617e3e064dfbcd217e842429b609d10626375244d6c28edc77a2d4caf551f8a3f362110b827f78f5067ceff94d9412dabcddf5e2924cf48f4f427cddcb9a97f2e8786c0af14a208f92fe860e54addb42fd078ead4a97429d2aa0d3cbaebc088e75c6820f7ab70cb79603e9ac204c430c3d1afd592e3f4a129864616a3ead232bbd257406935fa0bf2c076a42a04a992d4d7dd7c85ec24fa2fea69f783b6ffbafb916b10fffe2a98d65643aeefcfab651acab54992b401aa2d5e2a9c0da5a0234c47da2009209a3c72f357393eaa6263adbd9990a0331e3c0138a4116b8457d9f37edf7085f372f0ccdb469c3e4a893f49b343fdcbaa9e86fd0d5a5ab48d7b4b5d1c81c0bb8439a042799f9fc230c13b0bbb1763b0c416d7ff57559c6b957f29d74b316076057568bad5df3ff252ef897bc3ab847cecb0fd36afd98d02f841f942658850e129fdb82c14147b9d321f61404f843ff09b7e4324d570556e1ed1e3fdadf72048c4f146804df64abaff0fde4894f8445c8123774a5c7737ed64611a09d50c00b20a13a0dc0d5b9728b2cf72e42f077c6e65d3f66fe027c3b02b80e9f98b35b9f54843c30f1fcc2385eb2edd208fb40a7c0f4db617a38ff5e74d97d20d5495f0edff6731ca834ea55c0d9fbf042b9a2624cb643b0b8d23628bc001b2abafe890288a79d964b997b1fc87bcf5014d62c61c468a115e1d5c6d2d5f3b57eeb1c2e04ed1c852e01ca0bbb6a6958f2938c011ab310dddf312ed7c161a35655535bb505ebee3b20928c9dddb5880e363c34a7c9a0337dcac621b9392993bb28f750750eac9d539604d03c5723696cf55b8e4bfd6bd3ea68f6e26e03877daa27c733e20adcbf6688c9431d851d64b91c6fa2120138caf5af75c739fe8328eda88e941c0a4a4635c206f92c7dd1f59f14f9488e79a3a3fc158ede268081fe0844318d740f91b0ef06d0a355da22ef2eb8bd67ec60c0a606f0cd68f8dd6a01e1e9ff184a0622df9286186853ba640113d4b1aeb2e734f159e9cccb05cf6be4b8720f16c50fa2b8217792dd59a10f33fb523442443611498a4b8ef85a716fa80246b12e4b042bac1e6f9e3abd69bfecf0721610bb137b2a0758b0797c09e371d920def98c0ccd512bd3de04601c264d37bb78fa9852a33f279b8f71b378681d697c88042c02c716c68ff14d25350cfe416ebda8441cb9d53e6256162139f1a9f0a843688c0a5afb3d0a3c7710ab86b2ee6c9cabf7d6c17817793dd9ff1e28aea139bc5e0a07753e8fc28e66f3dcf858802a93b79c2b711dedbadc8c38ba1a5c614212bd370ac9802edf8e3645adb5f4425de3930fc9ca6c4cee1d9d9ce827e7494609461c08d16fc522e3ffd5189cf9fdc12da8286fc1e08064b2c3505cdefe60a4bcc3d116e4bc9167827ddfeccb4fe7427a473667037fae98a9310882ae248043a708453562e95d7797610de652108bf7580e09bc9be90f2d05837c6c230ca8302d0e28c2",
// 3->2 (> 2 inputs)
"03000302000353414c10745b62820171143d08070e2b0404011d0bedfed599b1b55489cd5b45ef9049cbaf899d244f7ddd3edcc3a2d5a01e6a396502000353414c10ef01ac01483e0d04132230260a0f060a10028f54232d770c212486c99308e48cef6b27605c5daa7cd7f00389f74dda42387e02000353414c105b71ae01150c17330b024a53171c032c0748c611e6b9f5460cd299880ee89cd656f4bc67f42b1b585ffadf09490c622b80020003c6b33b680ccfb42b1f5f68cafeb1cfd9c0a0862abb3a2683530b29a269cc86d10353414c00d70003c9fa49e5474181f18bad31f7c2bc29a4e86f47af59ba117ba172ec8bd141ef940353414c00f22c014825afc4e675666863552f222ed7e688920a1807e2845b32222516f1242b89c402090155429de00b9a64860300023584b9dd6a9f528aa810937cfe7635b2465706f4b2228d67c59f81138209c838494328ee98876edfbacec22be82d942c69e50f6414bf25242f2645b384d4728902f66c0353414c0353414c0007808564f60f03fa6ea90b2d4f197a35d1e3df14313318f69038a99bf6d92a7a0b3748dd4bc7f082c2868ad6889934e1cfc55001aa282db34e30d80bfd06fdb79f9cfc1136f3dcf903a69ff564fc7e039de2f52158f7ec75844e7218d211e67bc657667459abba19dee06d56112b7d72626263257f36049f81cce6a1302f5407aefa1bd3223a85db70eed33c13b9d641ef0151cd4c3eff88bf02a9ec03d965b44def3dcc88fa1a420af403a4c9e4bc2764ceb708000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d7ed99cad8753df857d6760017ce6a18021ba933340d1961c3bb4bf0f76e7db3ab27a4124ce2ab707b59416b71fa42b1fe82425a34b73c4d4909e073921c30b37f2f9a7bb221a99aaa3f1e1f041c04af6a44e684cd0ee2eea562dc40894b5b1dc33d7976cdbcc70c67506211af3678c5ac431e90fa9c1454ba664915ef3a770ceebeffff0fe7f3e70570c4b6dc102873d085c8dad1389dfc9f29d665cb5f5e0e3dc6d18a879a41bda7c0c27f49356e476f531edf9385da92b49cacbe0dd2b10807b2b5a35724b7cec298ff8786a03639e96e40f22870b6abd4c804ac2d3a446ff4be6a1c40994bbd89a895a66e3d9f9d85f73d920b1bb2ee72b9bc4e8c7a3e2a625acf7e1895e075ebaeea6bc5d55af79d7a70869cd81cb59daf792423f47202a430a51e80469855331c3931388dfb7b06c2eb76e9ef91792c76d12f8e9019674b15eb57e998b27be33a7ec94389b7494164429d990f1f6f43ba23f3812ef1ac285d1376e8382080775a613c49423b4e1dfac284f743d08f1a1142ceafc31ffa161bc6591ff6a54a047650cc0efbce5259bf2775e4bae4829a080b5a3fc72a664a0705ba86873af5b5f46f7c381a602f3059b3097404e4647e28d0a8c4beb9ff9a9f7f6c7b074db0dcf8a9270a29fef71052907d22cf488a7b9d97303f1a4b1ae00946cacaf2615b8b63329e5f430719b98673886acd565c11cec44607488f7c3942875b51f78a278eb993095ff60e97688ab6b04d1af19dab44bcf1f1ff4c3aebceffe0fb6315c418dc4adfe74ff1c62a61fc9fa3cd9e3908d6c5576770202bdc877f705ecb94cf61a659e05836cf481c7ff37629fa7b5da4135cd5d6d66f914ffa776f4b08f27e606a69d006bf27dac5e57d5426a7673334968ea35b0ba07dbed273d9cd910b88cfd59dd7746e9e15bdaaf6e584db0d248929249359f88bb1d00437c3cd6effe7b583811a3e540c309e0c3cc1b9640d776ab005caf7f0e36a7301a6e667a537e3308db8c7f98e5fb713190f362e37a912dfaa46bbf42efb215f07fcf2172d104d1c5f700f2dfe46d86fefa364d770e70949de73a75d01cfc847072b9831cf4187a6b11c37fd1b2e1a22ab6d7c1e344e8c98b083f2aa357e18160df8468e7709b14ebb35dc9718dd39c3e3c7f1ae9f4b5165f81435ae0c85a486073c9c21fd69003b1d50a371e29bc8d1f2b43b9e30342d0eba7bf5e9bc9b5905030d5610d7e9550c87e458b3186b3e3292fba5b642ca19d52c6d91a4f1be8cf20a04d9eef504117942568f1b78184fe43b2ef3595de1dcada86e968b1951a708084e403a4e32ea907a93929811aab2d94c9e3f9619fdb4259cbbc3ce1a481cfb0aedd10dea458c240763ee3d36fee9d2cd9aa0dd2ebf6a122ad60e268d83de7c03d51a9947dd65476fbefd68314ae4c9741c064c1fe004a4ad3e97ee97d449f10f8c45a9541e7121b66d6b07d4383d787a1aa65a5ce16c84bfebd2d793a0107d0010550c06562ceb3abe918563a4bebe669e5c665e8ae4ab45ce1329a9334b510ee01596a0e1e75bae93021566a7105b49fb39f3ae9658aded4bdeab56d8c10607725bfdf38440b92d05f7c266b6a33360be0718869a6d9481d8942ad84f3dbc09fbd7de66e45b4738641087f87e9c8b608b94de3ed8f90b1bf69a23c3a078850fcae89f7b1321ef9edc10999f5ec9db70bcd161f007c548f6a6dbb022c9571616de54315304b9b16725b9b5f61ec760cc27dc4a51fdc2b2c5fe7d0a4b74b80a083f33eaf458120692d24b66aec8001ffe8488f8cd6956e474bc2ec5fbbe51d409c1d4cef295564b033aa22d5e9d6eba28bb03921ebb1251326f3581a677b0230922e547c817744b686a987144bdd3ae31163fd6eefe7c3b55533623dd12092c03e0d2614f1cac36dc7970d0b1b31bccd256ecc4ce506321109b7ca5cd1d03f707ee0849387ce430e446c24519a545c581af8e1d8841e9c88ccdb22948edfc810edbcbd0407da175df588e175dd47b3fd469cad6746a800268d58d707ed20bab0eaeb897d33540508a7faebb536c8d9d8bef3daa29c2f3e8c3677d82e347607e08cb98c66ee36192e6e4da4dfc9fb80a484ae26885d69257e199244a00e854e209b069c6a3e45776581c69c956300706637db6be533895ee6dd3ecf6e09738da09c82724d505028a42f1fca54b66ff8e786f6fc26ad749bfbe64f1e7bbace0980a555c8e98dad5038c595383ec1881c8a293a82773458aa469404aa98df24cf008800a3f7d51944f12cfb1f2d004fe5b8b14aa564db65351d8a8ce6acdce287103af3ffb7b8ba6843619aed5981208e23919676cfb3f5040a3a92966d64d886b0becf303aedc545124a4b9ab9d8d757839ba2e6e348c261568b5612535bf82c90cdfa8e323fb61468e20f74fe8d9ca09c33e03f8e7c1dd3f8036c9c77a9adac4031c259d1f0713bf3117b0d84739b5d5adb441eb20a281325dd22ff380eba104041704702ca8d0fa236e8c6926daf54d346038da9dc099e912554dc71ddca052f3f92b824bbbb2be051a662d28a61ab4839f33295b679caae149f906f9793f850811e0ee9656583e87d24d08bbc2a441cb3a4795824fb5200ee322a68e54981900c4bcc85b4922c67097b99b201e35d29ab73adc9dd6cf61700db3ba05e9be9a0f1bd8964fbe4781681d046d1a53999b110fd49da942005da28d54bcc389e4680cd4879705f9fbdee45f09df4d242ff2748ea8de08bf590da0e2b0b5e486281a09f201c3915f5587d82d95d28b25671d1c221de53eb4d2193b47ef172e96b0ef081a0841787c1f235670f9baa03f2f4b2d361271b9aa907691e25584f12765a8078621491fccc235fdf335dfcb337ad1eb64e04ab669ae7544dec4d64fdce7e00d6be7bdfcd0a671765b3e3dbf30f116bc633c4b7027452efb96ecd7b4152a1f0e811f68cfc1015f9ece54d6ca0a940fec973f8ecb19a8e4e12fb405d3e9385805c492d69329ade55d7991ca366966a491fa2b82b66e50834b27c5031d16032106734c0dbd42ba8a52137a083fff8700de1793e186dfcaa8d12c4a16ef7440d7076832a688d1548f6cc3a2743801960916e712ddce3339cf82f2ee7ab370625a0c1a76e24237970b2ca7ba646c93ca4715a0ad0a32be97b4da0bbc353138e83a0b47f83053f890ef061ac546f2a643046cb210f8ed4156864578f1da9f3a77100dbb7eeb4c36e9ee82a824633c31a4b7ec6e6818e89a1f02db5c5a43c18ca36206fed42088dade8efbea3fa0c16c688d74a8d10f88e3a0bc7775aa733d09fc4905bd8a073a5931c4099430107414a246a8647be7c24c179f62f3ae670ee3e3cf0ac4e46ba24ba18a3e5dacc49a94ca65d323d0045ffe8702cab0bac87d129b2f6b83d6717fb5db955d94a5e06980d0491b90da5dbab985737bf357189701a4158a44d4e04a61967ca4a1aea3233a3a8f7304a6dfe5b15220c68fdb7ddff1891cbd",
// 2->4 (> 2 outputs, without padding)
"03000202000353414c10e00263262b06270b0f211d2506091a0c04e748f2e0744149fe29f6d3fc47de0d3d04eb499b34b95e2d07831f48f9d9ee6102000353414c10c302e001592c080c0508020402060d030d03235bd48aeaf7ad1f3f5326da525adaf6bf231e9bfab8bf84ebcbe1a63d6de5a60400036055f44b7308de4e86877f191d7da19c3035a5f18e83981f406da68d1dbb38800353414c00900003c6d13398f5b0227cd82819ce2bdea903fdebf543b38d57a6bbcc67a6109aff140353414c00d40003af22524ee91e1b7632647e1357ed27f6d13776e6871cf7ad5953351e84fd0f0f0353414c00970003c6040dc43e66b70ac8c7a7de67a5aa944c7e8202a404ce95f9f0ee67114d7deb0353414c006921014beebfd78a2968f6f32147312cea087ce8a343079b76daa365c58df8ff411a99030004f30ed1d8f9f68c07f3975e4babc4d4388d398f0d05e14493acfd2209673dde7fc931f3115c35737bb8758707b9867d703c741957ade22661dc27a23ac6abb00d8caa406cd1223d45ffdd3c9618772ff240643e2de65d6091d87fc85014a607c0ab7be6963845375251a15a14afd3f7e0064692ef5ed47162008252869bdede2604e08443a50353414c0353414c0007d8b566e1a7b3b4457f0157125180767f6dc1b7d2923e9bf3d696805fd833aed42a6fd265c7558da5162410de01bb50daae779e71266bc7a52cea9c1a54064a4c2cd8385ee4469096434199a8b06ef92ea806e2aa8eb34053885ec8573f7647fa560cea9a166dcee90100d44a56922865fc473c54ca095a9eea75754af832bebb38056588aa04817bc1c9e21d7a806760fbcce0c7b4eb1c3ef3b3f1a77357661e108d226393248dee66184afd243900eae84013d8be99b26bd1272d7813384b02a62efc83762cd503613d3ede26769b36d44e9a0fa106b0f359e81287f524269769833b54667dac430f1ccfeff975a5489cab63d04dbbc6ffc4fcf94b08b7c6f25335020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011cc2a68782305a6468e6693d2e374ef3bfb13f3289157ce00e30bad7eb80bfbabf2bbe38d1f8111af2b9e92f34e2ddf48bd59a63d3e2e505133d78f137d195e7f8a3ae55d185909ef4a43e6e0ffa137d43fe183dc6254dd0db4f02a3f046f40943f5e5eb071ff68a0ca552fe5a079a1f767bcddce0b287fe2733ff9f5e912c04903e68944109ec506491319c0c7876f33c329bd40fd7178f1556439fccbed2050ba0585618fcccdce26bc413973016e539fa951fec4a33d43a0a7f0c3a93760708f9398a538dca9956ff76ae0e397c47da38941bfd352822725a27408426c5f8cc40339f40fdb738b3bc70fd0af7a8748f1e18176d2b26f63b771c6c174bd64c247cbbf7a73f4bd5a082a5efe7981dc046c2dff05244145d5fac815e979d8a708d47b3b4ea194bd9c61cd6046c8e3ecb4c48c751c853100e4b459e8d17d528f0c8bd3599ea62be2d915160d471ff4b1344a9a013bfe02350d23d590661cbe234586e9bf60f711109b31cdb50fad758d16dab278b79558ff24ee75b3a02fba70dfb279b8f0671137680208473f211961e4999775b84b3d700799fe9e3ac1c86507d30d55ee6eea4e6b044c847cba4f37e3dab02f74167ed860311a00a1f22155afa0867f09b6ef8fe9d0ec5e86950848661ecd60f1ef1fab9e6d726e48744adc192f2bf8200bb55eb9e95a295ddcec25a3af51d7cdfb7d722348796a46381039ad643bc1573481d429ee9371a81a37be053a565e582c2ff252ed5b65087bd15ad911d6afc1150ea46f9098a6b69bef8b980d9b2a840a154ca7d17ce4716a4df1408afe32bf9212a10547e08bcc12b2b7ba0a11aa5dfedd46eaedc4b72eba931141744208794778aff799ad543423d491a790199285377d27bbc5831dd812a2d8469abd812ad9b2e2ada5489adfcd8694833d70ee736be2dddc9cd31268de4c7df5788a1aa2cfac828910705f63568ed7bb1436467983d37518d8805af4621072f63387b3decdec10c359c591bbc73df8e8cd5b69a32c4e47ad119104c42ddc7e7cd0d3425ffae85f8746ba74571547cf65e1e204afea678c3cd2554ba50324b242d0ad837182e69ac2c2b5684bbd3594a61b7bec9a0649e00aa7489633acd36001205d95a013c10fa7fbc6ceb6ab5cf857d1dd6bd16c8ad176e5ba8950c6bc63ff709a994050ec9450d0754158f5a00e73c40e70338ded0c54f15f1fec2df56cc360cee00e4d6514c350e16b03cbe78312512d604cd5eb1bb2bf9906c2f11e18df50de557d88aec01b7d18a5936ae8b2fcafd651d3d0dc81f74d575ca1ab498cc780fe281311c001600597a51c57ce994de36e1125c26c20032c6fd70f15464e88c0ba5e5b18d021505ba3a316ff3d5f1d7356c0d660923a38b6631d8c81f629d490596a549e370dedb2a025706db8b616a3b524310683c3d2c0d662f7e184103750732163769a9076401a64b75b6dabd8ceae3bc64a74db038cae558a37410f06b0444aaeb2c27bed13962f5d6e233f74ecf69082b7da102ea9bddba4eb30a86790546025862dc9001203bbc7774d9643e495e1deb812d142937bea3ceb07cc16c0df961f68b691a1f62ef8fc1907357e91a2f688911af2a51f968b265237b290f0309f27305a11a2d3bfcc12d0928b90866dd1036a1369adf82824a2e549071ec06579bcdef5080001942e936ee71308429326de45e6a97ff7702697936ccfdc001268b550f15830d883861f066d54ba31e024e63be5089d1be9c418b3102074e0c91c3e5ab13e81c8be903550b01e0cfa7b091f3b2d1082333ba30a8d20fe8ce59c216df52511972233acb4e062bce92cc2ae8ecc2ce855af24b0c383ab0fa59043557a7039776b567b0a410ebf70424294b47b783d8ecbb82cc1dfc5a7bd45a0b0417386da760127009d77edac7584c0ae833640746052df95b01f3d335f03e0250948ed9fc15ad9c48b7ad45ca18bbf56280cd3776eac7de943a8077a7c835043bab23d1ad503c70b59fe8a64e7624261c8c30db410c00501e5d11e260b9930ea7605319dbceb63010605b04f31cec5d562494b284cee3f875a54db65c0fc9077b9d36a257e1d2ffb9785fa72f7f75e71d2c4016d6b11b1598d6d36bd86472075c95b2e63b449745ef2a8221f0ebc17024eadf8f6aa065f5f7af2f6666da6808dc8899871658eaeec172f8d32d060b92e9306e657b31eb31fac53c72c8687e03f4c1e6553408dc61ef57bc8eafb128cfb3da262da50849c2e4853b263175fe05959d2bf9578491c6885dc0a7639fdbe10aed80df74ee946740a7e5113a04e9005f54a5b07aa7ef53a3df11fe3ea1cdd3604352a7dbbb41d8133053022b8b6e0154765316b35cf0f10442e7afce2125cbc0f259a9d839c8646603e7c51f12240199c3689bdc8283560810cc7f377bccf1bddb229e9ef119a264ada6a656a5fe08d8e6f8b521d58c84af12e3d2f71053e6e0f05f88a972b871a35369b05f1d0807e326b54cdbc133429d69261e9ac9c746a252ecef4a2f1a0684d565e5277c18081a5597d8a1c0953f1a052b8474fbcb65e8bd32a98dc725c6affad8b50376f606b4928331a2a3de0bba075d2d1877fe2ebc963f687c7a8ea565f5c51fa4221ba9a476e8df1b567de2fc65ec1a813951f43de4e265118414682fdc4828fd00ffa4f47e15957a4d8436757605e541d79ef3030d4a809d97bb1243318cd2a867318e",
// 1->3 (single input, > 2 outputs, padding needed)
"03000102000353414c103eda031b211f140c0812130d0e0604010f92eabd619159292e5ee0c5db6f1aa08bd8f0b6f8841a1438be230e342e8dd81a0300038d323c587a0dcc8831c0f5345dd5d963360dc403182f1cca713f46ca290ca5190353414c00ea0003a578778d1afea0a09ba4adfb170a2f75b68449285dd0e608a95420f4edbf26eb0353414c00cf0003d263eaa71c3848cc0d5633e734db7ee6ec8bab728296e88074609fdd4d5c2aa40353414c008d2101582846461f27107ec4cc0681cfc4ed1fe074a47239ff7b973660888ebfb2d40b0300035007f7b4d48bf6e0b6d369269986d687d398faf1ecc87beda3777b7ecec5280e7d01334944f5a1f653ae40677a80448ba4683b4ec9c5e393dbefe2706e9ae35e33231b0364c57140eb5cbdea06c6884e0d7a6994652418856007423b2c410215036c4efd0353414c0353414c000788dd4d61083c125bd76d3d308832dbf39f2ceb8be6ed78bb244fad6205fc66d3092282c37e983a29d91bdce9ec1267148e56ede4fb6656bda1815f7e3140e76539bd395b3e02b740a0ab11ddf9fc5712416283beeb133c53304150f6b6bdbd100528f3c9daad7aa9f560434a468467eb75e35bcda4ce000dbc1e885e58a2fff04824dbacdd11a17d2503f756bcadd34bf6fd20303dd9319ab9c4af7c52735a1aa3be25133f5b7342050ce44447d38da7289c58c1fe94eeacb499d34b523d324732af331a888ce6869553b26f546ff389e8a85b5ef0067d625ad40d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124440dcb78501f374838feff14c85c48444dcb7774b0187825050743f83c7ac51256e33923ddda47f751cdf75db1909dcdb980ba500e0ec3b9d89c7bfc84cd33f976bc5f09502ed58e42c359cf9dfef641cf8a9c691283e18d83f69ebbbfa5bc3be62f4f5d52fbcd772ceba4621064897729b59e0c8de97393a5c8a02685b504bcdafc664473750d5d69564641f0040b6719ad585b9439fd9101485e0875eb036fac3b5b7a65cfdd88214562469f485fe9f7f05ddb4178fddaa766506dd1f70e08db57dce32a97a2107f7920a5b475adf4dea7e4dad9d4f24f0d653fcc13cb70da51e5d3f5152c1f87cc8fa60d6cc61ab2613073c6ee724536d58d2806612574be4b448b7a5a6856a5e388cb359382881f5077c5046b3cd77c8dd09d2151076a8af9cc919d16b3880e09ea1caa3aa602a02bc9ae8b6c11acd5300489b3b7485781e3e5051be6f07a4a1a7bc56574007cce4fe9dfd381b8ec458240f8066b6829686e7c58eb5709be5b139d2e866610eb9dbc0d691c5a231b9fb231d76be839ab7e58a33136ad7f35d9c02c145f32ff17695ba23c285c7d7915dabb253ebb5f6362e3f97b9bcd6a75b477b6d2f24adf1657f2b14d4ae98f26da6fd0b697fff09dab084eb85beda81745e5de947cc403abded1b4a043b5cff47d7f8bd3f73cfc8af6c6f9ffdbdd8f1aa5a7e2a2e9a15bea8109328af524150d7560a2c0df90543b4b4cceda91f7fdba22a234979f73acd0146b5bc82aad3345430b008adb9ab52c114b795320e58f4c23c1a3cf199589d181fdb93b9aca8203f639dada6819ffff892fb1d89cba512078599320c217cc71eae67f8912210925fb998db6ceded47bb871b378961de657b80f23b52fffc765d72e301b66d7764b902b5270ab3fbdfe1d63f8d33cf36990eb990dfc6e54a8addfc67edebe08193ad3f49767d0e48b761a2c5afe0b37fce8b277c2960da61d4d9c53d5e60f808b6975665d6a52a1b525d0dc28f68c8b40043c30189e9bea247aa9f41fdf795f3e27ee10c793210a5110e2053db495098e5305d8b29e4e7f0eb8a9902be36bed2cced09669bdb927ee67e508cc67f754331d4c35d4d5c36ba3456d9aea7e9c9d6cd7fbe1d5015883b9996609ed215b36e303e973a0ac2a9fd8b12130a205ea3f8c2784a73376775f2279970107db9a105db81c6bd540951b8e42efa2810af19287c864cb7fb26b54d38db608da8ca9eab06d3ff51ede5cca68d4c2db3c7557ee2b22ca36307aac3f8b73da0167e3b000ac43c487839df9f7d9ccc215463cce53dc2aae082be4025d7eea590e40cc22796b1167564da81f9cf2d5ef72c2dea36ba0ccb305d483857e3dc20b0389493ec8713f63596bc6507fa0f7ea47960f0bed1f7269e4dc89b2e3b960f108ebe2ae711f3216f2736a400e2212fe0a61232fb21933a19b9d89ebb138bfd70447a5fdd9bce8017960df7cd3ff42569241130017fc82ed49beb0dbe1bab2430dea30f385480aa7832645650b3ce490c89bb5e30eea143bf1b0394b5425cf9103da4c0fb9ff2197b63fa1debca23bd8020a5e1cacd9d0b36d0f834b08b58fc80648e15f103013b4a4a98c715d973a1d4d5ec91500745b6f7272e4b0243a7c1709ead74e5ac2380bd1f8da0d24f309c51b72ad06e0728bb713e550ca4fb54b7d0d545c5f8be4fe941e6344b942ac4a20223c07c59c037f77d54b457f0ea270cb0f0335848826249bed0150238c8db05b0aa77ba960fcc0b3d4e85231242ec34e0eeb946898b94cefe4d27c87cbc52ca43d4e967a7a9fecea19940cda64748325e754481f5f786ac64998a26e7fc8fa340d97ecfa148d757bc5400efee2c4a52c7c",
// 2->16 (max number of outputs)
"03000202000353414c100d9b0180018602041218014b09121b0302010baeae79dfbbee96ddcb5c04dc44fefd4fcbee927ad79c22ad5e90077b6ad6354502000353414c10c302e001592c080c0508020402060d030d03235bd48aeaf7ad1f3f5326da525adaf6bf231e9bfab8bf84ebcbe1a63d6de5a6100003f8d53cd54d729cdbda8b2ce2e264d531283ec28957d7176bed2519e7429719710353414c00ae0003c26561ea1008fafb2ab33f7217a0c29d934873c5dddbd502f27c0329c28cdb580353414c002300032e5b483ada95df85d6e863c3b18bcfe29256b90bcf97526fe3d23e97cff1e0dc0353414c00c800032017d476f4a9092c406b0fad252b6794a2d92140705bd6fb1c41412827b4f45e0353414c002a00034c6c2859095a508a6a798d2dfd1db65f12b55bd19dc97c8dd18ac738604bfe840353414c00130003cc2729b1bf7644d94a300f228e501679b62c2e759743eabf6aa2239e39fb04e50353414c00e20003c52f8a93c84608045c3a8ce97c06736838ec77f3982a7cd728d2c2436578b2ca0353414c003f0003b30aaa812b0ec438c5f7cd20d5bc76ccd0671dc6cf7329a63dba71b51ddc90fb0353414c00350003eb772a56be6a474683c8b149b06c27a56d0434d5a33d12ceff83c2662e6196a80353414c002400031be26c353d192e09c861d2dabcc3f590e3d48fd8e329f9674705112ff98039c50353414c00fd0003883efe3578cdcfa9824e1b70287f22294b4d17de65ea5a6b2b887fa7c570ded30353414c002b00034db49a90b08f52c3ab65fa87de98f39d5bd1fad416becd7bee04f50e884ddbb80353414c002b00031cf7ed34b8d1dd1f8d2898f41acb6b0f8c5e405bd610f99713e05b07e7b3f6260353414c00d90003416e28728f2a9529b5cce7c04b844da9f58caee9f6f04bb91bb88afa2603d2810353414c00240003a8ec92d5061066addb8bd04cf2e228b8d6f3bfa78bc541acf45adddcf05543680353414c00010003388d6a51393995f204737e9870bf165636d7f9f7cc949d8b5473effd49e761ff0353414c00c9210150c9922a576c85e7bce9da9d6dd28ce6af30515eede7649717c13c09f3a2107d03001026d6c909b4d09732fc71ac40bc935121d5d83f92497cefd46c510e6f4c7691015a235eae26946d02511ecc152564029679fb3a98f167af6a097acd53061b618a251ee0d78af0b4761ef7137a049d7c35e1aba0c60db76a56ff558cb2dfdd6ecda613ef8144d67ca9ceacb5d003f4fdf5b4e8fa78078c1be16b3434ab49a9f3bb1464fc3290a9c880744cff296639b3ee0f6651c575dac6ec0cf35a6d8e94a675bbeccf82cc1e91c4c7dc43c44a3081ff7350ca2455278030a5a88104e6a9bd53a38a1cc758270c86eee017a8f124ca65d1d25a89c59cdcee2da49afb0b4285819e5fa96d7143412b7d41eeee835cc1fabc7c094a8062e50e5842ec1f2eb6450761e5d24f335eb3554f00cd8b801d7bb8bbc1ac914d49d81dd4a812ee819032a1d9a2381bb77c6f5545871a2c9cdf16500b41caee7fd179a69961f21a758ca3b7af5c7a536f1b26368314f711ac2da83b73569b07965d3b23cafeda3bee3f70cc2526429a19a2b49faa015176ae25cc96ce48710a24161f7fa44bea1dfe308f5c641270c0a7ae10bcc29b9c474dae8135bb672165dcd19036c77668203599be287dac896d80a0d1e5b304c30b1d8ce5a827cbc306c015bf8d7f2f9ff33a19160895f11f0de4ba754bd47a77c30389ca0d8768b5c9d67ba6881f2e0723f5a85ed7b13a039041025852c95595868cd4f3d6a572fd1d9a5ce15e3a6ccf5d66b3e7b110ece09c87b89cc6cfb5ec4869713b41880353414c0353414c0007a0f0f30174d2b3459cdd2200ddaaa25282e0f85dab0535171bad207545904a6d71b3a437d1537f7b1ee5664c9d4c2898028a81cc7c7e7c4e6d4963568334ba0db2534ef88688305d84ed0826889cc277f3103e0009a8ba353305a2cf41205cfc206d9005d8954b858dd5d64546e4c6878b7bfb7e88cece52c8e106578b67dfa7558bea4005c335436e5f3140dd25a5d13b310e68f767ad1aa810fd04a45f86bd22508079934e3b7a5fd5d5be28351a31cd8bd013eedbd3afeb548fb7216e34467185fb613511d7017c8b272deebf3e7e576161ad823a28086f950b676d32e70a98a8b08dd21acbbeec685f9aaf8a0989b521e70324ed47b895497acfc7422e77dfc03cfd6bc40a68fd4501cf8f7560e1cf18925d5013db4a2f66203195940c0d9b5bb36fbb16d1cd755acf323aeb2f78d8f76290975840f1439da62183af54d25b075a53b88f816057a4c0be29e5d7e5ec03edb58868c3c5bcb3d468013d09700a398e08bc0c2f7996f98587ecbdc590436a76bf93033c3ccbf3f9ba978e07f5b09802fd60672e33e1cebb9578292bc9a67a5460e40251602536f8452af37085865bd705339ce3491ff3820482c9aeffec8430552c51bad78785bb6ad5a136d6f232c8a29b541997a0795deada542376412ffc165f23a0811fba50a90bc1b86c47e30010f0d8ec8698002cb1a36c08d9358cd0fd914245b49a138a6f6bd440acdbd0d140dfcb1c1af3e7282d21293436bebf898075a68ebacf18e971b77dc0244c54835841f3547208e5c93a689f81f1a099837570abc36119eaef5fbbf82b8266f941695a884118b151a365e0ba2cd19182ff815b760aecac952a8ed3bcaa2b0e2d99d40afc60d2d6f6d9b8f9e6030b5d27ad243df29593f4052f60741ee402abe27bc6ce9df958929730ca4bf344e40268b34a0b0907ac47d8a7cc522cd6f0c82cc4b3393b351b8102f35bd5f9e1d667829d617a4963e477983e622b599719f575c3fc34dbeb7c28ec87758f9134fdf2af36faf5c47675d22b5f7a8c0f97399f0b4d0d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001059692f3b969945457c63ba4d26b296413da9c2d0574d5602cfe4f76bb9835872d9e6dcb1983bcd699dfaa20102c36f273c0c6a98381ab96ae6cc7a595e8594426258106afb045d571a74027189fe1cdc3acbfbd043e323226e1dc86894186a043d18ac4321e291d4fe5c7d539b8d37516d674cb4d5f27fbcf12ef99779e6c04b2dec2803e339671f703580aac1f453089dfe17aa5e38e5330ac6df47ae0d8099915e020698628bdb49f367fcc1e5807e1a2f3c752b38b74c8f9dff0f194aa0a0a24568058bcfeacd21129a1bb8541d2ef641b4bd2db5ed8ba6a978905fd1c2bf4b74dfe354e86bbdc8bda0baa214aec629159cfc6de89803979ae70e7662fff05586d7148ad010e9bc8a7a007cedafdc10e073e02f6b266d8127092b6d03e3bf00d659493253aa5ddec1ae875f663f94857f6f51f667d992be4875d9d9d25a89c6cc0dcace2259c89e7bacc480d8b1520beec4a56ad1becec0f131b91f6378fb853d2278e49f0ed57d7d31b3921f038d1a908c8aaf88dce640eb1343041e8369abfdfc440f9ccb90349f4db501d411f236ec60487f5b871c5bb00f988503160240a1255d434761cc3630bdb3e24910f0ba02ec1bf0dde0eb222e16359415a66f228de7f685b935d9fc9fbdeb3bde59955cac0cc138d3f74990f0a38f6f3994b9301a0ea2be847a765267354c8111cc07259f5283b71bc88f16f12fa6247b3c34c0a892661b65e8d0176a08083cafde1fd463dfbd1cd10d5593ca0982c3a31b2ca0f32169335a686ac0a0fe045cc98e3b266b00a3bec59a8a3789709f6f720a6d175009444d30889136cd23aa52ce2c668d08c8fa31a54c760bdd185020797db5ee56c1e956c10fc367917acba0d70f496ff5af3bdebdc94632bdc4544ce0559a538e41f9adbdd56ee06f1aa472397f04a87d92425d8b6f4f8c1585bbc295622a0810729085514601a30a9f1e7d380432a638d54170e76c3786a27f1ac5405493fb5cf51174e9dcda792de2fe21647f76cf1e4782cac7be68c4fc6ff7c902d3fececf291b3b992ead9a22c47a3a691107727edcad34001d30639b9b6bf67adecff2223ded81738eca5a45e2d5201fcc0c67f295f235277cfbd6a0db2579a13ee079a65abe72da2ca5deda3486b95de1ee628059f46798f36efc458542707150614451be87354c5494df9c453c495dc63397159c03d05e0eb638f034273c054a72501c46afd91968d9f3425a8aefd04369e6984da28d01206f7459f71d15f461f01062b5d00583d367927b2e83945495d251dade6d9605bb147a9d44aecfb05e6730adec8debd8e3ff08af5fbaac4f7112338b44c88c5a3ea2c31f89158f4fe92f60b4bfc235c3296cdd351c59838eaadbd8287cb5fe4433b6a9b0289a46dc869f601708fc4ebb37ffef5aea5879af2d721eab1652f66afce8980ac22ffc386f4c005419165c5021478c647e20414407a4d55684a88b78b65418f34b6f1cdd80f29007c3b325d36f324761d37b542d32d590257b0ff3ed2309dc3a12af699909e620b694c3af903b24b73bb89d544adba078736590980b5fd27c0b55db8d893647f0758bf8dda46cbe07976f6269e7f849aee6e3c25ca100021cbbc2866a2c4dd33012d85a41bcc7ff3e50ef3366da28aeca0174471b64c6ab9d051c0bda89bfeea0386353f4e6802fe44aefefae66de6b2d32a5c569c96795032058996a300bd9d0c621a157688ea5774ce221fba4af1dd1c768cf084725f75b9730bb8811bb4dd02796092e230745d11bb16a32a058d314fea1fb755b4b59d630c2563244315490e208fec98f332df8fa9f96ca60541d3d5ab0c3c66a0a9b055103e4a7a44ee1a069eff2c3781b5e185a63cfed0c1a744d05e115ac343ff4600ff471f5e24b7a608e257c9c615f3542e00c40283b87d617622544c202461bb4b0b4931ba1f547b075d2438d7766c0efc7e7a7382d909f54280b8d1c88b05cc9de7fb4c4f07aba498706c1df6dd9ef44c750dda646ffda95bd6c989077a67ce86b785e7c8b543140c1f92850bf4fb337a15d149f15907fa40161a102698169051b42a8762d2a59708670a44172c3279fb4fa16567506c62df8954348a219889bc106a96ad9551f202a720d4332fc78d2bbac8ac71db1128efbfd253b3b69dc3e35dc721c2a4400609ad4f7c033042a11c2fd8b7f0dd5d3a71d26b674a61608daf94eacd0a4c21340bf6701080d144dacb5515956749b34b9228ff4e5604d9bb2b8352095b63211e07e3b7e354c5a758e6db255d70300c1bf192e33362b0b509ae7d35d1226acedb0a591dd7c46a62a6ef24d13dbdbe4592e80d5a393960f65d3658b9782721528501f8ebe0a980281ce71629d7997813e81e5437faefe53161579ea1c8c32267860f230dfdf71d4c47e31e78341354d33c1ec2fa14ba274703a0ae383e2c700aad04e34505f4cc2d723544c77901c1a33e8d1b469519f04b2feef2d82fd6dde3df0206ac3b62f0bc8dc0cac26621f5311e2589836ed76644e52b78fb34d39fe45e0c476198efa3083b41d930edb6dc2fa57058d18cb1ecf08d5e28b5fa24e9c82f0c43ef71fa21ddf17f8ac973499b770fda32f7f24c3484d91f47888a28fe07f4032e1f203b77209f2b240e7f73addcfee3623498bce85183d87088638e0cfade08e4dd2b3e89c1fa901eed665d2cce8f95f1222902bc60c5c766099959faa8ac06e305284c71b0d6bd86078750bf8b62869ffbd68533d646d0ca52334d124735088c8605573ab2e35558b035da57a027164ae887ab9489ee4cdbe10b3fd2487f2ffb81d04be8fde8840b39d0f95c095a3d5635f748fcb806f84886a9204892dafe6cba1aedbd135c07439e8e482ec4dd9ad54d7f9d0a0ba5eb8f9a281d5c8df86d",
// 5->16 (all above typical)
"03000502000353414c1089033146560c0235131109220802010102f5cb199505232d0fac9c603b817a3731bbd9c29f33a2abcd7d87e7769edebbdb02000353414c10428d01a00160121227070f641f0b06121703e748f2e0744149fe29f6d3fc47de0d3d04eb499b34b95e2d07831f48f9d9ee6102000353414c10a201dc016c4437090819270901060818030c92eabd619159292e5ee0c5db6f1aa08bd8f0b6f8841a1438be230e342e8dd81a02000353414c1090022f7d227440031306190e01050813028f54232d770c212486c99308e48cef6b27605c5daa7cd7f00389f74dda42387e02000353414c10fd01022a2838bc011b2b280309032703050248c611e6b9f5460cd299880ee89cd656f4bc67f42b1b585ffadf09490c622b80100003283fcfa7e2cc56470d378848a12fba8fc7961c5cc6383eb517fc509f52104ab50353414c00b40003fbd69ed76762c6ff09790ad2de6205be87e11c171e097f602916897560ef31010353414c008500030929c783bbe0f597d29431318f285b15689190b144be185b58f628876f91e83e0353414c00c20003f38ece073d019847f0064d39b0a272956d6e17382d095ea253a1559a3ca563470353414c00620003121bf48ff28cfe4d3c09176ba11a3fa44710adcbf4720ec22b6c18d78e5f12fa0353414c004700035858e82060f0fdd2fe46926e56e136f5958d7352cbfc824806b347c5ad2d94b20353414c00c30003e6565d41cb70aa763ebf8c5bdeb7d35afc51895335c3681d21d3f501badb6f1d0353414c00ef000385b9d9e92d64c35c98ef867f0243d0740bd2b7b96a9172aa709dec5274d0a6fe0353414c000a00034d19b474b842e1ed8c1d5814c376688ba08c850f13fbfa61a4ee81daca70cf280353414c00470003cf6bec4fb4cdfde439c8c4efbba27a6947b28ac0761506f4157cdf43831bbbd50353414c0076000326f5fb2cc37d45eeb95c96e32da7d0e1ed1fdcd2f917615d625b6d54fc50354e0353414c00f200030b1eb958ce6ac6e8d4463cad80ef79b1b356815a4bdc3e38b5506ad70957f03b0353414c005700030a176f34f500177f691d792000191a4d986a29b410c7a11d806e8cb82df216b70353414c00a80003af3d43e889b1efdb48331dcb52f1d4a049faf124990d4f68d2b09d10087172420353414c0089000374e7d0e19a53525ba3fc99c03862a1992d932014f3009b45fa0910986590841d0353414c00f300039c9738b44759d7b8e8c9dbd7b7a9f52381da83a5313ad86cdbc00c4fbe25009a0353414c003c2101be2b1eb98118943354daf19235f988a50c7509b94cf123f5e9fc6b00785813e70300103a2ecd7f16676362f4a2a744fa2e16f5f130ed01702afd373eb15c76bc85bf1a89d682fad1162e2ee9885e4b6e672aa9c8ee055d00c63f0fe8577e320ede702638fe0f35476504d18f2cd8d40e276875fa45e536e038e8e73df584369d1778078a2ec5be9125f1b46d525fbcbe4de697fed1ebeb8db5b0005b2ca050b0888f0c198938408f2fee84f1b178f8a7da1f2ab6199576e80f131c82526fb25bc7c01603c2a1c04a06c1076362f21be02369cb9f5f35720fc8ce2de833d2f7ca9acf9acdd28eb3c6933824ec7f1cf33843873d1d42f2eea2c9e08a7e145d07fc0156aa68b320eec5563409a33338fd4e76e49009cd2d1934349ed4c2d104d1f48da434f8f98f4663afd2833d8ac8bd8c388bc511fe0c6ca5e4d65fda63da50595552a1d082aaf49d7cebd68153dbb6b1e36eee1fd16e8641ffab34d4d75ff31e540711b6e1ce7243e5bf4c271fd3e0214fa62c43135a07f1733ca26bfbaca7270bef7fa2e3030e658738409d62b4a83ea8afac2eb3564f27f97da6c2b6a4c6a30fe08440d0f83398b78736dd012c8fc4264698692647394f82543e6ea257e973b3807fea9d3f6b51a53f02e8000f6bd744ed3ab99008a698d926cc18fe1fe20ef7fbdb3c0b26efe36b0b1d633032fb8ad29935f472339d5954fd3edcf1b1418b2571ee960d18cc18a549dba8019238c0712ee523c41dcf44567a9265a03412fca7db9a10a9cf8b4195530f9b0fedfa6494fab8430353414c0353414c0007e08cb302f93517eb0210a56354e328cad54a872c4960b05af883b74e8dc1a1e949ff4c72c438fed02aa3e250257267a325557c1f1c6503857737d066ce15dbc4ca7ab1f5e5020350ef2c8ddf53d916011c571033ab61798bd9d65cfdefbe865da61eb8ae4f28e3bf3840cf1fa3ec28691ee92a62046fc506e311e08dea85101b9502adc1078179c66252fd01eaaeb85145549c65a4ca5ead6b3d5ba940a2e8f76275b073538a1444f168b237b9d43003399c756ef64dadee3c28abfdf46aaf145d77e1a8eefdf8893e50c278667560844e68f44336ff9b8f4f5e5e0a18a76b19ae2045b5d8527198adde170bf2740e6662b4c55c2ae49ea34ccf9b42620d92a313c17a8d6a7b76ec3b5793841fd14576c9a5fc3226058a6e62ad501fcf62a9d6d9b2609da5a5f2ee70a28610a37168481e0d1f25025435b8193240cf96838f9abc09a8f07170966c7cd80667aae92d93b570474fc7e8cba3ad10d84f2b08e2e208f4bfa7c2960c4d785556459c1b0d9fafa8a8548cabc19653a93352e8bb82b27695d5715fb7c3d95de0bbceb96c5aa4714bad4538f81f095e4a2940fd0dff878a0828911f09cb0c7b0f7f784a4c9b57152823ca6471cd555d1648400065f993feb2ea512923cebfdd3cff71ed45c62ef56050c99b42cb718b252c566506750224ac139f6e4581af7e33bf2bd1730990e3a6b60119f56868b524f5932bb1cfafe31aa0028fe3aa3a4c91978953579acf17bafa62644e3ef1135c02aa19c932214561d5bf711e5f6af4d01b0be9c1960373663bc7bca252f837968675893dfcfe9634d96b8fc717e4341be4970a9cdb6fe7b731a1da98962a62d4a9103f199e0f8d9a03a6064aa77dacf8813bffa7b31da0b3ae446d89764129615c615d719d8d3844dd7c521fbe75a131436b89aa1e8a335969c1d6919fe528601086cfb4044287742d01c9c30ccd6167961f8b459872897e67e1c7ac63dcd5159d24668b5e3f7653ceab8fe25271d508c6132c626e9677e28305d54337b26d2be4247a2daf9de767f506000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001dc0d42b65e71efe0241c57f6e352fb1f7686643ea5c31d71e1322dbd1e315971a95ff894982b51836aee64a590cc481667118242f8ff5b4a5fc87c545525f60c277b13187c9abdcacf40f4acdd51a3892f2b3f7a7012e79b6be9c412251dfa3719a65cb35dffd5624a5c2905f21c8ad19aeefb08a98df86722c36f306b545906f41209e297839aaeea830bf46c006d9f3f87886615ee8eee14bb11533f69410a4290a8f642ee96ab4b0d0317b50bc0c15f625fcd0ff02b113e6710ef3f7d78050a6fe71fb1c0ce82160ac5ced754dcaf3d27fa6a02c34413ec74289f5dd483d88f13455ede41874971f3b0bb1c9e16113e3a652d1d5f246a64d55d47f46d646929daa976c44fcb962df4790e5e96fc3df807a1838a0e62f8f52f26f581744aa001db68596adf022fcb10a52f36eb8814441b71b6b56c29c1f9e7f49aed15a093ca9343f06487ae859a54587e3c83902abc7b54203444fffe3691f904ed84cfc5378986a65a9c734e8a5d66623cd346a400fe5e11c5c93a288d5461fbcbc70aee7a832c462f856af5a01307ea2653b819294e13f7667ae520ba909eee6c14995d518c328535cb5d5f5270946380f565a24da22a10206f11d59a9248d7934918227cc31f51b351813f8a9315b043825c2f5502e2f786cdc79f7679f02181c1b8aa6a8d6c27b1e4d23a7b423813d216c7ff70ed5e88d559d2704ecb4b9cf7fcd891c70a3d87a418f2b64485985ea4af13526e85e14e29d50b239725fc00020532fc7a3980bf70e05321c24b90f5ef11d639c037b2881e07b07ce4810b96682836fec98d5423e7139e22af52fc4edcb35e4d3deb5d88c28867dc5e1450ac278fb204a2c2befd18e4da26890beec2ccece1c4b1928c9c4a1cc1a9e79bc9f8c874169445bb4f4f9bade1ff82fe05154be75cb3e1d116576a6e94dcf91d25dbd22afdfeb5bbd8c88b30e099258b8d17b6cfadd70bf33b303697ff321486b050e0925bfae90208c999f161396f71ff05931e7183cdc64c3704c36f643539462f5a8908ba61fb720737326eae46110360d04d456187571e590f8115306dd86ceddcef031156e445b1bddbece4e39dcbc2002d06f0887ef13abbbf3669d8a6d2be9f488ec81fb42d89383b2201e917daa716242527e33c21ebbaba098738c9ee7c9ad725ee3bfde9738bf76818f999f7a64e8cddc2ec5e344c18f4e66d92063e8417a17e201b0b9bd867e2a7f2548802281d13296866d1b328738815a84821375e6219d0963104aba3e7a713bcb244353819ae1a4fada6e7e4c8b90c939d2b5f9c1f31bd11490bfe92eada58b4319c9139ad72d665b188428717b3ce77acb553fe093c987d2401099437633f0fe47756ac2f8732d9470d8444542bfedda513f15f304fe214fd0ced606b8b84322ae8e36942a037cb8640441e0eb2964895eb276371329cabe00885e211e90e79cc5758984ec17ad6b1a09766d66b6002ebd37716400c35372c0db810c381a2bf31c321c394f0abadb8acf106da3305770b463ab0ea7fdd4bcb0118c1086f3b33880ddd71fdcebd022aef44aecc9e593f71a2bce821bdc47a6408cbe996bf643d4a4922c0df2042f941001612b490dfac3db9e9b08f175dcd0c011bededda2c0adbe25975740f5d7e8181780f34cc6791ace454ce11975fe5c20e6a4e1c569fc41bd08688d9d616f7f6bcb1b159581a936b4411fbd843f0cf7409a4891ead0143364290c35fab3cb371fca74cfcae06562c2da02e6577d284dd0b2a47592fb690b3b4f90b19b8414659957f8e515d15b77786f28d65d81e3d6404c4152e3ec82073843a6ea762f022e88e296789ec7654efdee01db402b09cb70286534744b0fadc0ab22a3cbd7665256c2d79afb35e444ca12df6f77587ccc60fa6af4b545b516a75fbcc64706e841932e5e6716d9ef794b5d6a96151231d2b0e3947b226e2857cb3ff0a6d4456cee3a9074a077f0837265c9bb31237e486b06cf3e6b77bd6f8e4d7ea937e5734046ba4a77f2e8b03960add19fb702044f36e0bab15986566eed31f3242f0bcad9c1eca8ebb33422c90b04da0e3d6964aa1c70a7b794e115ef3f42fd39e7461ff994a8d5a81e3e4d5ea87bcf403ae327ae7ae0c35818d94e8e87db0f45a8ee12831aefe350b625adf0886c7566c9cd608f8bd0f3b9a0dfcf5d19de57af7a03a3816e3ae3232fdd1ca14cfea417cba6e3624b60bbd28fe5638ed34868b021fbda7842e0a4d430fe70088ee428cb4b98a5ea03e018cc945576ee8cd6f6a6dcb3ed3773f3690c7bd55b1a427e6e2ab63b10c4bb20f932288ffca9bc94e1b87c309299e9058cdce2d821d64ea77492f2a20e9b98a05ea841bb61828dd851ae730ddf6c5496874a89eabf32b07bac2b5bdd1814f5e0939362a1f083192ad24e8018483aa73692690719424970ba16c37dde55fe222096a56115e8c89840ee0a560eeb68616ff7b976d1d49dd60773fcde69689e12f024138de10766277f152abef69e951737ef115be104e32b97c13e20d5c13cecd0f8bbbf17de72c33845fb59e705db22b5285ba1a09a0f5b46418e72bc2dec3820739b651f411b2498e8c1411d900a224c75e64f76aad78e6515b16ee2d4b5c400cab5f3807f8ecfc69c2c078844b86606c59fb12e107cec6f863238aed6cdd260236f2aa470cdc7cac32ec25cb472eb9170add7b78498d4caab677a1dcd7a81b09d606ab5856bea83b944729ba596aba961f85014fa66b4d17c465c7ecd83b3c0c1f50cdcc84680fe229fead6cc9a446e86ca6db6d66a32f930eaed2f9a5aab4264cbeb1bf7adfa0a9cbae5ba3e76a1e8714381d647bcf26b688c54468d5491000c513a37aa6f6ca55285139a489e9efcdcb27c13f8d3633fa45d73caa97c75703894c77bf2c1aca924af69b41564903a1f2d9cc0d06532ff5908d04f75715330898e6316ffba70fa1b1f9bc280b54d82bb661d04001e8bf65b9807c5ba7c0ea012a9b7887de6cbecdb687fe82b9fca6a5f9530d95fb246fb84f8b07f87953b004abb1cdae07d1c242a88b92219456e4e493a0f6e885a9b80a0674e55b330ca606de48b30e8b1a4ec28b0486f841b94793e047c1e7e7988c7cca1475ef4b871609da44d3a4a0b8353353999fa9f79781127739fbdfa427ca0f32e3a387156f5305a8576126606728258ad967c7fc91d8e0c50b685b485f4f57ac33e7b09a8a1201fe08d067f272723accde747063a6d6f7362501e0a852fa309d485bc9adb1f90f10c4ad71d8dd3bbfff195b54ae6f89cfd4a874115db38a3ae9ded1d2c8609901cc3fe89308bc72b170bf877eb4bca5e377dd9cd1cd1fa69d11a01fd7c77bc003c427e7d4957a48829f0150319350d1f6bf50d01c66a568003ef4ce73c5877a053a591f463ceefad51d079c0a76d8ad20f57476855d9a78bd7d35b58709183103c5fa170f04721711b25ec306898320c78acae030f530787e894752722db5970cbef421b2c8de343779a3374b8d009bb53239b48ca24092c5ba28bd7e00e70b00c589cf51bc430b62ce2de8d3a547bc6dcf5019948435a23404eeedbb2b6e89092ce40faa33cb3b9ab54933e866f7e70d98dd5c4947b2021b2a8dd80a6b3558ecbc1a84321ec8bf75ea70a30db199e8abe526c392394c10c1ff10b07efc75f503657ff856221ba082026dc57d78689793dc12ba98bad5f5fe550344f3f3fb5109dec1c0b07ec83069732b98ccb006b9db81965414d715a9f31de6ad8533b8bd0204b5e420d28c531c8948b0a4346023dbeffcf50d945e5186b4b7d945ad7a7d0ffe0ed2cc1af99cc493c601d97e5e200dcb263a9e520e15405875d8d3b87e1c0ba4ab09ee55c95c346c785581cf60415b7668dcb95d537f425879b2c7713ff90eaf050b9fe88c6cd5fd3fadf7479348a7990318a5766513747e6775ba2af55d05205fb757ca9d64f43a6a280de9f6c4d2bf5bed2a181ac74bdd5819646c9f8406fa8f248d81f4c5aae6a0bfe4b0034da1cc709ef0256ca97c24422368aa1d870d384722120ac0adc6b41368c53c90202dde5b7b6eb530c4484adbe3747d96c50f575f5f9894d00fd66fd7ec8e5be6ce1801c982695680a3474b82c60c79bca3069fa41437f3c9cbc1798e13b53ab61b673d88df4fa03d6a907fb69108e5880200472f98c7e410c6295fc18aec9b92cdd3024ea28f7dbe350032231972d5eecc017044b725c939e2a228402ccbd0950d3841dc1c500ab1393011a607ba3774110a7d2285cc92868371909e16f7e5c2ced86f04f4d7f30e10af95db2bc26c32ae0777d97ab1906fd17a47cb081525e82c710ff8fc070d98371ca839b8a95343c5073186a7c7f7fdef262ce0500358b31d6a18c17f417fe983642198cee6d8b7230e96795d0100e0706ad2bf2ac6f14133dce9837dfacb386b963b791f4e1987b4bee83506a2d29d6ddfd0f3a1cffcff65735a7b3eaf4e5c1fb36716bc0f81f5580f5694beaa2ba4674023b7251d39bc258e4b3fb414c294787b2b6f9ae6f5826b0b576c3746b6ccd93937766cbee50cd15849b1e71f5f3c445914fc056f20672a09b24d9dff3df8c41da93dc313c447e45980a8e6f7135630a818979bd70cdd1b0a993c36b989dd437f8a07861e2e7b5759123885873ff12b3abc1f3197c2bbb9061c63839690284488f7222b728f797df522c4139d61a2746198158d03ba09f308efd80c69f814d0981b8b724048b66f60f540f49b82c0ddaf1d271b16c5907e093db4041d1ffe5334aa042dd86c4a28766aee303ae05590841f358064b323fe08f8ef5409358fdfde578990e47d249b40f098706e4a671a907797545f7333190ab39f1e6f115cfb60a8ab485d90c275ed545263bd795b8edaa05fcc3896794b027db049edb1b4aebcfcd0b31ede9b40150a7c63993d7d83dca2fc2f87e5da09015fb72b63f4af67e2319a3a60b9f6443c8ed6e2b8fa2bda9fc60262f4ffee4e0e12317baa11c6d8d200b0d9d4f031688e0174fe4fae7035b7100361083a1ea001a2ec7cd72e337b19160c3d406dd0ef2b1b270e393e96e4a0803e75bb802e7a0f886c284cbe8987e3be2fd037df4226c06cfa97175a6229e3e06548402be9c30ca2e4b412bdc6a26f82eb6d02a117cfca4e5e73e4e52611ccde56d531fbeac9097581d3ed0ec1cd8439bd4c1720d1e8927a13a047e4a1e5147b2ff2b83df15f0b9c6d4304a4fb0b05e45e06ba36cc2b8dc9eb7ea8ef334fb882c4e6fbe0e9885774e300d047085defde91725fdc2660ec36b1ddcd82ea769a5c5300a38797f51598142ee08d62c0ee16d0f53c14b932fe333fb757f47028b91e7eb3fda8451aca6ca364486e1b245da45168dc184affabe31c454eddf0afcf05330ee2cf5cf9b66b72ff494a11a308921468af46e72103199fded9f4eda1d29083c0b305935323ebb6a022f2e6a2a9be0b5a454c1c216553ee0498e5c3f3844ddd73e61eef68e0",
};
for (const char *tx_hex: txs_hex)
{
cryptonote::blobdata bd;
ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(std::string(tx_hex), bd));
cryptonote::transaction tx, pruned_tx;
crypto::hash tx_hash, tx_prefix_hash;
ASSERT_TRUE(parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash));
ASSERT_TRUE(tx.version == 3); // >=2
ASSERT_FALSE(tx.pruned);
ASSERT_TRUE(rct::is_rct_bulletproof_plus(tx.rct_signatures.type)); // salvium started with bulletproof+
const uint64_t tx_weight = cryptonote::get_transaction_weight(tx);
ASSERT_TRUE(parse_and_validate_tx_base_from_blob(bd, pruned_tx));
ASSERT_TRUE(pruned_tx.version == 3); // >=2
ASSERT_TRUE(pruned_tx.pruned);
const uint64_t pruned_tx_weight = cryptonote::get_pruned_transaction_weight(pruned_tx);
ASSERT_EQ(tx_weight, pruned_tx_weight);
}
}