mirror of
https://github.com/monero-project/monero.git
synced 2026-01-17 07:12:01 -08:00
rct: make the amount key derivable by a third party with the tx key
Scheme design from luigi1114.
This commit is contained in:
@@ -535,7 +535,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, unsigned int index, ctkeyV &outSk) {
|
||||
rctSig genRct(const key &message, const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> & amounts, const ctkeyM &mixRing, const keyV &amount_keys, unsigned int index, ctkeyV &outSk) {
|
||||
CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size() || amounts.size() == destinations.size() + 1, "Different number of amounts/destinations");
|
||||
CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing");
|
||||
for (size_t n = 0; n < mixRing.size(); ++n) {
|
||||
@@ -563,7 +563,7 @@ namespace rct {
|
||||
//mask amount and mask
|
||||
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
||||
rv.ecdhInfo[i].amount = d2h(amounts[i]);
|
||||
ecdhEncode(rv.ecdhInfo[i], destinations[i]);
|
||||
ecdhEncodeFromSharedSecret(rv.ecdhInfo[i], amount_keys[i]);
|
||||
|
||||
}
|
||||
|
||||
@@ -584,17 +584,17 @@ namespace rct {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const int mixin) {
|
||||
rctSig genRct(const key &message, const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const keyV &amount_keys, const int mixin) {
|
||||
unsigned int index;
|
||||
ctkeyM mixRing;
|
||||
ctkeyV outSk;
|
||||
tie(mixRing, index) = populateFromBlockchain(inPk, mixin);
|
||||
return genRct(message, inSk, destinations, amounts, mixRing, index, outSk);
|
||||
return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, index, outSk);
|
||||
}
|
||||
|
||||
//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 std::vector<unsigned int> & index, ctkeyV &outSk) {
|
||||
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<unsigned int> & index, ctkeyV &outSk) {
|
||||
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");
|
||||
@@ -630,7 +630,7 @@ namespace rct {
|
||||
//mask amount and mask
|
||||
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
|
||||
rv.ecdhInfo[i].amount = d2h(outamounts[i]);
|
||||
ecdhEncode(rv.ecdhInfo[i], destinations[i]);
|
||||
ecdhEncodeFromSharedSecret(rv.ecdhInfo[i], amount_keys[i]);
|
||||
}
|
||||
|
||||
//set txn fee
|
||||
@@ -656,7 +656,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, xmr_amount txnFee, unsigned int mixin) {
|
||||
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, xmr_amount txnFee, unsigned int mixin) {
|
||||
std::vector<unsigned int> index;
|
||||
index.resize(inPk.size());
|
||||
ctkeyM mixRing;
|
||||
@@ -666,7 +666,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, index, outSk);
|
||||
return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk);
|
||||
}
|
||||
|
||||
//RingCT protocol
|
||||
@@ -782,7 +782,7 @@ namespace rct {
|
||||
//decodeRct: (c.f. http://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
|
||||
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask) {
|
||||
static xmr_amount decodeRctMain(const rctSig & rv, const key & sk, unsigned int i, key & mask, void (*decode)(ecdhTuple&, const key&)) {
|
||||
CHECK_AND_ASSERT_MES(!rv.simple, false, "decodeRct called on simple rctSig");
|
||||
CHECK_AND_ASSERT_THROW_MES(rv.rangeSigs.size() > 0, "Empty rv.rangeSigs");
|
||||
CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.rangeSigs.size(), "Mismatched sizes of rv.outPk and rv.rangeSigs");
|
||||
@@ -790,7 +790,7 @@ namespace rct {
|
||||
|
||||
//mask amount and mask
|
||||
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
||||
ecdhDecode(ecdh_info, sk);
|
||||
(*decode)(ecdh_info, sk);
|
||||
mask = ecdh_info.mask;
|
||||
key amount = ecdh_info.amount;
|
||||
key C = rv.outPk[i].mask;
|
||||
@@ -806,12 +806,20 @@ namespace rct {
|
||||
return h2d(amount);
|
||||
}
|
||||
|
||||
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask) {
|
||||
return decodeRctMain(rv, sk, i, mask, &ecdhDecode);
|
||||
}
|
||||
|
||||
xmr_amount decodeRctFromSharedSecret(const rctSig & rv, const key & sk, unsigned int i, key & mask) {
|
||||
return decodeRctMain(rv, sk, i, mask, &ecdhDecodeFromSharedSecret);
|
||||
}
|
||||
|
||||
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i) {
|
||||
key mask;
|
||||
return decodeRct(rv, sk, i, mask);
|
||||
}
|
||||
|
||||
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask) {
|
||||
static xmr_amount decodeRctSimpleMain(const rctSig & rv, const key & sk, unsigned int i, key &mask, void (*decode)(ecdhTuple &ecdh, const key&)) {
|
||||
CHECK_AND_ASSERT_MES(rv.simple, false, "decodeRct called on non simple rctSig");
|
||||
CHECK_AND_ASSERT_THROW_MES(rv.rangeSigs.size() > 0, "Empty rv.rangeSigs");
|
||||
CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.rangeSigs.size(), "Mismatched sizes of rv.outPk and rv.rangeSigs");
|
||||
@@ -819,7 +827,7 @@ namespace rct {
|
||||
|
||||
//mask amount and mask
|
||||
ecdhTuple ecdh_info = rv.ecdhInfo[i];
|
||||
ecdhDecode(ecdh_info, sk);
|
||||
(*decode)(ecdh_info, sk);
|
||||
mask = ecdh_info.mask;
|
||||
key amount = ecdh_info.amount;
|
||||
key C = rv.outPk[i].mask;
|
||||
@@ -835,6 +843,14 @@ namespace rct {
|
||||
return h2d(amount);
|
||||
}
|
||||
|
||||
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask) {
|
||||
return decodeRctSimpleMain(rv, sk, i, mask, &ecdhDecode);
|
||||
}
|
||||
|
||||
xmr_amount decodeRctSimpleFromSharedSecret(const rctSig & rv, const key & sk, unsigned int i, key &mask) {
|
||||
return decodeRctSimpleMain(rv, sk, i, mask, &ecdhDecodeFromSharedSecret);
|
||||
}
|
||||
|
||||
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i) {
|
||||
key mask;
|
||||
return decodeRctSimple(rv, sk, i, mask);
|
||||
|
||||
Reference in New Issue
Block a user