aboutsummaryrefslogtreecommitdiff
path: root/src/ringct
diff options
context:
space:
mode:
Diffstat (limited to 'src/ringct')
-rw-r--r--src/ringct/rctSigs.cpp36
-rw-r--r--src/ringct/rctSigs.h11
-rw-r--r--src/ringct/rctTypes.h17
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); }
}