1
0
Fork 0
forked from lthn/blockchain

signature refactoring: pre-core tests

This commit is contained in:
cryptozoidberg 2022-06-23 16:22:55 +02:00
parent 4f80c7c334
commit fa4b8ab130
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
8 changed files with 92 additions and 59 deletions

View file

@ -6673,7 +6673,7 @@ bool blockchain_storage::is_output_allowed_for_input(const output_key_or_htlc_v&
}
}
//------------------------------------------------------------------
bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, const signature_v& input_sigs_v, uint64_t split_height, const alt_chain_type& alt_chain) const
bool blockchain_storage::validate_alt_block_ms_input(const transaction& input_tx, const crypto::hash& input_tx_hash, size_t input_index, uint64_t split_height, const alt_chain_type& alt_chain) const
{
// Main and alt chain outline:
//

View file

@ -759,7 +759,7 @@ namespace currency
FIELDS(*static_cast<transaction_prefix *>(this))
CHAIN_TRANSITION_VER(TRANSACTION_VERSION_INITAL, transaction_v1)
CHAIN_TRANSITION_VER(TRANSACTION_VERSION_PRE_HF4, transaction_v1)
FIELD(signature)
FIELD(signatures)
FIELD(attachment)
END_SERIALIZE()
};
@ -774,7 +774,7 @@ namespace currency
vin.clear();
vout.clear();
extra.clear();
signature = NLSAG_sig();
signatures.clear();
attachment.clear();
}

View file

@ -90,13 +90,15 @@ template<typename transaction_current_t>
bool transition_convert(const transaction_current_t& from, transaction_v1& to)
{
to.attachment = from.attachment;
if (from.signature.type() == typeid(NLSAG_sig))
for (const auto& s : from.signatures)
{
to.signatures = boost::get<NLSAG_sig>(from.signature).s;
}
else
{
throw std::runtime_error("Unexpected type in signature_v");
if (s.type() == typeid(NLSAG_sig))
{
to.signatures.push_back(boost::get<NLSAG_sig>(s).s); ;
}else
{
throw std::runtime_error("Unexpected type in signature_v");
}
}
return true;
}
@ -106,6 +108,10 @@ bool transition_convert(const transaction_v1& from, transaction_current_t& to)
{
// TODO: consider using move semantic for 'from'
to.attachment = from.attachment;
to.signature = NLSAG_sig({from.signatures});
to.signatures.resize(from.signatures.size());
for (size_t i = 0; i != from.signatures.size(); i++)
{
boost::get<NLSAG_sig>(to.signatures[i]).s = from.signatures[i];
}
return true;
}

View file

@ -196,7 +196,6 @@ namespace currency
posin.k_image = pe.keyimage;
tx.vin.push_back(posin);
//reserve place for ring signature
//tx.signature = NLSAG_sig();
tx.signatures.resize(1);
tx.signatures[0] = NLSAG_sig();
boost::get<NLSAG_sig>(tx.signatures[0]).s.resize(posin.key_offsets.size());

View file

@ -56,7 +56,9 @@ namespace currency
bool operator ==(const currency::transaction& a, const currency::transaction& b);
bool operator ==(const currency::block& a, const currency::block& b);
bool operator ==(const currency::extra_attachment_info& a, const currency::extra_attachment_info& b);
bool operator ==(const currency::NLSAG_sig& a, const currency::NLSAG_sig& b);
bool operator ==(const currency::void_sig& a, const currency::void_sig& b);
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b);
typedef boost::multiprecision::uint128_t uint128_tl;

View file

@ -3507,8 +3507,9 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b,
return false; // to get rid of warning
}else
{
NLSAG_sig& signatures = boost::get<NLSAG_sig>(b.miner_tx.signature);
WLT_CHECK_AND_ASSERT_MES(signatures.s.size() == 1 && signatures.s[0].size() == txin.key_offsets.size(),
WLT_CHECK_AND_ASSERT_MES(b.miner_tx.signatures.size() == 1 &&
b.miner_tx.signatures[0].type() == typeid(NLSAG_sig) &&
boost::get<NLSAG_sig>(b.miner_tx.signatures[0]).s.size() == txin.key_offsets.size(),
false, "Wrong signatures amount in coinbase transacton");
@ -3536,12 +3537,12 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b,
keys_ptrs,
derived_secret_ephemeral_key,
0,
&signatures.s[0][0]);
&boost::get<NLSAG_sig>(b.miner_tx.signatures[0]).s[0]);
WLT_LOG_L4("GENERATED RING SIGNATURE: block_id " << block_hash
<< "txin.k_image" << txin.k_image
<< "key_ptr:" << *keys_ptrs[0]
<< "signature:" << signatures.s[0][0]);
<< "signature:" << boost::get<NLSAG_sig>(b.miner_tx.signatures[0]).s);
return true;
}

View file

@ -234,14 +234,14 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n
// (5/5) signatures
VARIANT_SWITCH_BEGIN(tx.signature);
VARIANT_CASE_CONST(NLSAG_sig, signatures)
{
LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector
LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector
// As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present).
// Having a_keys, we determine index of A key in multisig output keys array.
// Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature.
VARIANT_SWITCH_BEGIN(tx.signatures[0]);
VARIANT_CASE_CONST(NLSAG_sig, signature)
{
// As we don't have b_keys we can't be sure which signature is B's and which is reserved for A (should be a null-placeholder, if present).
// Having a_keys, we determine index of A key in multisig output keys array.
// Thus it's possible to determine the order of signatures (A, B or B, A), and, eventually, validate B signature.
crypto::public_key source_tx_pub_key = get_tx_pub_key_from_extra(source_tx);
r = crypto::generate_key_derivation(source_tx_pub_key, a_keys.view_secret_key, der);
LOC_CHK(r, "generate_key_derivation failed");
@ -250,14 +250,14 @@ bool wallet2::validate_escrow_release(const transaction& tx, bool release_type_n
LOC_CHK(r, "derive_public_key failed");
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid ms output keys array, size: " << source_ms_out.keys.size());
LOC_CHK(signatures.s[0].size() == 2, "internal error: invalid signature size for input #0: " << signatures.s[0].size())
LOC_CHK(signature.size() == 2, "internal error: invalid signature size for input #0: " << signature.size())
size_t ms_out_key_a_index = std::find(source_ms_out.keys.begin(), source_ms_out.keys.end(), ephemeral_pub_key) - source_ms_out.keys.begin();
LOC_CHK(ms_out_key_a_index < source_ms_out.keys.size(), "internal error: can't find A ephemeral pub key within ms output keys");
size_t ms_out_key_b_index = 1 - ms_out_key_a_index;
// in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in signatures.s[0]
// in this particular case (source_ms_out.minimum_sigs == source_ms_out.keys.size() == 2) index in 'keys' is the same as index in signature
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], signatures.s[0][ms_out_key_b_index]);
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[ms_out_key_b_index], signature[ms_out_key_b_index]);
LOC_CHK(r, "B signature for multisig input is invalid");
}
VARIANT_CASE_CONST(zarcanum_sig, s);
@ -418,17 +418,18 @@ bool wallet2::validate_escrow_cancel_release(const currency::transaction& tx, co
// (5/5) signatures
VARIANT_SWITCH_BEGIN(tx.signature);
LOC_CHK(tx.signatures.size() == 1, "invalid singatures size: " << tx.signatures.size()); // only 1 input means only 1 signature vector
VARIANT_SWITCH_BEGIN(tx.signatures[0]);
VARIANT_CASE_CONST(NLSAG_sig, signatures)
{
LOC_CHK(signatures.s.size() == 1, "invalid singatures size: " << signatures.s.size()); // only 1 input means only 1 signature vector
LOC_CHK(signatures.s[0].size() == 2, "invalid signature[0] size: " << signatures.s[0].size()); // it's expected to contain A-party signature and null-sig placeholder
LOC_CHK(signature.size() == 2, "invalid signature[0] size: " << signature.size()); // it's expected to contain A-party signature and null-sig placeholder
LOC_CHK(source_ms_out.keys.size() == 2, "internal error: invalid source ms output keys array, size: " << source_ms_out.keys.size());
size_t a_sign_index = (signatures.s[0][0] != null_sig) ? 0 : 1;
size_t a_sign_index = (signature[0] != null_sig) ? 0 : 1;
crypto::hash tx_hash_for_signature = prepare_prefix_hash_for_sign(tx, 0, get_transaction_hash(tx));
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], signatures.s[0][a_sign_index]);
r = crypto::check_signature(tx_hash_for_signature, source_ms_out.keys[a_sign_index], signature[a_sign_index]);
LOC_CHK(r, "A signature for multisig input is invalid");
}
VARIANT_CASE_CONST(zarcanum_sig, s);

View file

@ -26,6 +26,12 @@ struct Struct
char blob[8];
};
std::ostream& operator <<(std::ostream& o, const currency::signature_v& v)
{
return o;
}
template <class Archive>
struct serializer<Archive, Struct>
{
@ -270,6 +276,18 @@ namespace
}
return res;
}
template<typename T>
std::vector<T> linearize_vector2(const std::vector< currency::signature_v >& vec_vec)
{
std::vector<T> res;
BOOST_FOREACH(const auto& vec, vec_vec)
{
res.insert(res.end(), vec.begin(), vec.end());
}
return res;
}
}
bool test_get_varint_packed_size_for_num(uint64_t n)
@ -330,7 +348,8 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
ASSERT_EQ(tx.signatures, tx1.signatures);
//ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Miner tx without signatures
txin_gen txin_gen1;
@ -344,10 +363,11 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
ASSERT_EQ(tx.signatures, tx1.signatures);
//ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Miner tx with empty signatures 2nd vector
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(1);
tx.signatures.resize(1);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures + counter
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -355,29 +375,30 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
ASSERT_EQ(tx.signatures, tx1.signatures);
//ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
//TX VALIDATION REMOVED FROM SERIALIZATION
/*
// Miner tx with one signature
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
tx.signatures[0].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 empty vectors
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(0);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(0);
tx.signatures.resize(2);
tx.signatures[0].resize(0);
tx.signatures[1].resize(0);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 signatures
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(1);
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
*/
// Two txin_gen, no signatures
tx.vin.push_back(txin_gen1);
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(0);
tx.signatures.resize(0);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(10, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -385,14 +406,15 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
ASSERT_EQ(tx.signatures, tx1.signatures);
//ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Two txin_gen, signatures vector contains only one empty element
//signatures.resize(1);
//ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two empty elements
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
tx.signatures.resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(12, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
@ -400,7 +422,9 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
{
ASSERT_TRUE(false);
}
ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
ASSERT_EQ(tx.signatures, tx1.signatures);
//ASSERT_EQ(linearize_vector2(boost::get<currency::NLSAG_sig>(tx.signature).s), linearize_vector2(boost::get<currency::NLSAG_sig>(tx1.signature).s));
// Two txin_gen, signatures vector contains three empty elements
//signatures.resize(3);
@ -415,7 +439,7 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
// A few bytes instead of signature
tx.vin.clear();
tx.vin.push_back(txin_gen1);
boost::get<currency::NLSAG_sig>(tx.signature).s.clear();
tx.signatures.clear();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
blob.append(std::string(sizeof(crypto::signature) / 2, 'x'));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
@ -438,28 +462,28 @@ TEST(Serialization, serializes_transacion_signatures_correctly)
/*
// Too much signatures for two inputs
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(3);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[2].resize(2);
tx.signatures.resize(3);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
tx.signatures[2].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too little elements
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(1);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too much elements
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(3);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
tx.signatures.resize(2);
tx.signatures[0].resize(3);
tx.signatures[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// There are signatures for each input
boost::get<currency::NLSAG_sig>(tx.signature).s.resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[0].resize(2);
boost::get<currency::NLSAG_sig>(tx.signature).s[1].resize(2);
tx.signatures.resize(2);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);