diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2016-07-24 17:53:34 +0100 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2016-08-28 21:29:46 +0100 |
commit | 9b70856ccb97943249f6e76b19f8abce5cd7aabe (patch) | |
tree | e4717e7723dfc3aab14e3fdc85d9294efbd4b1eb /src/ringct/rctSigs.cpp | |
parent | rct: do not serialize public keys in outPk (diff) | |
download | monero-9b70856ccb97943249f6e76b19f8abce5cd7aabe.tar.xz |
rct: make the amount key derivable by a third party with the tx key
Scheme design from luigi1114.
Diffstat (limited to 'src/ringct/rctSigs.cpp')
-rw-r--r-- | src/ringct/rctSigs.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index fa9c833dd..0d4fbee1a 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -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); |