diff options
Diffstat (limited to 'src/ringct')
-rw-r--r-- | src/ringct/rctOps.cpp | 20 | ||||
-rw-r--r-- | src/ringct/rctOps.h | 2 | ||||
-rw-r--r-- | src/ringct/rctSigs.cpp | 40 | ||||
-rw-r--r-- | src/ringct/rctSigs.h | 12 | ||||
-rw-r--r-- | src/ringct/rctTypes.h | 2 |
5 files changed, 52 insertions, 24 deletions
diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index 06267fd8e..b8a0d26ad 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -741,22 +741,28 @@ void fe_mul(fe h,const fe f,const fe g) //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH + void ecdhEncodeFromSharedSecret(ecdhTuple & unmasked, const key & sharedSec1) { + key sharedSec2 = hash_to_scalar(sharedSec1); + //encode + sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes); + sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); + } void ecdhEncode(ecdhTuple & unmasked, const key & receiverPk) { key esk; //compute shared secret skpkGen(esk, unmasked.senderPk); key sharedSec1 = hash_to_scalar(scalarmultKey(receiverPk, esk)); + ecdhEncodeFromSharedSecret(unmasked, sharedSec1); + } + void ecdhDecodeFromSharedSecret(ecdhTuple & masked, const key & sharedSec1) { key sharedSec2 = hash_to_scalar(sharedSec1); - //encode - sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes); - sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); + //decode + sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); + sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); } void ecdhDecode(ecdhTuple & masked, const key & receiverSk) { //compute shared secret key sharedSec1 = hash_to_scalar(scalarmultKey(masked.senderPk, receiverSk)); - key sharedSec2 = hash_to_scalar(sharedSec1); - //encode - sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); - sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); + ecdhDecodeFromSharedSecret(masked, sharedSec1); } } diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index 6438a1f03..225c5abb9 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -165,7 +165,9 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH + void ecdhEncodeFromSharedSecret(ecdhTuple & unmasked, const key & sharedSec1); void ecdhEncode(ecdhTuple & unmasked, const key & receiverPk); + void ecdhDecodeFromSharedSecret(ecdhTuple & masked, const key & sharedSec1); void ecdhDecode(ecdhTuple & masked, const key & receiverSk); } #endif /* RCTOPS_H */ 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); diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 2064962c3..d150e7180 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -135,18 +135,20 @@ 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 - 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 ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> & amounts, const 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, xmr_amount txnFee, unsigned int mixin); - 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 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); + 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); + 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); + 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); bool verRct(const rctSig & rv); bool verRct(const rctSig & rv, const ctkeyM &mixRing, const keyV &II, const ctkeyV &outPk, const key &message); bool verRctSimple(const rctSig & rv); bool verRctSimple(const rctSig & rv, const ctkeyM &mixRing, const std::vector<keyV> *II, const ctkeyV &outPk, const key &message); xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask); + xmr_amount decodeRctFromSharedSecret(const rctSig & rv, const key & sk, unsigned int i, key & mask); xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i); - xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i); + xmr_amount decodeRctSimpleFromSharedSecret(const rctSig & rv, const key & sk, unsigned int i, key & mask); xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key & mask); + xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i); } #endif /* RCTSIGS_H */ diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 7e31f679d..d36d3f1b1 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -341,6 +341,8 @@ namespace rct { namespace cryptonote { static inline bool operator==(const crypto::public_key &k0, const rct::key &k1) { return !memcmp(&k0, &k1, 32); } static inline bool operator!=(const crypto::public_key &k0, const rct::key &k1) { return memcmp(&k0, &k1, 32); } + static inline bool operator==(const crypto::secret_key &k0, const rct::key &k1) { return !memcmp(&k0, &k1, 32); } + static inline bool operator!=(const crypto::secret_key &k0, const rct::key &k1) { return memcmp(&k0, &k1, 32); } } template<typename T> std::ostream &print256(std::ostream &o, const T &v); |