diff options
Diffstat (limited to 'src/ringct')
-rw-r--r-- | src/ringct/rctSigs.cpp | 36 | ||||
-rw-r--r-- | src/ringct/rctSigs.h | 11 | ||||
-rw-r--r-- | src/ringct/rctTypes.h | 17 |
3 files changed, 43 insertions, 21 deletions
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 89adb2a77..917ac54cd 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -226,7 +226,7 @@ namespace rct { // Gen creates a signature which proves that for some column in the keymatrix "pk" // the signer knows a secret key for each row in that column // Ver verifies that the MG sig was created correctly - bool MLSAG_Ver(key message, const keyM & pk, const mgSig & rv) { + bool MLSAG_Ver(key message, const keyM & pk, const mgSig & rv, const keyV &II) { size_t cols = pk.size(); CHECK_AND_ASSERT_MES(cols >= 2, false, "Error! What is c if cols = 1!"); @@ -235,7 +235,7 @@ namespace rct { for (size_t i = 1; i < cols; ++i) { CHECK_AND_ASSERT_MES(pk[i].size() == rows, false, "pk is not rectangular"); } - CHECK_AND_ASSERT_MES(rv.II.size() == rows, false, "Bad rv.II size"); + CHECK_AND_ASSERT_MES(II.size() == rows, false, "Bad II size"); CHECK_AND_ASSERT_MES(rv.ss.size() == cols, false, "Bad rv.ss size"); for (size_t i = 0; i < cols; ++i) { CHECK_AND_ASSERT_MES(rv.ss[i].size() == rows, false, "rv.ss is not rectangular"); @@ -246,7 +246,7 @@ namespace rct { key c_old = copy(rv.cc); vector<geDsmp> Ip(rows); for (i= 0 ; i< rows ; i++) { - precomp(Ip[i].k, rv.II[i]); + precomp(Ip[i].k, II[i]); } unsigned char m2[128]; memcpy(m2, message.bytes, 32); @@ -334,7 +334,7 @@ namespace rct { // this shows that sum inputs = sum outputs //Ver: // verifies the above sig is created corretly - mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const ctkeyV &outSk, const ctkeyV & outPk, unsigned int index, key txnFeeKey) { + mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const ctkeyV &outSk, const ctkeyV & outPk, unsigned int index, key txnFeeKey, const key &base_hash) { mgSig mg; //setup vars size_t cols = pubs.size(); @@ -378,7 +378,9 @@ namespace rct { for (size_t j = 0; j < outPk.size(); j++) { sc_sub(sk[rows].bytes, sk[rows].bytes, outSk[j].mask.bytes); //subtract output masks in last row.. } - key message = cn_fast_hash(outPk); + ctkeyV signed_data = outPk; + signed_data.push_back(ctkey({base_hash, identity()})); + key message = cn_fast_hash(signed_data); return MLSAG_Gen(message, M, sk, index); } @@ -391,7 +393,7 @@ namespace rct { // this shows that sum inputs = sum outputs //Ver: // verifies the above sig is created corretly - bool verRctMG(mgSig mg, const ctkeyM & pubs, const ctkeyV & outPk, key txnFeeKey) { + bool verRctMG(mgSig mg, const keyV &II, const ctkeyM & pubs, const ctkeyV & outPk, key txnFeeKey, const key &base_hash) { //setup vars size_t cols = pubs.size(); CHECK_AND_ASSERT_MES(cols >= 1, false, "Empty pubs"); @@ -422,10 +424,12 @@ namespace rct { //subtract txn fee output in last row subKeys(M[i][rows], M[i][rows], txnFeeKey); } - key message = cn_fast_hash(outPk); + ctkeyV signed_data = outPk; + signed_data.push_back(ctkey({base_hash, identity()})); + key message = cn_fast_hash(signed_data); DP("message:"); DP(message); - return MLSAG_Ver(message, M, mg); + return MLSAG_Ver(message, M, mg, II); } //These functions get keys from blockchain @@ -470,7 +474,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 ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> amounts, const ctkeyM &mixRing, unsigned int index) { + rctSig genRct(const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> amounts, const ctkeyM &mixRing, const key &base_hash, unsigned int index) { 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) { @@ -513,15 +517,16 @@ namespace rct { key txnFeeKey = scalarmultH(d2h(rv.txnFee)); rv.mixRing = mixRing; - rv.MG = proveRctMG(rv.mixRing, inSk, outSk, rv.outPk, index, txnFeeKey); + rv.base_hash = base_hash; + rv.MG = proveRctMG(rv.mixRing, inSk, outSk, rv.outPk, index, txnFeeKey, base_hash); return rv; } - rctSig genRct(const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const int mixin) { + rctSig genRct(const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const key &base_hash, const int mixin) { unsigned int index; ctkeyM mixRing; tie(mixRing, index) = populateFromBlockchain(inPk, mixin); - return genRct(inSk, destinations, amounts, mixRing, index); + return genRct(inSk, destinations, amounts, mixRing, base_hash, index); } //RingCT protocol @@ -534,7 +539,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 - bool verRct(const rctSig & rv) { + bool verRct(const rctSig & rv, const ctkeyM &mixRing, const keyV &II, const key &base_hash) { CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.rangeSigs.size(), false, "Mismatched sizes of rv.outPk and rv.rangeSigs"); CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of rv.outPk and rv.ecdhInfo"); @@ -552,7 +557,7 @@ namespace rct { } //compute txn fee key txnFeeKey = scalarmultH(d2h(rv.txnFee)); - bool mgVerd = verRctMG(rv.MG, rv.mixRing, rv.outPk, txnFeeKey); + bool mgVerd = verRctMG(rv.MG, II, mixRing, rv.outPk, txnFeeKey, base_hash); DP("mg sig verified?"); DP(mgVerd); @@ -563,6 +568,9 @@ namespace rct { return false; } } + bool verRct(const rctSig & rv) { + return verRct(rv, rv.mixRing, rv.MG.II, rv.base_hash); + } //RingCT protocol //genRct: diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index d5c036910..f87312fa8 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -91,7 +91,7 @@ namespace rct { // Ver verifies that the MG sig was created correctly keyV keyImageV(const keyV &xx); mgSig MLSAG_Gen(key message, const keyM & pk, const keyV & xx, const unsigned int index); - bool MLSAG_Ver(key message, const keyM &pk, const mgSig &sig); + bool MLSAG_Ver(key message, const keyM &pk, const mgSig &sig, const keyV &II); //mgSig MLSAG_Gen_Old(const keyM & pk, const keyV & xx, const int index); //proveRange and verRange @@ -112,8 +112,8 @@ namespace rct { // this shows that sum inputs = sum outputs //Ver: // verifies the above sig is created corretly - mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const keyV &outMasks, const ctkeyV & outPk, unsigned int index, key txnFee); - bool verRctMG(mgSig mg, const ctkeyM & pubs, const ctkeyV & outPk, key txnFee); + mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const keyV &outMasks, const ctkeyV & outPk, unsigned int index, key txnFee, const key &base_hash); + bool verRctMG(mgSig mg, const ctkeyM & pubs, const ctkeyV & outPk, key txnFee, const key &base_hash); //These functions get keys from blockchain //replace these when connecting blockchain @@ -133,9 +133,10 @@ 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 ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> amounts, const ctkeyM &mixRing, unsigned int index); - rctSig genRct(const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const int mixin); + rctSig genRct(const ctkeyV & inSk, const keyV & destinations, const vector<xmr_amount> amounts, const ctkeyM &mixRing, const key &bash_hash, unsigned int index); + rctSig genRct(const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const key &bash_hash, const int mixin); bool verRct(const rctSig & rv); + bool verRct(const rctSig & rv, const ctkeyM &mixRing, const keyV &II, const key &base_hash); xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask); xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i); diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 13e9fb6f2..2dc4718db 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -148,7 +148,16 @@ namespace rct { BEGIN_SERIALIZE_OBJECT() FIELD(ss) FIELD(cc) - FIELD(II) + if (II.size() == 0) { + // loading + FIELD(II) + } + else { + // saving + keyV II; + II.push_back(this->II.back()); + FIELD(II) + } END_SERIALIZE() }; //contains the data for an asnl sig @@ -181,14 +190,16 @@ namespace rct { vector<ecdhTuple> ecdhInfo; ctkeyV outPk; xmr_amount txnFee; + key base_hash; BEGIN_SERIALIZE_OBJECT() FIELD(rangeSigs) FIELD(MG) - FIELD(mixRing) + // FIELD(mixRing) - not serialized, it can be reconstructed FIELD(ecdhInfo) FIELD(outPk) FIELD(txnFee) + // FIELD(base_hash) - not serialized, it can be reconstructed END_SERIALIZE() }; @@ -296,9 +307,11 @@ namespace rct { static inline rct::key pk2rct(const crypto::public_key &pk) { rct::key k; memcpy(&k, &pk, 32); return k; } static inline rct::key sk2rct(const crypto::secret_key &sk) { rct::key k; memcpy(&k, &sk, 32); return k; } static inline rct::key ki2rct(const crypto::key_image &ki) { rct::key k; memcpy(&k, &ki, 32); return k; } + static inline rct::key hash2rct(const crypto::hash &h) { rct::key k; memcpy(&k, &h, 32); return k; } static inline crypto::public_key rct2pk(const rct::key &k) { crypto::public_key pk; memcpy(&pk, &k, 32); return pk; } static inline crypto::secret_key rct2sk(const rct::key &k) { crypto::secret_key sk; memcpy(&sk, &k, 32); return sk; } static inline crypto::key_image rct2ki(const rct::key &k) { crypto::key_image ki; memcpy(&ki, &k, 32); return ki; } + static inline crypto::hash rct2hash(const rct::key &k) { crypto::hash h; memcpy(&h, &k, 32); return h; } static inline bool operator==(const rct::key &k0, const crypto::public_key &k1) { return !memcmp(&k0, &k1, 32); } static inline bool operator!=(const rct::key &k0, const crypto::public_key &k1) { return memcmp(&k0, &k1, 32); } } |