mirror of
https://github.com/monero-project/monero.git
synced 2025-07-31 04:38:42 -04:00
add a bulletproof version, new bulletproof type, and rct config
This makes it easier to modify the bulletproof format
This commit is contained in:
parent
4e72384318
commit
f931e16c6e
24 changed files with 184 additions and 140 deletions
|
@ -416,7 +416,7 @@ namespace rct {
|
|||
hashes.push_back(hash2rct(h));
|
||||
|
||||
keyV kv;
|
||||
if (rv.type == RCTTypeBulletproof)
|
||||
if (rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2)
|
||||
{
|
||||
kv.reserve((6*2+9) * rv.p.bulletproofs.size());
|
||||
for (const auto &p: rv.p.bulletproofs)
|
||||
|
@ -686,7 +686,7 @@ namespace rct {
|
|||
// 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
|
||||
// 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(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations");
|
||||
CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing");
|
||||
|
@ -737,18 +737,18 @@ namespace rct {
|
|||
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;
|
||||
ctkeyM mixRing;
|
||||
ctkeyV outSk;
|
||||
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
|
||||
//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) {
|
||||
const bool bulletproof = range_proof_type != RangeProofBorromean;
|
||||
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 = rct_config.range_proof_type != RangeProofBorromean;
|
||||
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(outamounts.size() == destinations.size(), "Different number of amounts/destinations");
|
||||
|
@ -764,7 +764,7 @@ namespace rct {
|
|||
}
|
||||
|
||||
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.outPk.resize(destinations.size());
|
||||
if (!bulletproof)
|
||||
|
@ -793,7 +793,7 @@ namespace rct {
|
|||
std::vector<uint64_t> proof_amounts;
|
||||
size_t n_amounts = outamounts.size();
|
||||
size_t amounts_proved = 0;
|
||||
if (range_proof_type == RangeProofPaddedBulletproof)
|
||||
if (rct_config.range_proof_type == RangeProofPaddedBulletproof)
|
||||
{
|
||||
rct::keyV C, masks;
|
||||
if (hwdev.get_mode() == hw::device::TRANSACTION_CREATE_FAKE)
|
||||
|
@ -817,7 +817,7 @@ namespace rct {
|
|||
else while (amounts_proved < n_amounts)
|
||||
{
|
||||
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)
|
||||
batch_size *= 2;
|
||||
rct::keyV C, masks;
|
||||
|
@ -884,7 +884,7 @@ namespace rct {
|
|||
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;
|
||||
index.resize(inPk.size());
|
||||
ctkeyM mixRing;
|
||||
|
@ -894,7 +894,7 @@ namespace rct {
|
|||
mixRing[i].resize(mixin+1);
|
||||
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
|
||||
|
@ -984,7 +984,8 @@ namespace rct {
|
|||
{
|
||||
CHECK_AND_ASSERT_MES(rvp, false, "rctSig pointer is NULL");
|
||||
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);
|
||||
if (bulletproof)
|
||||
{
|
||||
|
@ -1083,7 +1084,8 @@ namespace rct {
|
|||
{
|
||||
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);
|
||||
// semantics check is early, and mixRing/MGs aren't resolved yet
|
||||
if (bulletproof)
|
||||
|
@ -1173,7 +1175,7 @@ namespace rct {
|
|||
}
|
||||
|
||||
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(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
|
||||
|
||||
|
@ -1203,7 +1205,7 @@ namespace rct {
|
|||
}
|
||||
|
||||
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");
|
||||
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");
|
||||
|
|
|
@ -119,10 +119,10 @@ namespace rct {
|
|||
//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
|
||||
// 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 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 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 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 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, 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, 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, const RCTConfig &rct_config, hw::device &hwdev);
|
||||
bool verRct(const rctSig & rv, bool semantics);
|
||||
static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); }
|
||||
bool verRctSemanticsSimple(const rctSig & rv);
|
||||
|
|
|
@ -217,6 +217,7 @@ namespace rct {
|
|||
{
|
||||
case RCTTypeSimple:
|
||||
case RCTTypeBulletproof:
|
||||
case RCTTypeBulletproof2:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -228,6 +229,7 @@ namespace rct {
|
|||
switch (type)
|
||||
{
|
||||
case RCTTypeBulletproof:
|
||||
case RCTTypeBulletproof2:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -231,8 +231,13 @@ namespace rct {
|
|||
RCTTypeFull = 1,
|
||||
RCTTypeSimple = 2,
|
||||
RCTTypeBulletproof = 3,
|
||||
RCTTypeBulletproof2 = 4,
|
||||
};
|
||||
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
||||
struct RCTConfig {
|
||||
RangeProofType range_proof_type;
|
||||
int bp_version;
|
||||
};
|
||||
struct rctSigBase {
|
||||
uint8_t type;
|
||||
key message;
|
||||
|
@ -249,7 +254,7 @@ namespace rct {
|
|||
FIELD(type)
|
||||
if (type == RCTTypeNull)
|
||||
return true;
|
||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof)
|
||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2)
|
||||
return false;
|
||||
VARINT_FIELD(txnFee)
|
||||
// inputs/outputs not saved, only here for serialization help
|
||||
|
@ -310,9 +315,9 @@ namespace rct {
|
|||
{
|
||||
if (type == RCTTypeNull)
|
||||
return true;
|
||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof)
|
||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2)
|
||||
return false;
|
||||
if (type == RCTTypeBulletproof)
|
||||
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2)
|
||||
{
|
||||
uint32_t nbp = bulletproofs.size();
|
||||
FIELD(nbp)
|
||||
|
@ -351,7 +356,7 @@ namespace rct {
|
|||
ar.begin_array();
|
||||
// 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
|
||||
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);
|
||||
if (MGs.size() != mg_elements)
|
||||
return false;
|
||||
|
@ -369,7 +374,7 @@ namespace rct {
|
|||
for (size_t j = 0; j < mixin + 1; ++j)
|
||||
{
|
||||
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]);
|
||||
if (MGs[i].ss[j].size() != mg_ss2_elements)
|
||||
return false;
|
||||
|
@ -395,7 +400,7 @@ namespace rct {
|
|||
ar.delimit_array();
|
||||
}
|
||||
ar.end_array();
|
||||
if (type == RCTTypeBulletproof)
|
||||
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2)
|
||||
{
|
||||
ar.tag("pseudoOuts");
|
||||
ar.begin_array();
|
||||
|
@ -419,12 +424,12 @@ namespace rct {
|
|||
|
||||
keyV& get_pseudo_outs()
|
||||
{
|
||||
return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts;
|
||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
||||
}
|
||||
|
||||
keyV const& get_pseudo_outs() const
|
||||
{
|
||||
return type == RCTTypeBulletproof ? p.pseudoOuts : pseudoOuts;
|
||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue