mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-12-22 23:38:52 +00:00
Merge pull request #5052
b6534c40
ringct: remove unused senderPk from ecdhTuple (moneromooo-monero)7d375981
ringct: the commitment mask is now deterministic (moneromooo-monero)99d946e6
ringct: encode 8 byte amount, saving 24 bytes per output (moneromooo-monero)cdc3ccec
ringct: save 3 bytes on bulletproof size (moneromooo-monero)f931e16c
add a bulletproof version, new bulletproof type, and rct config (moneromooo-monero)
This commit is contained in:
commit
0daa00e035
@ -45,6 +45,8 @@
|
|||||||
#include "ringct/rctTypes.h"
|
#include "ringct/rctTypes.h"
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
|
|
||||||
|
BOOST_CLASS_VERSION(rct::ecdhTuple, 1)
|
||||||
|
|
||||||
//namespace cryptonote {
|
//namespace cryptonote {
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -247,9 +249,19 @@ namespace boost
|
|||||||
template <class Archive>
|
template <class Archive>
|
||||||
inline void serialize(Archive &a, rct::ecdhTuple &x, const boost::serialization::version_type ver)
|
inline void serialize(Archive &a, rct::ecdhTuple &x, const boost::serialization::version_type ver)
|
||||||
{
|
{
|
||||||
a & x.mask;
|
if (ver < 1)
|
||||||
a & x.amount;
|
{
|
||||||
// a & x.senderPk; // not serialized, as we do not use it in monero currently
|
a & x.mask;
|
||||||
|
a & x.amount;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crypto::hash8 &amount = (crypto::hash8&)x.amount;
|
||||||
|
if (!Archive::is_saving::value)
|
||||||
|
{
|
||||||
|
memset(&x.mask, 0, sizeof(x.mask));
|
||||||
|
memset(&x.amount, 0, sizeof(x.amount));
|
||||||
|
}
|
||||||
|
a & amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -295,7 +307,7 @@ namespace boost
|
|||||||
a & x.type;
|
a & x.type;
|
||||||
if (x.type == rct::RCTTypeNull)
|
if (x.type == rct::RCTTypeNull)
|
||||||
return;
|
return;
|
||||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof)
|
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2)
|
||||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||||
@ -323,7 +335,7 @@ namespace boost
|
|||||||
a & x.type;
|
a & x.type;
|
||||||
if (x.type == rct::RCTTypeNull)
|
if (x.type == rct::RCTTypeNull)
|
||||||
return;
|
return;
|
||||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof)
|
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2)
|
||||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||||
@ -337,7 +349,7 @@ namespace boost
|
|||||||
if (x.p.rangeSigs.empty())
|
if (x.p.rangeSigs.empty())
|
||||||
a & x.p.bulletproofs;
|
a & x.p.bulletproofs;
|
||||||
a & x.p.MGs;
|
a & x.p.MGs;
|
||||||
if (x.type == rct::RCTTypeBulletproof)
|
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2)
|
||||||
a & x.p.pseudoOuts;
|
a & x.p.pseudoOuts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@
|
|||||||
#define HF_VERSION_MIN_MIXIN_10 8
|
#define HF_VERSION_MIN_MIXIN_10 8
|
||||||
#define HF_VERSION_ENFORCE_RCT 6
|
#define HF_VERSION_ENFORCE_RCT 6
|
||||||
#define HF_VERSION_PER_BYTE_FEE 8
|
#define HF_VERSION_PER_BYTE_FEE 8
|
||||||
|
#define HF_VERSION_SMALLER_BP 10
|
||||||
|
|
||||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||||
|
|
||||||
|
@ -2517,6 +2517,18 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from v10, allow bulletproofs v2
|
||||||
|
if (hf_version < HF_VERSION_SMALLER_BP) {
|
||||||
|
if (tx.version >= 2) {
|
||||||
|
if (tx.rct_signatures.type == rct::RCTTypeBulletproof2)
|
||||||
|
{
|
||||||
|
MERROR_VER("Bulletproofs v2 are not allowed before v" << HF_VERSION_SMALLER_BP);
|
||||||
|
tvc.m_invalid_output = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
@ -2557,7 +2569,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof)
|
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
||||||
rv.mixRing.resize(pubkeys.size());
|
rv.mixRing.resize(pubkeys.size());
|
||||||
@ -2583,7 +2595,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
|||||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||||
rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
||||||
}
|
}
|
||||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof)
|
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rct::RCTTypeBulletproof2)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(rv.p.MGs.size() == tx.vin.size(), false, "Bad MGs size");
|
CHECK_AND_ASSERT_MES(rv.p.MGs.size() == tx.vin.size(), false, "Bad MGs size");
|
||||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||||
@ -2857,6 +2869,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
|||||||
}
|
}
|
||||||
case rct::RCTTypeSimple:
|
case rct::RCTTypeSimple:
|
||||||
case rct::RCTTypeBulletproof:
|
case rct::RCTTypeBulletproof:
|
||||||
|
case rct::RCTTypeBulletproof2:
|
||||||
{
|
{
|
||||||
// check all this, either reconstructed (so should really pass), or not
|
// check all this, either reconstructed (so should really pass), or not
|
||||||
{
|
{
|
||||||
|
@ -816,6 +816,7 @@ namespace cryptonote
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case rct::RCTTypeBulletproof:
|
case rct::RCTTypeBulletproof:
|
||||||
|
case rct::RCTTypeBulletproof2:
|
||||||
if (!is_canonical_bulletproof_layout(rv.p.bulletproofs))
|
if (!is_canonical_bulletproof_layout(rv.p.bulletproofs))
|
||||||
{
|
{
|
||||||
MERROR_VER("Bulletproof does not have canonical form");
|
MERROR_VER("Bulletproof does not have canonical form");
|
||||||
@ -843,7 +844,7 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
if (!tx_info[n].result)
|
if (!tx_info[n].result)
|
||||||
continue;
|
continue;
|
||||||
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof)
|
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2)
|
||||||
continue;
|
continue;
|
||||||
if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures))
|
if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures))
|
||||||
{
|
{
|
||||||
|
@ -198,7 +198,7 @@ namespace cryptonote
|
|||||||
return addr.m_view_public_key;
|
return addr.m_view_public_key;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, rct::RangeProofType range_proof_type, rct::multisig_out *msout, bool shuffle_outs)
|
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool shuffle_outs)
|
||||||
{
|
{
|
||||||
hw::device &hwdev = sender_account_keys.get_device();
|
hw::device &hwdev = sender_account_keys.get_device();
|
||||||
|
|
||||||
@ -531,7 +531,7 @@ namespace cryptonote
|
|||||||
|
|
||||||
// the non-simple version is slightly smaller, but assumes all real inputs
|
// the non-simple version is slightly smaller, but assumes all real inputs
|
||||||
// are on the same index, so can only be used if there just one ring.
|
// are on the same index, so can only be used if there just one ring.
|
||||||
bool use_simple_rct = sources.size() > 1 || range_proof_type != rct::RangeProofBorromean;
|
bool use_simple_rct = sources.size() > 1 || rct_config.range_proof_type != rct::RangeProofBorromean;
|
||||||
|
|
||||||
if (!use_simple_rct)
|
if (!use_simple_rct)
|
||||||
{
|
{
|
||||||
@ -629,9 +629,9 @@ namespace cryptonote
|
|||||||
get_transaction_prefix_hash(tx, tx_prefix_hash);
|
get_transaction_prefix_hash(tx, tx_prefix_hash);
|
||||||
rct::ctkeyV outSk;
|
rct::ctkeyV outSk;
|
||||||
if (use_simple_rct)
|
if (use_simple_rct)
|
||||||
tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, range_proof_type, hwdev);
|
tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, rct_config, hwdev);
|
||||||
else
|
else
|
||||||
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, hwdev); // same index assumption
|
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption
|
||||||
memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey));
|
memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey));
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
|
CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout");
|
||||||
@ -644,7 +644,7 @@ namespace cryptonote
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, rct::RangeProofType range_proof_type, rct::multisig_out *msout)
|
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout)
|
||||||
{
|
{
|
||||||
hw::device &hwdev = sender_account_keys.get_device();
|
hw::device &hwdev = sender_account_keys.get_device();
|
||||||
hwdev.open_tx(tx_key);
|
hwdev.open_tx(tx_key);
|
||||||
@ -662,7 +662,7 @@ namespace cryptonote
|
|||||||
additional_tx_keys.push_back(keypair::generate(sender_account_keys.get_device()).sec);
|
additional_tx_keys.push_back(keypair::generate(sender_account_keys.get_device()).sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, range_proof_type, msout);
|
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
|
||||||
hwdev.close_tx();
|
hwdev.close_tx();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -674,7 +674,7 @@ namespace cryptonote
|
|||||||
crypto::secret_key tx_key;
|
crypto::secret_key tx_key;
|
||||||
std::vector<crypto::secret_key> additional_tx_keys;
|
std::vector<crypto::secret_key> additional_tx_keys;
|
||||||
std::vector<tx_destination_entry> destinations_copy = destinations;
|
std::vector<tx_destination_entry> destinations_copy = destinations;
|
||||||
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, rct::RangeProofBorromean, NULL);
|
return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}, NULL);
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool generate_genesis_block(
|
bool generate_genesis_block(
|
||||||
|
@ -95,8 +95,8 @@ namespace cryptonote
|
|||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
|
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
|
||||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
||||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
|
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
|
||||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, rct::multisig_out *msout = NULL);
|
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL);
|
||||||
|
|
||||||
bool generate_genesis_block(
|
bool generate_genesis_block(
|
||||||
block& bl
|
block& bl
|
||||||
|
@ -208,8 +208,8 @@ namespace hw {
|
|||||||
return encrypt_payment_id(payment_id, public_key, secret_key);
|
return encrypt_payment_id(payment_id, public_key, secret_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) = 0;
|
virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) = 0;
|
||||||
virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) = 0;
|
virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) = 0;
|
||||||
|
|
||||||
virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0;
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0;
|
||||||
|
@ -302,13 +302,13 @@ namespace hw {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) {
|
bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) {
|
||||||
rct::ecdhEncode(unmasked, sharedSec);
|
rct::ecdhEncode(unmasked, sharedSec, short_amount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_default::ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) {
|
bool device_default::ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) {
|
||||||
rct::ecdhDecode(masked, sharedSec);
|
rct::ecdhDecode(masked, sharedSec, short_amount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +111,8 @@ namespace hw {
|
|||||||
|
|
||||||
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
||||||
|
|
||||||
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override;
|
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) override;
|
||||||
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override;
|
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) override;
|
||||||
|
|
||||||
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
||||||
|
@ -1140,13 +1140,13 @@ namespace hw {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout) {
|
bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout, bool short_amount) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
||||||
rct::ecdhTuple unmasked_x = unmasked;
|
rct::ecdhTuple unmasked_x = unmasked;
|
||||||
this->controle_device->ecdhEncode(unmasked_x, AKout_x);
|
this->controle_device->ecdhEncode(unmasked_x, AKout_x, short_amount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_BLIND);
|
int offset = set_command_header_noopt(INS_BLIND);
|
||||||
@ -1177,13 +1177,13 @@ namespace hw {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout) {
|
bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout, bool short_amount) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
||||||
rct::ecdhTuple masked_x = masked;
|
rct::ecdhTuple masked_x = masked;
|
||||||
this->controle_device->ecdhDecode(masked_x, AKout_x);
|
this->controle_device->ecdhDecode(masked_x, AKout_x, short_amount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_UNBLIND);
|
int offset = set_command_header_noopt(INS_UNBLIND);
|
||||||
|
@ -191,8 +191,8 @@ namespace hw {
|
|||||||
|
|
||||||
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
||||||
|
|
||||||
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override;
|
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_format) override;
|
||||||
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override;
|
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_format) override;
|
||||||
|
|
||||||
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
||||||
|
@ -270,7 +270,7 @@ namespace tx {
|
|||||||
throw std::invalid_argument("RV not initialized");
|
throw std::invalid_argument("RV not initialized");
|
||||||
}
|
}
|
||||||
auto tp = m_ct.rv->type;
|
auto tp = m_ct.rv->type;
|
||||||
return tp == rct::RCTTypeBulletproof;
|
return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_offloading() const {
|
bool is_offloading() const {
|
||||||
|
@ -670,18 +670,58 @@ namespace rct {
|
|||||||
|
|
||||||
//Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a
|
//Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a
|
||||||
// where C= aG + bH
|
// where C= aG + bH
|
||||||
void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec) {
|
static key ecdhHash(const key &k)
|
||||||
key sharedSec1 = hash_to_scalar(sharedSec);
|
{
|
||||||
key sharedSec2 = hash_to_scalar(sharedSec1);
|
char data[38];
|
||||||
//encode
|
rct::key hash;
|
||||||
sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes);
|
memcpy(data, "amount", 6);
|
||||||
sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes);
|
memcpy(data + 6, &k, sizeof(k));
|
||||||
|
cn_fast_hash(hash, data, sizeof(data));
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
void ecdhDecode(ecdhTuple & masked, const key & sharedSec) {
|
static void xor8(key &v, const key &k)
|
||||||
key sharedSec1 = hash_to_scalar(sharedSec);
|
{
|
||||||
key sharedSec2 = hash_to_scalar(sharedSec1);
|
for (int i = 0; i < 8; ++i)
|
||||||
|
v.bytes[i] ^= k.bytes[i];
|
||||||
|
}
|
||||||
|
key genCommitmentMask(const key &sk)
|
||||||
|
{
|
||||||
|
char data[15 + sizeof(key)];
|
||||||
|
memcpy(data, "commitment_mask", 15);
|
||||||
|
memcpy(data + 15, &sk, sizeof(sk));
|
||||||
|
key scalar;
|
||||||
|
hash_to_scalar(scalar, data, sizeof(data));
|
||||||
|
return scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool v2) {
|
||||||
|
//encode
|
||||||
|
if (v2)
|
||||||
|
{
|
||||||
|
unmasked.mask = zero();
|
||||||
|
xor8(unmasked.amount, ecdhHash(sharedSec));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key sharedSec1 = hash_to_scalar(sharedSec);
|
||||||
|
key sharedSec2 = hash_to_scalar(sharedSec1);
|
||||||
|
sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes);
|
||||||
|
sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool v2) {
|
||||||
//decode
|
//decode
|
||||||
sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes);
|
if (v2)
|
||||||
sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes);
|
{
|
||||||
|
masked.mask = genCommitmentMask(sharedSec);
|
||||||
|
xor8(masked.amount, ecdhHash(sharedSec));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key sharedSec1 = hash_to_scalar(sharedSec);
|
||||||
|
key sharedSec2 = hash_to_scalar(sharedSec1);
|
||||||
|
sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes);
|
||||||
|
sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,8 @@ namespace rct {
|
|||||||
|
|
||||||
//Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a
|
//Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a
|
||||||
// where C= aG + bH
|
// where C= aG + bH
|
||||||
void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec);
|
key genCommitmentMask(const key &sk);
|
||||||
void ecdhDecode(ecdhTuple & masked, const key & sharedSec);
|
void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool v2);
|
||||||
|
void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool v2);
|
||||||
}
|
}
|
||||||
#endif /* RCTOPS_H */
|
#endif /* RCTOPS_H */
|
||||||
|
@ -79,9 +79,12 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace rct {
|
namespace rct {
|
||||||
Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector<uint64_t> &amounts)
|
Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector<uint64_t> &amounts, epee::span<const key> sk)
|
||||||
{
|
{
|
||||||
masks = rct::skvGen(amounts.size());
|
CHECK_AND_ASSERT_THROW_MES(amounts.size() == sk.size(), "Invalid amounts/sk sizes");
|
||||||
|
masks.resize(amounts.size());
|
||||||
|
for (size_t i = 0; i < masks.size(); ++i)
|
||||||
|
masks[i] = genCommitmentMask(sk[i]);
|
||||||
Bulletproof proof = bulletproof_PROVE(amounts, masks);
|
Bulletproof proof = bulletproof_PROVE(amounts, masks);
|
||||||
CHECK_AND_ASSERT_THROW_MES(proof.V.size() == amounts.size(), "V does not have the expected size");
|
CHECK_AND_ASSERT_THROW_MES(proof.V.size() == amounts.size(), "V does not have the expected size");
|
||||||
C = proof.V;
|
C = proof.V;
|
||||||
@ -416,7 +419,7 @@ namespace rct {
|
|||||||
hashes.push_back(hash2rct(h));
|
hashes.push_back(hash2rct(h));
|
||||||
|
|
||||||
keyV kv;
|
keyV kv;
|
||||||
if (rv.type == RCTTypeBulletproof)
|
if (rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2)
|
||||||
{
|
{
|
||||||
kv.reserve((6*2+9) * rv.p.bulletproofs.size());
|
kv.reserve((6*2+9) * rv.p.bulletproofs.size());
|
||||||
for (const auto &p: rv.p.bulletproofs)
|
for (const auto &p: rv.p.bulletproofs)
|
||||||
@ -686,7 +689,7 @@ namespace rct {
|
|||||||
// must know the destination private key to find the correct amount, else will return a random number
|
// must know the destination private key to find the correct amount, else will return a random number
|
||||||
// Note: For txn fees, the last index in the amounts vector should contain that
|
// Note: For txn fees, the last index in the amounts vector should contain that
|
||||||
// Thus the amounts vector will be "one" longer than the destinations vectort
|
// Thus the amounts vector will be "one" longer than the destinations vectort
|
||||||
rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, hw::device &hwdev) {
|
rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev) {
|
||||||
CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size() || amounts.size() == destinations.size() + 1, "Different number of amounts/destinations");
|
CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size() || amounts.size() == destinations.size() + 1, "Different number of amounts/destinations");
|
||||||
CHECK_AND_ASSERT_THROW_MES(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations");
|
CHECK_AND_ASSERT_THROW_MES(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations");
|
||||||
CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing");
|
CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing");
|
||||||
@ -716,7 +719,7 @@ namespace rct {
|
|||||||
//mask amount and mask
|
//mask amount and mask
|
||||||
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
||||||
rv.ecdhInfo[i].amount = d2h(amounts[i]);
|
rv.ecdhInfo[i].amount = d2h(amounts[i]);
|
||||||
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]);
|
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set txn fee
|
//set txn fee
|
||||||
@ -737,18 +740,18 @@ namespace rct {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, hw::device &hwdev) {
|
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, const RCTConfig &rct_config, hw::device &hwdev) {
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
ctkeyM mixRing;
|
ctkeyM mixRing;
|
||||||
ctkeyV outSk;
|
ctkeyV outSk;
|
||||||
tie(mixRing, index) = populateFromBlockchain(inPk, mixin);
|
tie(mixRing, index) = populateFromBlockchain(inPk, mixin);
|
||||||
return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, kLRki, msout, index, outSk, hwdev);
|
return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
//RCT simple
|
//RCT simple
|
||||||
//for post-rct only
|
//for post-rct only
|
||||||
rctSig genRctSimple(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, RangeProofType range_proof_type, hw::device &hwdev) {
|
rctSig genRctSimple(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev) {
|
||||||
const bool bulletproof = range_proof_type != RangeProofBorromean;
|
const bool bulletproof = rct_config.range_proof_type != RangeProofBorromean;
|
||||||
CHECK_AND_ASSERT_THROW_MES(inamounts.size() > 0, "Empty inamounts");
|
CHECK_AND_ASSERT_THROW_MES(inamounts.size() > 0, "Empty inamounts");
|
||||||
CHECK_AND_ASSERT_THROW_MES(inamounts.size() == inSk.size(), "Different number of inamounts/inSk");
|
CHECK_AND_ASSERT_THROW_MES(inamounts.size() == inSk.size(), "Different number of inamounts/inSk");
|
||||||
CHECK_AND_ASSERT_THROW_MES(outamounts.size() == destinations.size(), "Different number of amounts/destinations");
|
CHECK_AND_ASSERT_THROW_MES(outamounts.size() == destinations.size(), "Different number of amounts/destinations");
|
||||||
@ -764,7 +767,7 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rctSig rv;
|
rctSig rv;
|
||||||
rv.type = bulletproof ? RCTTypeBulletproof : RCTTypeSimple;
|
rv.type = bulletproof ? (rct_config.bp_version == 0 || rct_config.bp_version >= 2 ? RCTTypeBulletproof2 : RCTTypeBulletproof) : RCTTypeSimple;
|
||||||
rv.message = message;
|
rv.message = message;
|
||||||
rv.outPk.resize(destinations.size());
|
rv.outPk.resize(destinations.size());
|
||||||
if (!bulletproof)
|
if (!bulletproof)
|
||||||
@ -793,7 +796,7 @@ namespace rct {
|
|||||||
std::vector<uint64_t> proof_amounts;
|
std::vector<uint64_t> proof_amounts;
|
||||||
size_t n_amounts = outamounts.size();
|
size_t n_amounts = outamounts.size();
|
||||||
size_t amounts_proved = 0;
|
size_t amounts_proved = 0;
|
||||||
if (range_proof_type == RangeProofPaddedBulletproof)
|
if (rct_config.range_proof_type == RangeProofPaddedBulletproof)
|
||||||
{
|
{
|
||||||
rct::keyV C, masks;
|
rct::keyV C, masks;
|
||||||
if (hwdev.get_mode() == hw::device::TRANSACTION_CREATE_FAKE)
|
if (hwdev.get_mode() == hw::device::TRANSACTION_CREATE_FAKE)
|
||||||
@ -803,7 +806,8 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts));
|
const epee::span<const key> keys{&amount_keys[0], amount_keys.size()};
|
||||||
|
rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys));
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
|
CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
|
||||||
#endif
|
#endif
|
||||||
@ -817,7 +821,7 @@ namespace rct {
|
|||||||
else while (amounts_proved < n_amounts)
|
else while (amounts_proved < n_amounts)
|
||||||
{
|
{
|
||||||
size_t batch_size = 1;
|
size_t batch_size = 1;
|
||||||
if (range_proof_type == RangeProofMultiOutputBulletproof)
|
if (rct_config.range_proof_type == RangeProofMultiOutputBulletproof)
|
||||||
while (batch_size * 2 + amounts_proved <= n_amounts && batch_size * 2 <= BULLETPROOF_MAX_OUTPUTS)
|
while (batch_size * 2 + amounts_proved <= n_amounts && batch_size * 2 <= BULLETPROOF_MAX_OUTPUTS)
|
||||||
batch_size *= 2;
|
batch_size *= 2;
|
||||||
rct::keyV C, masks;
|
rct::keyV C, masks;
|
||||||
@ -831,7 +835,8 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts));
|
const epee::span<const key> keys{&amount_keys[amounts_proved], batch_size};
|
||||||
|
rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts, keys));
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
|
CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
|
||||||
#endif
|
#endif
|
||||||
@ -853,7 +858,7 @@ namespace rct {
|
|||||||
//mask amount and mask
|
//mask amount and mask
|
||||||
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
||||||
rv.ecdhInfo[i].amount = d2h(outamounts[i]);
|
rv.ecdhInfo[i].amount = d2h(outamounts[i]);
|
||||||
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]);
|
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set txn fee
|
//set txn fee
|
||||||
@ -884,7 +889,7 @@ namespace rct {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rctSig genRctSimple(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, hw::device &hwdev) {
|
rctSig genRctSimple(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> &inamounts, const vector<xmr_amount> &outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev) {
|
||||||
std::vector<unsigned int> index;
|
std::vector<unsigned int> index;
|
||||||
index.resize(inPk.size());
|
index.resize(inPk.size());
|
||||||
ctkeyM mixRing;
|
ctkeyM mixRing;
|
||||||
@ -894,7 +899,7 @@ namespace rct {
|
|||||||
mixRing[i].resize(mixin+1);
|
mixRing[i].resize(mixin+1);
|
||||||
index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin);
|
index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin);
|
||||||
}
|
}
|
||||||
return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, kLRki, msout, index, outSk, RangeProofBorromean, hwdev);
|
return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
//RingCT protocol
|
//RingCT protocol
|
||||||
@ -984,7 +989,8 @@ namespace rct {
|
|||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(rvp, false, "rctSig pointer is NULL");
|
CHECK_AND_ASSERT_MES(rvp, false, "rctSig pointer is NULL");
|
||||||
const rctSig &rv = *rvp;
|
const rctSig &rv = *rvp;
|
||||||
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "verRctSemanticsSimple called on non simple rctSig");
|
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2,
|
||||||
|
false, "verRctSemanticsSimple called on non simple rctSig");
|
||||||
const bool bulletproof = is_rct_bulletproof(rv.type);
|
const bool bulletproof = is_rct_bulletproof(rv.type);
|
||||||
if (bulletproof)
|
if (bulletproof)
|
||||||
{
|
{
|
||||||
@ -1083,7 +1089,8 @@ namespace rct {
|
|||||||
{
|
{
|
||||||
PERF_TIMER(verRctNonSemanticsSimple);
|
PERF_TIMER(verRctNonSemanticsSimple);
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "verRctNonSemanticsSimple called on non simple rctSig");
|
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2,
|
||||||
|
false, "verRctNonSemanticsSimple called on non simple rctSig");
|
||||||
const bool bulletproof = is_rct_bulletproof(rv.type);
|
const bool bulletproof = is_rct_bulletproof(rv.type);
|
||||||
// semantics check is early, and mixRing/MGs aren't resolved yet
|
// semantics check is early, and mixRing/MGs aren't resolved yet
|
||||||
if (bulletproof)
|
if (bulletproof)
|
||||||
@ -1149,7 +1156,7 @@ namespace rct {
|
|||||||
|
|
||||||
//mask amount and mask
|
//mask amount and mask
|
||||||
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
||||||
hwdev.ecdhDecode(ecdh_info, sk);
|
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2);
|
||||||
mask = ecdh_info.mask;
|
mask = ecdh_info.mask;
|
||||||
key amount = ecdh_info.amount;
|
key amount = ecdh_info.amount;
|
||||||
key C = rv.outPk[i].mask;
|
key C = rv.outPk[i].mask;
|
||||||
@ -1173,13 +1180,13 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask, hw::device &hwdev) {
|
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask, hw::device &hwdev) {
|
||||||
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof, false, "decodeRct called on non simple rctSig");
|
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, false, "decodeRct called on non simple rctSig");
|
||||||
CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
|
CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
|
||||||
CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
|
CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
|
||||||
|
|
||||||
//mask amount and mask
|
//mask amount and mask
|
||||||
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
||||||
hwdev.ecdhDecode(ecdh_info, sk);
|
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2);
|
||||||
mask = ecdh_info.mask;
|
mask = ecdh_info.mask;
|
||||||
key amount = ecdh_info.amount;
|
key amount = ecdh_info.amount;
|
||||||
key C = rv.outPk[i].mask;
|
key C = rv.outPk[i].mask;
|
||||||
@ -1203,7 +1210,7 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool signMultisig(rctSig &rv, const std::vector<unsigned int> &indices, const keyV &k, const multisig_out &msout, const key &secret_key) {
|
bool signMultisig(rctSig &rv, const std::vector<unsigned int> &indices, const keyV &k, const multisig_out &msout, const key &secret_key) {
|
||||||
CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull || rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof,
|
CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull || rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2,
|
||||||
false, "unsupported rct type");
|
false, "unsupported rct type");
|
||||||
CHECK_AND_ASSERT_MES(indices.size() == k.size(), false, "Mismatched k/indices sizes");
|
CHECK_AND_ASSERT_MES(indices.size() == k.size(), false, "Mismatched k/indices sizes");
|
||||||
CHECK_AND_ASSERT_MES(k.size() == rv.p.MGs.size(), false, "Mismatched k/MGs size");
|
CHECK_AND_ASSERT_MES(k.size() == rv.p.MGs.size(), false, "Mismatched k/MGs size");
|
||||||
|
@ -119,10 +119,10 @@ namespace rct {
|
|||||||
//decodeRct: (c.f. https://eprint.iacr.org/2015/1098 section 5.1.1)
|
//decodeRct: (c.f. https://eprint.iacr.org/2015/1098 section 5.1.1)
|
||||||
// uses the attached ecdh info to find the amounts represented by each output commitment
|
// uses the attached ecdh info to find the amounts represented by each output commitment
|
||||||
// must know the destination private key to find the correct amount, else will return a random number
|
// must know the destination private key to find the correct amount, else will return a random number
|
||||||
rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, hw::device &hwdev);
|
rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev);
|
||||||
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, hw::device &hwdev);
|
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, const RCTConfig &rct_config, hw::device &hwdev);
|
||||||
rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, hw::device &hwdev);
|
rctSig genRctSimple(const key & message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, xmr_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev);
|
||||||
rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, RangeProofType range_proof_type, hw::device &hwdev);
|
rctSig genRctSimple(const key & message, const ctkeyV & inSk, const keyV & destinations, const std::vector<xmr_amount> & inamounts, const std::vector<xmr_amount> & outamounts, xmr_amount txnFee, const ctkeyM & mixRing, const keyV &amount_keys, const std::vector<multisig_kLRki> *kLRki, multisig_out *msout, const std::vector<unsigned int> & index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev);
|
||||||
bool verRct(const rctSig & rv, bool semantics);
|
bool verRct(const rctSig & rv, bool semantics);
|
||||||
static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); }
|
static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); }
|
||||||
bool verRctSemanticsSimple(const rctSig & rv);
|
bool verRctSemanticsSimple(const rctSig & rv);
|
||||||
|
@ -217,6 +217,7 @@ namespace rct {
|
|||||||
{
|
{
|
||||||
case RCTTypeSimple:
|
case RCTTypeSimple:
|
||||||
case RCTTypeBulletproof:
|
case RCTTypeBulletproof:
|
||||||
|
case RCTTypeBulletproof2:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -228,6 +229,7 @@ namespace rct {
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case RCTTypeBulletproof:
|
case RCTTypeBulletproof:
|
||||||
|
case RCTTypeBulletproof2:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -120,17 +120,14 @@ namespace rct {
|
|||||||
// If the pedersen commitment to an amount is C = aG + bH,
|
// If the pedersen commitment to an amount is C = aG + bH,
|
||||||
// "mask" contains a 32 byte key a
|
// "mask" contains a 32 byte key a
|
||||||
// "amount" contains a hex representation (in 32 bytes) of a 64 bit number
|
// "amount" contains a hex representation (in 32 bytes) of a 64 bit number
|
||||||
// "senderPk" is not the senders actual public key, but a one-time public key generated for
|
|
||||||
// the purpose of the ECDH exchange
|
// the purpose of the ECDH exchange
|
||||||
struct ecdhTuple {
|
struct ecdhTuple {
|
||||||
key mask;
|
key mask;
|
||||||
key amount;
|
key amount;
|
||||||
key senderPk;
|
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
FIELD(mask)
|
FIELD(mask) // not saved from v2 BPs
|
||||||
FIELD(amount)
|
FIELD(amount)
|
||||||
// FIELD(senderPk) // not serialized, as we do not use it in monero currently
|
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,8 +228,13 @@ namespace rct {
|
|||||||
RCTTypeFull = 1,
|
RCTTypeFull = 1,
|
||||||
RCTTypeSimple = 2,
|
RCTTypeSimple = 2,
|
||||||
RCTTypeBulletproof = 3,
|
RCTTypeBulletproof = 3,
|
||||||
|
RCTTypeBulletproof2 = 4,
|
||||||
};
|
};
|
||||||
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
||||||
|
struct RCTConfig {
|
||||||
|
RangeProofType range_proof_type;
|
||||||
|
int bp_version;
|
||||||
|
};
|
||||||
struct rctSigBase {
|
struct rctSigBase {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
key message;
|
key message;
|
||||||
@ -249,7 +251,7 @@ namespace rct {
|
|||||||
FIELD(type)
|
FIELD(type)
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return true;
|
return true;
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2)
|
||||||
return false;
|
return false;
|
||||||
VARINT_FIELD(txnFee)
|
VARINT_FIELD(txnFee)
|
||||||
// inputs/outputs not saved, only here for serialization help
|
// inputs/outputs not saved, only here for serialization help
|
||||||
@ -278,7 +280,19 @@ namespace rct {
|
|||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
{
|
{
|
||||||
FIELDS(ecdhInfo[i])
|
if (type == RCTTypeBulletproof2)
|
||||||
|
{
|
||||||
|
ar.begin_object();
|
||||||
|
if (!typename Archive<W>::is_saving())
|
||||||
|
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
|
||||||
|
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
|
||||||
|
FIELD(amount);
|
||||||
|
ar.end_object();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIELDS(ecdhInfo[i])
|
||||||
|
}
|
||||||
if (outputs - i > 1)
|
if (outputs - i > 1)
|
||||||
ar.delimit_array();
|
ar.delimit_array();
|
||||||
}
|
}
|
||||||
@ -310,12 +324,15 @@ namespace rct {
|
|||||||
{
|
{
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return true;
|
return true;
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2)
|
||||||
return false;
|
return false;
|
||||||
if (type == RCTTypeBulletproof)
|
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2)
|
||||||
{
|
{
|
||||||
uint32_t nbp = bulletproofs.size();
|
uint32_t nbp = bulletproofs.size();
|
||||||
FIELD(nbp)
|
if (type == RCTTypeBulletproof2)
|
||||||
|
VARINT_FIELD(nbp)
|
||||||
|
else
|
||||||
|
FIELD(nbp)
|
||||||
ar.tag("bp");
|
ar.tag("bp");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
if (nbp > outputs)
|
if (nbp > outputs)
|
||||||
@ -351,7 +368,7 @@ namespace rct {
|
|||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
// we keep a byte for size of MGs, because we don't know whether this is
|
// we keep a byte for size of MGs, because we don't know whether this is
|
||||||
// a simple or full rct signature, and it's starting to annoy the hell out of me
|
// a simple or full rct signature, and it's starting to annoy the hell out of me
|
||||||
size_t mg_elements = (type == RCTTypeSimple || type == RCTTypeBulletproof) ? inputs : 1;
|
size_t mg_elements = (type == RCTTypeSimple || type == RCTTypeBulletproof || type == RCTTypeBulletproof2) ? inputs : 1;
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_elements, MGs);
|
PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_elements, MGs);
|
||||||
if (MGs.size() != mg_elements)
|
if (MGs.size() != mg_elements)
|
||||||
return false;
|
return false;
|
||||||
@ -369,7 +386,7 @@ namespace rct {
|
|||||||
for (size_t j = 0; j < mixin + 1; ++j)
|
for (size_t j = 0; j < mixin + 1; ++j)
|
||||||
{
|
{
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
size_t mg_ss2_elements = ((type == RCTTypeSimple || type == RCTTypeBulletproof) ? 1 : inputs) + 1;
|
size_t mg_ss2_elements = ((type == RCTTypeSimple || type == RCTTypeBulletproof || type == RCTTypeBulletproof2) ? 1 : inputs) + 1;
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_ss2_elements, MGs[i].ss[j]);
|
PREPARE_CUSTOM_VECTOR_SERIALIZATION(mg_ss2_elements, MGs[i].ss[j]);
|
||||||
if (MGs[i].ss[j].size() != mg_ss2_elements)
|
if (MGs[i].ss[j].size() != mg_ss2_elements)
|
||||||
return false;
|
return false;
|
||||||
@ -395,7 +412,7 @@ namespace rct {
|
|||||||
ar.delimit_array();
|
ar.delimit_array();
|
||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
if (type == RCTTypeBulletproof)
|
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2)
|
||||||
{
|
{
|
||||||
ar.tag("pseudoOuts");
|
ar.tag("pseudoOuts");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
@ -419,12 +436,12 @@ namespace rct {
|
|||||||
|
|
||||||
keyV& get_pseudo_outs()
|
keyV& get_pseudo_outs()
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyV const& get_pseudo_outs() const
|
keyV const& get_pseudo_outs() const
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1409,6 +1409,7 @@ static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &
|
|||||||
{
|
{
|
||||||
case rct::RCTTypeSimple:
|
case rct::RCTTypeSimple:
|
||||||
case rct::RCTTypeBulletproof:
|
case rct::RCTTypeBulletproof:
|
||||||
|
case rct::RCTTypeBulletproof2:
|
||||||
return rct::decodeRctSimple(rv, rct::sk2rct(scalar1), i, mask, hwdev);
|
return rct::decodeRctSimple(rv, rct::sk2rct(scalar1), i, mask, hwdev);
|
||||||
case rct::RCTTypeFull:
|
case rct::RCTTypeFull:
|
||||||
return rct::decodeRct(rv, rct::sk2rct(scalar1), i, mask, hwdev);
|
return rct::decodeRct(rv, rct::sk2rct(scalar1), i, mask, hwdev);
|
||||||
@ -5920,15 +5921,16 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
|
|||||||
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
|
LOG_PRINT_L1(" " << (n+1) << ": " << sd.sources.size() << " inputs, ring size " << sd.sources[0].outputs.size());
|
||||||
signed_txes.ptx.push_back(pending_tx());
|
signed_txes.ptx.push_back(pending_tx());
|
||||||
tools::wallet2::pending_tx &ptx = signed_txes.ptx.back();
|
tools::wallet2::pending_tx &ptx = signed_txes.ptx.back();
|
||||||
rct::RangeProofType range_proof_type = rct::RangeProofBorromean;
|
rct::RCTConfig rct_config = { rct::RangeProofBorromean, 0 };
|
||||||
if (sd.use_bulletproofs)
|
if (sd.use_bulletproofs)
|
||||||
{
|
{
|
||||||
range_proof_type = rct::RangeProofPaddedBulletproof;
|
rct_config.range_proof_type = rct::RangeProofPaddedBulletproof;
|
||||||
|
rct_config.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1;
|
||||||
}
|
}
|
||||||
crypto::secret_key tx_key;
|
crypto::secret_key tx_key;
|
||||||
std::vector<crypto::secret_key> additional_tx_keys;
|
std::vector<crypto::secret_key> additional_tx_keys;
|
||||||
rct::multisig_out msout;
|
rct::multisig_out msout;
|
||||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, range_proof_type, m_multisig ? &msout : NULL);
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, m_multisig ? &msout : NULL);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
|
||||||
// we don't test tx size, because we don't know the current limit, due to not having a blockchain,
|
// we don't test tx size, because we don't know the current limit, due to not having a blockchain,
|
||||||
// and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway,
|
// and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway,
|
||||||
@ -6390,12 +6392,13 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
|
|||||||
cryptonote::transaction tx;
|
cryptonote::transaction tx;
|
||||||
rct::multisig_out msout = ptx.multisig_sigs.front().msout;
|
rct::multisig_out msout = ptx.multisig_sigs.front().msout;
|
||||||
auto sources = sd.sources;
|
auto sources = sd.sources;
|
||||||
rct::RangeProofType range_proof_type = rct::RangeProofBorromean;
|
rct::RCTConfig rct_config = { rct::RangeProofBorromean, 0 };
|
||||||
if (sd.use_bulletproofs)
|
if (sd.use_bulletproofs)
|
||||||
{
|
{
|
||||||
range_proof_type = rct::RangeProofPaddedBulletproof;
|
rct_config.range_proof_type = rct::RangeProofPaddedBulletproof;
|
||||||
|
rct_config.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1;
|
||||||
}
|
}
|
||||||
bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, range_proof_type, &msout, false);
|
bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources, sd.splitted_dsts, ptx.change_dts.addr, sd.extra, tx, sd.unlock_time, ptx.tx_key, ptx.additional_tx_keys, sd.use_rct, rct_config, &msout, false);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype);
|
||||||
|
|
||||||
THROW_WALLET_EXCEPTION_IF(get_transaction_prefix_hash (tx) != get_transaction_prefix_hash(ptx.tx),
|
THROW_WALLET_EXCEPTION_IF(get_transaction_prefix_hash (tx) != get_transaction_prefix_hash(ptx.tx),
|
||||||
@ -7807,7 +7810,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
|||||||
std::vector<crypto::secret_key> additional_tx_keys;
|
std::vector<crypto::secret_key> additional_tx_keys;
|
||||||
rct::multisig_out msout;
|
rct::multisig_out msout;
|
||||||
LOG_PRINT_L2("constructing tx");
|
LOG_PRINT_L2("constructing tx");
|
||||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, rct::RangeProofBulletproof, m_multisig ? &msout : NULL);
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, m_multisig ? &msout : NULL);
|
||||||
LOG_PRINT_L2("constructed tx, r="<<r);
|
LOG_PRINT_L2("constructed tx, r="<<r);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
|
||||||
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
||||||
@ -7856,7 +7859,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
|
|||||||
|
|
||||||
void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
|
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, rct::RangeProofType range_proof_type)
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config)
|
||||||
{
|
{
|
||||||
using namespace cryptonote;
|
using namespace cryptonote;
|
||||||
// throw if attempting a transaction with no destinations
|
// throw if attempting a transaction with no destinations
|
||||||
@ -8038,7 +8041,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
|||||||
rct::multisig_out msout;
|
rct::multisig_out msout;
|
||||||
LOG_PRINT_L2("constructing tx");
|
LOG_PRINT_L2("constructing tx");
|
||||||
auto sources_copy = sources;
|
auto sources_copy = sources;
|
||||||
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, range_proof_type, m_multisig ? &msout : NULL);
|
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, m_multisig ? &msout : NULL);
|
||||||
LOG_PRINT_L2("constructed tx, r="<<r);
|
LOG_PRINT_L2("constructed tx, r="<<r);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype);
|
||||||
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
||||||
@ -8083,7 +8086,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
|
|||||||
LOG_PRINT_L2("Creating supplementary multisig transaction");
|
LOG_PRINT_L2("Creating supplementary multisig transaction");
|
||||||
cryptonote::transaction ms_tx;
|
cryptonote::transaction ms_tx;
|
||||||
auto sources_copy_copy = sources_copy;
|
auto sources_copy_copy = sources_copy;
|
||||||
bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, range_proof_type, &msout, false);
|
bool r = cryptonote::construct_tx_with_tx_key(m_account.get_keys(), m_subaddresses, sources_copy_copy, splitted_dsts, change_dts.addr, extra, ms_tx, unlock_time,tx_key, additional_tx_keys, true, rct_config, &msout, false);
|
||||||
LOG_PRINT_L2("constructed tx, r="<<r);
|
LOG_PRINT_L2("constructed tx, r="<<r);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
|
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time, m_nettype);
|
||||||
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
THROW_WALLET_EXCEPTION_IF(upper_transaction_weight_limit <= get_transaction_weight(tx), error::tx_too_big, tx, upper_transaction_weight_limit);
|
||||||
@ -8794,7 +8797,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|||||||
const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0);
|
const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE, 0);
|
||||||
const bool use_rct = use_fork_rules(4, 0);
|
const bool use_rct = use_fork_rules(4, 0);
|
||||||
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
|
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
|
||||||
const rct::RangeProofType range_proof_type = bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean;
|
const rct::RCTConfig rct_config {
|
||||||
|
bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean,
|
||||||
|
bulletproof ? (use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1) : 0
|
||||||
|
};
|
||||||
|
|
||||||
const uint64_t base_fee = get_base_fee();
|
const uint64_t base_fee = get_base_fee();
|
||||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||||
@ -9107,7 +9113,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|||||||
tx.selected_transfers.size() << " inputs");
|
tx.selected_transfers.size() << " inputs");
|
||||||
if (use_rct)
|
if (use_rct)
|
||||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
test_tx, test_ptx, range_proof_type);
|
test_tx, test_ptx, rct_config);
|
||||||
else
|
else
|
||||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
||||||
@ -9150,7 +9156,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
|||||||
while (needed_fee > test_ptx.fee) {
|
while (needed_fee > test_ptx.fee) {
|
||||||
if (use_rct)
|
if (use_rct)
|
||||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
test_tx, test_ptx, range_proof_type);
|
test_tx, test_ptx, rct_config);
|
||||||
else
|
else
|
||||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
||||||
@ -9223,7 +9229,7 @@ skip_tx:
|
|||||||
extra, /* const std::vector<uint8_t>& extra, */
|
extra, /* const std::vector<uint8_t>& extra, */
|
||||||
test_tx, /* OUT cryptonote::transaction& tx, */
|
test_tx, /* OUT cryptonote::transaction& tx, */
|
||||||
test_ptx, /* OUT cryptonote::transaction& tx, */
|
test_ptx, /* OUT cryptonote::transaction& tx, */
|
||||||
range_proof_type);
|
rct_config);
|
||||||
} else {
|
} else {
|
||||||
transfer_selected(tx.dsts,
|
transfer_selected(tx.dsts,
|
||||||
tx.selected_transfers,
|
tx.selected_transfers,
|
||||||
@ -9363,7 +9369,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|||||||
const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE);
|
const bool use_per_byte_fee = use_fork_rules(HF_VERSION_PER_BYTE_FEE);
|
||||||
const bool use_rct = fake_outs_count > 0 && use_fork_rules(4, 0);
|
const bool use_rct = fake_outs_count > 0 && use_fork_rules(4, 0);
|
||||||
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
|
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
|
||||||
const rct::RangeProofType range_proof_type = bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean;
|
const rct::RCTConfig rct_config {
|
||||||
|
bulletproof ? rct::RangeProofPaddedBulletproof : rct::RangeProofBorromean,
|
||||||
|
bulletproof ? (use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1) : 0,
|
||||||
|
};
|
||||||
const uint64_t base_fee = get_base_fee();
|
const uint64_t base_fee = get_base_fee();
|
||||||
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
const uint64_t fee_multiplier = get_fee_multiplier(priority, get_fee_algorithm());
|
||||||
const uint64_t fee_quantization_mask = get_fee_quantization_mask();
|
const uint64_t fee_quantization_mask = get_fee_quantization_mask();
|
||||||
@ -9439,7 +9448,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|||||||
tx.selected_transfers.size() << " outputs");
|
tx.selected_transfers.size() << " outputs");
|
||||||
if (use_rct)
|
if (use_rct)
|
||||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
test_tx, test_ptx, range_proof_type);
|
test_tx, test_ptx, rct_config);
|
||||||
else
|
else
|
||||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
||||||
@ -9476,7 +9485,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|||||||
}
|
}
|
||||||
if (use_rct)
|
if (use_rct)
|
||||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
test_tx, test_ptx, range_proof_type);
|
test_tx, test_ptx, rct_config);
|
||||||
else
|
else
|
||||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
|
||||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
||||||
@ -9515,7 +9524,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
|||||||
pending_tx test_ptx;
|
pending_tx test_ptx;
|
||||||
if (use_rct) {
|
if (use_rct) {
|
||||||
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
|
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
|
||||||
test_tx, test_ptx, range_proof_type);
|
test_tx, test_ptx, rct_config);
|
||||||
} else {
|
} else {
|
||||||
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
|
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, tx.needed_fee, extra,
|
||||||
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
|
||||||
@ -10163,7 +10172,7 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de
|
|||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
hwdev.derivation_to_scalar(found_derivation, n, scalar1);
|
hwdev.derivation_to_scalar(found_derivation, n, scalar1);
|
||||||
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
||||||
hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1));
|
hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
const rct::key C = tx.rct_signatures.outPk[n].mask;
|
const rct::key C = tx.rct_signatures.outPk[n].mask;
|
||||||
rct::key Ctmp;
|
rct::key Ctmp;
|
||||||
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask");
|
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask");
|
||||||
@ -10677,7 +10686,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
|
|||||||
crypto::secret_key shared_secret;
|
crypto::secret_key shared_secret;
|
||||||
crypto::derivation_to_scalar(derivation, proof.index_in_tx, shared_secret);
|
crypto::derivation_to_scalar(derivation, proof.index_in_tx, shared_secret);
|
||||||
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[proof.index_in_tx];
|
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[proof.index_in_tx];
|
||||||
rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret));
|
rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
amount = rct::h2d(ecdh_info.amount);
|
amount = rct::h2d(ecdh_info.amount);
|
||||||
}
|
}
|
||||||
total += amount;
|
total += amount;
|
||||||
|
@ -764,7 +764,7 @@ namespace tools
|
|||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx);
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx);
|
||||||
void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
void transfer_selected_rct(std::vector<cryptonote::tx_destination_entry> dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
|
||||||
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
|
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
|
||||||
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, rct::RangeProofType range_proof_type);
|
uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config);
|
||||||
|
|
||||||
void commit_tx(pending_tx& ptx_vector);
|
void commit_tx(pending_tx& ptx_vector);
|
||||||
void commit_tx(std::vector<pending_tx>& ptx_vector);
|
void commit_tx(std::vector<pending_tx>& ptx_vector);
|
||||||
|
@ -42,7 +42,7 @@ using namespace cryptonote;
|
|||||||
// Tests
|
// Tests
|
||||||
|
|
||||||
bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& events,
|
bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& events,
|
||||||
size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type,
|
size_t mixin, size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config,
|
||||||
const std::function<bool(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations, size_t tx_idx)> &pre_tx,
|
const std::function<bool(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations, size_t tx_idx)> &pre_tx,
|
||||||
const std::function<bool(transaction &tx, size_t tx_idx)> &post_tx) const
|
const std::function<bool(transaction &tx, size_t tx_idx)> &post_tx) const
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
|
|||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||||
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||||
rct_txes.resize(rct_txes.size() + 1);
|
rct_txes.resize(rct_txes.size() + 1);
|
||||||
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, range_proof_type[n]);
|
bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||||
|
|
||||||
if (post_tx && !post_tx(rct_txes.back(), n))
|
if (post_tx && !post_tx(rct_txes.back(), n))
|
||||||
@ -157,7 +157,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
|
|||||||
crypto::secret_key amount_key;
|
crypto::secret_key amount_key;
|
||||||
crypto::derivation_to_scalar(derivation, o, amount_key);
|
crypto::derivation_to_scalar(derivation, o, amount_key);
|
||||||
rct::key rct_tx_mask;
|
rct::key rct_tx_mask;
|
||||||
if (rct_txes.back().rct_signatures.type == rct::RCTTypeSimple || rct_txes.back().rct_signatures.type == rct::RCTTypeBulletproof)
|
const uint8_t type = rct_txes.back().rct_signatures.type;
|
||||||
|
if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2)
|
||||||
rct::decodeRctSimple(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
|
rct::decodeRctSimple(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
|
||||||
else
|
else
|
||||||
rct::decodeRct(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
|
rct::decodeRct(rct_txes.back().rct_signatures, rct::sk2rct(amount_key), o, rct_tx_mask, hw::get_device("default"));
|
||||||
@ -173,8 +174,8 @@ bool gen_bp_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
|
|||||||
|
|
||||||
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes, blk_last, miner_account,
|
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk_txes, blk_last, miner_account,
|
||||||
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs,
|
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_tx_hashes | test_generator::bf_hf_version | test_generator::bf_max_outs,
|
||||||
8, 8, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
|
10, 10, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
|
||||||
crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 8),
|
crypto::hash(), 0, transaction(), starting_rct_tx_hashes, 0, 6, 10),
|
||||||
false, "Failed to generate block");
|
false, "Failed to generate block");
|
||||||
if (!valid)
|
if (!valid)
|
||||||
DO_CALLBACK(events, "mark_invalid_block");
|
DO_CALLBACK(events, "mark_invalid_block");
|
||||||
@ -210,16 +211,16 @@ bool gen_bp_tx_valid_1::generate(std::vector<test_event_entry>& events) const
|
|||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {1, (size_t)-1};
|
const size_t bp_sizes[] = {1, (size_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
|
return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_1"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_invalid_1_1::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_invalid_1_1::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof , 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
|
||||||
@ -227,8 +228,8 @@ bool gen_bp_tx_valid_2::generate(std::vector<test_event_entry>& events) const
|
|||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {2, (size_t)-1};
|
const size_t bp_sizes[] = {2, (size_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); });
|
return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_2"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const
|
||||||
@ -236,8 +237,8 @@ bool gen_bp_tx_valid_3::generate(std::vector<test_event_entry>& events) const
|
|||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, 5000, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {4, (size_t)-1};
|
const size_t bp_sizes[] = {4, (size_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); });
|
return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_3"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const
|
||||||
@ -245,24 +246,24 @@ bool gen_bp_tx_valid_16::generate(std::vector<test_event_entry>& events) const
|
|||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {16, (size_t)-1};
|
const size_t bp_sizes[] = {16, (size_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof , 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); });
|
return generate_with(events, mixin, 1, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_tx_valid_16"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_invalid_4_2_1::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_invalid_4_2_1::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_invalid_16_16::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_invalid_16_16::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofMultiOutputBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofMultiOutputBulletproof , 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, NULL);
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) const
|
||||||
@ -270,25 +271,25 @@ bool gen_bp_txs_valid_2_and_2::generate(std::vector<test_event_entry>& events) c
|
|||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {1000, 1000, (size_t)-1, 1000, 1000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1000, 1000, (size_t)-1, 1000, 1000, (uint64_t)-1};
|
||||||
const size_t bp_sizes[] = {2, (size_t)-1, 2, (size_t)-1};
|
const size_t bp_sizes[] = {2, (size_t)-1, 2, (size_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof};
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofPaddedBulletproof, 0 }, {rct::RangeProofPaddedBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 2, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); });
|
return generate_with(events, mixin, 2, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx){ return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_2"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_txs_invalid_2_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_txs_invalid_2_and_8_2_and_16_16_1::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = {rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof, rct::RangeProofMultiOutputBulletproof};
|
const rct::RCTConfig rct_config[] = {{rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}, {rct::RangeProofMultiOutputBulletproof, 0}};
|
||||||
return generate_with(events, mixin, 3, amounts_paid, false, range_proof_type, NULL, NULL);
|
return generate_with(events, mixin, 3, amounts_paid, false, rct_config, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_txs_valid_2_and_3_and_2_and_4::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_txs_valid_2_and_3_and_2_and_4::generate(std::vector<test_event_entry>& events) const
|
||||||
{
|
{
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {11111115000, 11111115000, (uint64_t)-1, 11111115000, 11111115000, 11111115001, (uint64_t)-1, 11111115000, 11111115002, (uint64_t)-1, 11111115000, 11111115000, 11111115000, 11111115003, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {11111115000, 11111115000, (uint64_t)-1, 11111115000, 11111115000, 11111115001, (uint64_t)-1, 11111115000, 11111115002, (uint64_t)-1, 11111115000, 11111115000, 11111115000, 11111115003, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof, rct::RangeProofPaddedBulletproof};
|
const rct::RCTConfig rct_config[] = {{rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}, {rct::RangeProofPaddedBulletproof, 0}};
|
||||||
const size_t bp_sizes[] = {2, (size_t)-1, 4, (size_t)-1, 2, (size_t)-1, 4, (size_t)-1};
|
const size_t bp_sizes[] = {2, (size_t)-1, 4, (size_t)-1, 2, (size_t)-1, 4, (size_t)-1};
|
||||||
return generate_with(events, mixin, 4, amounts_paid, true, range_proof_type, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); });
|
return generate_with(events, mixin, 4, amounts_paid, true, rct_config, NULL, [&](const cryptonote::transaction &tx, size_t tx_idx) { return check_bp(tx, tx_idx, bp_sizes, "gen_bp_txs_valid_2_and_3_and_2_and_4"); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>& events) const
|
bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>& events) const
|
||||||
@ -296,9 +297,9 @@ bool gen_bp_tx_invalid_not_enough_proofs::generate(std::vector<test_event_entry>
|
|||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_not_enough_proofs");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_not_enough_proofs");
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
||||||
tx.rct_signatures.p.bulletproofs.pop_back();
|
tx.rct_signatures.p.bulletproofs.pop_back();
|
||||||
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
||||||
@ -311,9 +312,9 @@ bool gen_bp_tx_invalid_empty_proofs::generate(std::vector<test_event_entry>& eve
|
|||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_empty_proofs");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_empty_proofs");
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {50000, 50000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {50000, 50000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
tx.rct_signatures.p.bulletproofs.clear();
|
tx.rct_signatures.p.bulletproofs.clear();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -324,9 +325,9 @@ bool gen_bp_tx_invalid_too_many_proofs::generate(std::vector<test_event_entry>&
|
|||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_too_many_proofs");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_too_many_proofs");
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
||||||
tx.rct_signatures.p.bulletproofs.push_back(tx.rct_signatures.p.bulletproofs.back());
|
tx.rct_signatures.p.bulletproofs.push_back(tx.rct_signatures.p.bulletproofs.back());
|
||||||
return true;
|
return true;
|
||||||
@ -338,9 +339,9 @@ bool gen_bp_tx_invalid_wrong_amount::generate(std::vector<test_event_entry>& eve
|
|||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_wrong_amount");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_wrong_amount");
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {10000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = { rct::RangeProofBulletproof };
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBulletproof, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof || tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
CHECK_TEST_CONDITION(!tx.rct_signatures.p.bulletproofs.empty());
|
||||||
tx.rct_signatures.p.bulletproofs.back() = rct::bulletproof_PROVE(1000, rct::skGen());
|
tx.rct_signatures.p.bulletproofs.back() = rct::bulletproof_PROVE(1000, rct::skGen());
|
||||||
return true;
|
return true;
|
||||||
@ -352,10 +353,8 @@ bool gen_bp_tx_invalid_borromean_type::generate(std::vector<test_event_entry>& e
|
|||||||
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_borromean_type");
|
DEFINE_TESTS_ERROR_CONTEXT("gen_bp_tx_invalid_borromean_type");
|
||||||
const size_t mixin = 10;
|
const size_t mixin = 10;
|
||||||
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
const uint64_t amounts_paid[] = {5000, 5000, (uint64_t)-1};
|
||||||
const rct::RangeProofType range_proof_type[] = {rct::RangeProofPaddedBulletproof};
|
const rct::RCTConfig rct_config[] = { { rct::RangeProofBorromean, 0 } };
|
||||||
return generate_with(events, mixin, 1, amounts_paid, false, range_proof_type, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
|
return generate_with(events, mixin, 1, amounts_paid, false, rct_config, NULL, [&](cryptonote::transaction &tx, size_t tx_idx){
|
||||||
CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeBulletproof);
|
|
||||||
tx.rct_signatures.type = rct::RCTTypeSimple;
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ struct gen_bp_tx_validation_base : public test_chain_unit_base
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool generate_with(std::vector<test_event_entry>& events, size_t mixin,
|
bool generate_with(std::vector<test_event_entry>& events, size_t mixin,
|
||||||
size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RangeProofType *range_proof_type,
|
size_t n_txes, const uint64_t *amounts_paid, bool valid, const rct::RCTConfig *rct_config,
|
||||||
const std::function<bool(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations, size_t)> &pre_tx,
|
const std::function<bool(std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_destination_entry> &destinations, size_t)> &pre_tx,
|
||||||
const std::function<bool(cryptonote::transaction &tx, size_t)> &post_tx) const;
|
const std::function<bool(cryptonote::transaction &tx, size_t)> &post_tx) const;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ private:
|
|||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct get_test_options<gen_bp_tx_validation_base> {
|
struct get_test_options<gen_bp_tx_validation_base> {
|
||||||
const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(8, 73), std::make_pair(0, 0)};
|
const std::pair<uint8_t, uint64_t> hard_forks[4] = {std::make_pair(1, 0), std::make_pair(2, 1), std::make_pair(10, 73), std::make_pair(0, 0)};
|
||||||
const cryptonote::test_options test_options = {
|
const cryptonote::test_options test_options = {
|
||||||
hard_forks
|
hard_forks
|
||||||
};
|
};
|
||||||
|
@ -365,7 +365,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
|
|||||||
#endif
|
#endif
|
||||||
std::vector<crypto::secret_key> additional_tx_secret_keys;
|
std::vector<crypto::secret_key> additional_tx_secret_keys;
|
||||||
auto sources_copy = sources;
|
auto sources_copy = sources;
|
||||||
r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, rct::RangeProofBorromean, msoutp);
|
r = construct_tx_and_get_tx_key(miner_account[creator].get_keys(), subaddresses, sources, destinations, boost::none, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_secret_keys, true, { rct::RangeProofBorromean, 0 }, msoutp);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
|
||||||
|
|
||||||
#ifndef NO_MULTISIG
|
#ifndef NO_MULTISIG
|
||||||
@ -455,7 +455,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
|
|||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
crypto::derivation_to_scalar(derivation, n, scalar1);
|
crypto::derivation_to_scalar(derivation, n, scalar1);
|
||||||
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
||||||
rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1));
|
rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
rct::key C = tx.rct_signatures.outPk[n].mask;
|
rct::key C = tx.rct_signatures.outPk[n].mask;
|
||||||
rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H);
|
rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H);
|
||||||
CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount");
|
CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount");
|
||||||
|
@ -133,7 +133,8 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
|
|||||||
CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
|
CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation");
|
||||||
crypto::secret_key amount_key;
|
crypto::secret_key amount_key;
|
||||||
crypto::derivation_to_scalar(derivation, o, amount_key);
|
crypto::derivation_to_scalar(derivation, o, amount_key);
|
||||||
if (rct_txes[n].rct_signatures.type == rct::RCTTypeSimple || rct_txes[n].rct_signatures.type == rct::RCTTypeBulletproof)
|
const uint8_t type = rct_txes[n].rct_signatures.type;
|
||||||
|
if (type == rct::RCTTypeSimple || type == rct::RCTTypeBulletproof || type == rct::RCTTypeBulletproof2)
|
||||||
rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
|
rct::decodeRctSimple(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
|
||||||
else
|
else
|
||||||
rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
|
rct::decodeRct(rct_txes[n].rct_signatures, rct::sk2rct(amount_key), o, rct_tx_masks[o+n*4], hw::get_device("default"));
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#include "multi_tx_test_base.h"
|
#include "multi_tx_test_base.h"
|
||||||
|
|
||||||
template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
|
template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2>
|
||||||
class test_check_tx_signature : private multi_tx_test_base<a_ring_size>
|
class test_check_tx_signature : private multi_tx_test_base<a_ring_size>
|
||||||
{
|
{
|
||||||
static_assert(0 < a_ring_size, "ring_size must be greater than 0");
|
static_assert(0 < a_ring_size, "ring_size must be greater than 0");
|
||||||
@ -71,7 +71,8 @@ public:
|
|||||||
std::vector<crypto::secret_key> additional_tx_keys;
|
std::vector<crypto::secret_key> additional_tx_keys;
|
||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||||
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type))
|
rct::RCTConfig rct_config{range_proof_type, bp_version};
|
||||||
|
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
get_transaction_prefix_hash(m_tx, m_tx_prefix_hash);
|
get_transaction_prefix_hash(m_tx, m_tx_prefix_hash);
|
||||||
@ -135,7 +136,7 @@ public:
|
|||||||
m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0));
|
m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0));
|
||||||
for (size_t n = 0; n < a_num_txes; ++n)
|
for (size_t n = 0; n < a_num_txes; ++n)
|
||||||
{
|
{
|
||||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, rct::RangeProofPaddedBulletproof))
|
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2}))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ public:
|
|||||||
for (size_t n = 1; n < extra_outs; ++n)
|
for (size_t n = 1; n < extra_outs; ++n)
|
||||||
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
|
destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
|
||||||
|
|
||||||
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, rct::RangeProofMultiOutputBulletproof))
|
if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2}))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "multi_tx_test_base.h"
|
#include "multi_tx_test_base.h"
|
||||||
|
|
||||||
template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
|
template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean, int bp_version = 2>
|
||||||
class test_construct_tx : private multi_tx_test_base<a_in_count>
|
class test_construct_tx : private multi_tx_test_base<a_in_count>
|
||||||
{
|
{
|
||||||
static_assert(0 < a_in_count, "in_count must be greater than 0");
|
static_assert(0 < a_in_count, "in_count must be greater than 0");
|
||||||
@ -73,7 +73,8 @@ public:
|
|||||||
std::vector<crypto::secret_key> additional_tx_keys;
|
std::vector<crypto::secret_key> additional_tx_keys;
|
||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||||
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
|
||||||
return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type);
|
rct::RCTConfig rct_config{range_proof_type, bp_version};
|
||||||
|
return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -134,17 +134,17 @@ int main(int argc, char** argv)
|
|||||||
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, true);
|
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, true);
|
||||||
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, true);
|
TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, true);
|
||||||
|
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
|
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
|
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
|
|
||||||
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 1, 2, false);
|
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 1, 2, false);
|
||||||
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 2, false);
|
TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 2, false);
|
||||||
@ -157,14 +157,14 @@ int main(int argc, char** argv)
|
|||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofBorromean);
|
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofBorromean);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofBorromean);
|
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofBorromean);
|
||||||
|
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof, 2);
|
||||||
TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof);
|
TEST_PERFORMANCE5(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof, 2);
|
||||||
|
|
||||||
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 64);
|
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 64);
|
||||||
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 64);
|
TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 64);
|
||||||
|
@ -131,7 +131,8 @@ TEST(bulletproofs, multi_splitting)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rct::ctkeyV outSk;
|
rct::ctkeyV outSk;
|
||||||
rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct::RangeProofPaddedBulletproof, hw::get_device("default"));
|
rct::RCTConfig rct_config { rct::RangeProofPaddedBulletproof, 0 };
|
||||||
|
rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, inamounts, outamounts, available, mixRing, amount_keys, NULL, NULL, index, outSk, rct_config, hw::get_device("default"));
|
||||||
ASSERT_TRUE(rct::verRctSimple(s));
|
ASSERT_TRUE(rct::verRctSimple(s));
|
||||||
for (size_t i = 0; i < n_outputs; ++i)
|
for (size_t i = 0; i < n_outputs; ++i)
|
||||||
{
|
{
|
||||||
|
@ -114,18 +114,17 @@ TEST(device, ops)
|
|||||||
ASSERT_EQ(ki0, ki1);
|
ASSERT_EQ(ki0, ki1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(device, ecdh)
|
TEST(device, ecdh32)
|
||||||
{
|
{
|
||||||
hw::core::device_default dev;
|
hw::core::device_default dev;
|
||||||
rct::ecdhTuple tuple, tuple2;
|
rct::ecdhTuple tuple, tuple2;
|
||||||
rct::key key = rct::skGen();
|
rct::key key = rct::skGen();
|
||||||
tuple.mask = rct::skGen();
|
tuple.mask = rct::skGen();
|
||||||
tuple.amount = rct::skGen();
|
tuple.amount = rct::skGen();
|
||||||
tuple.senderPk = rct::pkGen();
|
|
||||||
tuple2 = tuple;
|
tuple2 = tuple;
|
||||||
dev.ecdhEncode(tuple, key);
|
dev.ecdhEncode(tuple, key, false);
|
||||||
dev.ecdhDecode(tuple, key);
|
dev.ecdhDecode(tuple, key, false);
|
||||||
ASSERT_EQ(tuple2.mask, tuple.mask);
|
ASSERT_EQ(tuple2.mask, tuple.mask);
|
||||||
ASSERT_EQ(tuple2.amount, tuple.amount);
|
ASSERT_EQ(tuple2.amount, tuple.amount);
|
||||||
ASSERT_EQ(tuple2.senderPk, tuple.senderPk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ namespace
|
|||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||||
subaddresses[from.m_account_address.m_spend_public_key] = {0,0};
|
subaddresses[from.m_account_address.m_spend_public_key] = {0,0};
|
||||||
|
|
||||||
if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean))
|
if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 }))
|
||||||
throw std::runtime_error{"transaction construction error"};
|
throw std::runtime_error{"transaction construction error"};
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
|
@ -171,8 +171,10 @@ TEST(ringct, range_proofs)
|
|||||||
skpkGen(Sk, Pk);
|
skpkGen(Sk, Pk);
|
||||||
destinations.push_back(Pk);
|
destinations.push_back(Pk);
|
||||||
|
|
||||||
|
const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
|
||||||
|
|
||||||
//compute rct data with mixin 500
|
//compute rct data with mixin 500
|
||||||
rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
//verify rct data
|
//verify rct data
|
||||||
ASSERT_TRUE(verRct(s));
|
ASSERT_TRUE(verRct(s));
|
||||||
@ -189,7 +191,7 @@ TEST(ringct, range_proofs)
|
|||||||
|
|
||||||
|
|
||||||
//compute rct data with mixin 500
|
//compute rct data with mixin 500
|
||||||
s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
//verify rct data
|
//verify rct data
|
||||||
ASSERT_FALSE(verRct(s));
|
ASSERT_FALSE(verRct(s));
|
||||||
@ -235,8 +237,10 @@ TEST(ringct, range_proofs_with_fee)
|
|||||||
skpkGen(Sk, Pk);
|
skpkGen(Sk, Pk);
|
||||||
destinations.push_back(Pk);
|
destinations.push_back(Pk);
|
||||||
|
|
||||||
|
const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
|
||||||
|
|
||||||
//compute rct data with mixin 500
|
//compute rct data with mixin 500
|
||||||
rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
rctSig s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
//verify rct data
|
//verify rct data
|
||||||
ASSERT_TRUE(verRct(s));
|
ASSERT_TRUE(verRct(s));
|
||||||
@ -253,7 +257,7 @@ TEST(ringct, range_proofs_with_fee)
|
|||||||
|
|
||||||
|
|
||||||
//compute rct data with mixin 500
|
//compute rct data with mixin 500
|
||||||
s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
s = genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
//verify rct data
|
//verify rct data
|
||||||
ASSERT_FALSE(verRct(s));
|
ASSERT_FALSE(verRct(s));
|
||||||
@ -311,7 +315,8 @@ TEST(ringct, simple)
|
|||||||
//compute sig with mixin 2
|
//compute sig with mixin 2
|
||||||
xmr_amount txnfee = 1;
|
xmr_amount txnfee = 1;
|
||||||
|
|
||||||
rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, hw::get_device("default"));
|
const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
|
||||||
|
rctSig s = genRctSimple(message, sc, pc, destinations,inamounts, outamounts, amount_keys, NULL, NULL, txnfee, 2, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
//verify ring ct signature
|
//verify ring ct signature
|
||||||
ASSERT_TRUE(verRctSimple(s));
|
ASSERT_TRUE(verRctSimple(s));
|
||||||
@ -345,7 +350,8 @@ static rct::rctSig make_sample_rct_sig(int n_inputs, const uint64_t input_amount
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
|
||||||
|
return genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input_amounts[], int n_outputs, const uint64_t output_amounts[], uint64_t fee)
|
static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input_amounts[], int n_outputs, const uint64_t output_amounts[], uint64_t fee)
|
||||||
@ -371,7 +377,8 @@ static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input
|
|||||||
destinations.push_back(Pk);
|
destinations.push_back(Pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, hw::get_device("default"));
|
const rct::RCTConfig rct_config { RangeProofBorromean, 0 };
|
||||||
|
return genRctSimple(rct::zero(), sc, pc, destinations, inamounts, outamounts, amount_keys, NULL, NULL, fee, 3, rct_config, hw::get_device("default"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool range_proof_test(bool expected_valid,
|
static bool range_proof_test(bool expected_valid,
|
||||||
@ -824,27 +831,6 @@ TEST(ringct, HPow2)
|
|||||||
|
|
||||||
static const xmr_amount test_amounts[]={0, 1, 2, 3, 4, 5, 10000, 10000000000000000000ull, 10203040506070809000ull, 123456789123456789};
|
static const xmr_amount test_amounts[]={0, 1, 2, 3, 4, 5, 10000, 10000000000000000000ull, 10203040506070809000ull, 123456789123456789};
|
||||||
|
|
||||||
TEST(ringct, ecdh_roundtrip)
|
|
||||||
{
|
|
||||||
key k;
|
|
||||||
ecdhTuple t0, t1;
|
|
||||||
|
|
||||||
for (auto amount: test_amounts) {
|
|
||||||
skGen(k);
|
|
||||||
|
|
||||||
t0.mask = skGen();
|
|
||||||
t0.amount = d2h(amount);
|
|
||||||
|
|
||||||
t1 = t0;
|
|
||||||
ecdhEncode(t1, k);
|
|
||||||
ecdhDecode(t1, k);
|
|
||||||
ASSERT_TRUE(t0.mask == t1.mask);
|
|
||||||
ASSERT_TRUE(equalKeys(t0.mask, t1.mask));
|
|
||||||
ASSERT_TRUE(t0.amount == t1.amount);
|
|
||||||
ASSERT_TRUE(equalKeys(t0.amount, t1.amount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ringct, d2h)
|
TEST(ringct, d2h)
|
||||||
{
|
{
|
||||||
key k, P1;
|
key k, P1;
|
||||||
|
@ -550,12 +550,10 @@ TEST(Serialization, serializes_ringct_types)
|
|||||||
|
|
||||||
ecdh0.mask = rct::skGen();
|
ecdh0.mask = rct::skGen();
|
||||||
ecdh0.amount = rct::skGen();
|
ecdh0.amount = rct::skGen();
|
||||||
ecdh0.senderPk = rct::skGen();
|
|
||||||
ASSERT_TRUE(serialization::dump_binary(ecdh0, blob));
|
ASSERT_TRUE(serialization::dump_binary(ecdh0, blob));
|
||||||
ASSERT_TRUE(serialization::parse_binary(blob, ecdh1));
|
ASSERT_TRUE(serialization::parse_binary(blob, ecdh1));
|
||||||
ASSERT_TRUE(!memcmp(&ecdh0.mask, &ecdh1.mask, sizeof(ecdh0.mask)));
|
ASSERT_TRUE(!memcmp(&ecdh0.mask, &ecdh1.mask, sizeof(ecdh0.mask)));
|
||||||
ASSERT_TRUE(!memcmp(&ecdh0.amount, &ecdh1.amount, sizeof(ecdh0.amount)));
|
ASSERT_TRUE(!memcmp(&ecdh0.amount, &ecdh1.amount, sizeof(ecdh0.amount)));
|
||||||
// senderPk is not serialized
|
|
||||||
|
|
||||||
for (size_t n = 0; n < 64; ++n)
|
for (size_t n = 0; n < 64; ++n)
|
||||||
{
|
{
|
||||||
@ -591,7 +589,8 @@ TEST(Serialization, serializes_ringct_types)
|
|||||||
rct::skpkGen(Sk, Pk);
|
rct::skpkGen(Sk, Pk);
|
||||||
destinations.push_back(Pk);
|
destinations.push_back(Pk);
|
||||||
//compute rct data with mixin 500
|
//compute rct data with mixin 500
|
||||||
s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, hw::get_device("default"));
|
const rct::RCTConfig rct_config{ rct::RangeProofPaddedBulletproof, 0 };
|
||||||
|
s0 = rct::genRct(rct::zero(), sc, pc, destinations, amounts, amount_keys, NULL, NULL, 3, rct_config, hw::get_device("default"));
|
||||||
|
|
||||||
mg0 = s0.p.MGs[0];
|
mg0 = s0.p.MGs[0];
|
||||||
ASSERT_TRUE(serialization::dump_binary(mg0, blob));
|
ASSERT_TRUE(serialization::dump_binary(mg0, blob));
|
||||||
|
Loading…
Reference in New Issue
Block a user