aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cryptonote_core/blockchain.cpp14
-rw-r--r--src/cryptonote_core/cryptonote_boost_serialization.h13
-rw-r--r--src/ringct/rctSigs.cpp62
-rw-r--r--src/ringct/rctSigs.h4
-rw-r--r--src/ringct/rctTypes.h11
-rw-r--r--tests/unit_tests/serialization.cpp6
6 files changed, 55 insertions, 55 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index f6f56b086..91a9d5d6f 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2475,12 +2475,12 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
const rct::ctkeyM &mixRing = tx.rct_signatures.mixRing.empty() ? reconstructed_mixRing : tx.rct_signatures.mixRing;
// always do II, because it's split in the simple version, and always do outPk
- // all MGs should have the same II size (1)
+ // all MGs should have empty II
for (size_t n = 0; n < tx.rct_signatures.MGs.size(); ++n)
{
- if (tx.rct_signatures.MGs[n].II.size() != 1)
+ if (tx.rct_signatures.MGs[n].II.size() != 0)
{
- LOG_PRINT_L1("Failed to check ringct signatures: mismatched MGs II sizes");
+ LOG_PRINT_L1("Failed to check ringct signatures: non empty MGs II");
return false;
}
}
@@ -2489,7 +2489,6 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
for (size_t n = 0; n < tx.vin.size(); ++n)
{
reconstructed_II[n].push_back(rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image));
- reconstructed_II[n].push_back(tx.rct_signatures.MGs[n].II[0]);
}
if (tx.rct_signatures.outPk.size() != tx.vout.size())
@@ -2579,7 +2578,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
// if the tx already has a non empty mixRing and/or II, use them,
// else reconstruct them. Always do outPk.
const rct::ctkeyM &mixRing = tx.rct_signatures.mixRing.empty() ? reconstructed_mixRing : tx.rct_signatures.mixRing;
- const rct::keyV &II = tx.rct_signatures.MG.II.size() == 1 ? reconstructed_II : tx.rct_signatures.MG.II;
+ const rct::keyV &II = tx.rct_signatures.MG.II.empty() ? reconstructed_II : tx.rct_signatures.MG.II;
const rct::ctkeyV outPk = reconstructed_outPk;
// RCT needs the same mixin for all inputs
@@ -2604,14 +2603,13 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
}
}
- if (tx.rct_signatures.MG.II.size() == 1)
+ if (tx.rct_signatures.MG.II.empty())
{
reconstructed_II.resize(tx.vin.size());
for (size_t n = 0; n < tx.vin.size(); ++n)
{
reconstructed_II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
}
- reconstructed_II.push_back(tx.rct_signatures.MG.II.back());
}
if (tx.rct_signatures.outPk.size() != tx.vout.size())
@@ -2657,7 +2655,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
}
}
- if (II.size() != 1 + tx.vin.size())
+ if (II.size() != tx.vin.size())
{
LOG_PRINT_L1("Failed to check ringct signatures: mismatched II/vin sizes");
return false;
diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h
index 41f864803..8a82aa7a7 100644
--- a/src/cryptonote_core/cryptonote_boost_serialization.h
+++ b/src/cryptonote_core/cryptonote_boost_serialization.h
@@ -209,19 +209,12 @@ namespace boost
a & x.s;
}
- inline void serialize(boost::archive::binary_iarchive &a, rct::mgSig &x, const boost::serialization::version_type ver)
- {
- a & x.ss;
- a & x.cc;
- x.II.resize(1);
- a & x.II[0];
- }
-
- inline void serialize(boost::archive::binary_oarchive &a, rct::mgSig &x, const boost::serialization::version_type ver)
+ template <class Archive>
+ inline void serialize(Archive &a, rct::mgSig &x, const boost::serialization::version_type ver)
{
a & x.ss;
a & x.cc;
- a & x.II.back();
+ // a & x.II; // not serialized, we can recover it from the tx vin
}
template <class Archive>
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp
index 0d4fbee1a..c252645f8 100644
--- a/src/ringct/rctSigs.cpp
+++ b/src/ringct/rctSigs.cpp
@@ -148,7 +148,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
- mgSig MLSAG_Gen(key message, const keyM & pk, const keyV & xx, const unsigned int index) {
+ mgSig MLSAG_Gen(key message, const keyM & pk, const keyV & xx, const unsigned int index, size_t dsRows) {
mgSig rv;
size_t cols = pk.size();
CHECK_AND_ASSERT_THROW_MES(cols >= 2, "Error! What is c if cols = 1!");
@@ -159,20 +159,21 @@ namespace rct {
CHECK_AND_ASSERT_THROW_MES(pk[i].size() == rows, "pk is not rectangular");
}
CHECK_AND_ASSERT_THROW_MES(xx.size() == rows, "Bad xx size");
+ CHECK_AND_ASSERT_THROW_MES(dsRows <= rows, "Bad dsRows size");
- size_t i = 0, j = 0;
+ size_t i = 0, j = 0, ii = 0;
key c, c_old, L, R, Hi;
sc_0(c_old.bytes);
- vector<geDsmp> Ip(rows);
- rv.II = keyV(rows);
- rv.ss = keyM(cols, rv.II);
+ vector<geDsmp> Ip(dsRows);
+ rv.II = keyV(dsRows);
keyV alpha(rows);
keyV aG(rows);
- keyV aHP(rows);
- keyV toHash(1 + 3 * rows);
+ rv.ss = keyM(cols, aG);
+ keyV aHP(dsRows);
+ keyV toHash(1 + 3 * dsRows + 2 * (rows - dsRows));
toHash[0] = message;
DP("here1");
- for (i = 0; i < rows; i++) {
+ for (i = 0; i < dsRows; i++) {
skpkGen(alpha[i], aG[i]); //need to save alphas for later..
Hi = hashToPoint(pk[index][i]);
aHP[i] = scalarmultKey(Hi, alpha[i]);
@@ -182,6 +183,13 @@ namespace rct {
rv.II[i] = scalarmultKey(Hi, xx[i]);
precomp(Ip[i].k, rv.II[i]);
}
+ size_t ndsRows = 3 * dsRows; //non Double Spendable Rows (see identity chains paper)
+ for (i = dsRows, ii = 0 ; i < rows ; i++, ii++) {
+ skpkGen(alpha[i], aG[i]); //need to save alphas for later..
+ toHash[ndsRows + 2 * ii + 1] = pk[index][i];
+ toHash[ndsRows + 2 * ii + 2] = aG[i];
+ }
+
c_old = hash_to_scalar(toHash);
@@ -193,7 +201,7 @@ namespace rct {
rv.ss[i] = skvGen(rows);
sc_0(c.bytes);
- for (j = 0; j < rows; j++) {
+ for (j = 0; j < dsRows; j++) {
addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
hashToPoint(Hi, pk[i][j]);
addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j].k);
@@ -201,6 +209,11 @@ namespace rct {
toHash[3 * j + 2] = L;
toHash[3 * j + 3] = R;
}
+ for (j = dsRows, ii = 0; j < rows; j++, ii++) {
+ addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
+ toHash[ndsRows + 2 * ii + 1] = pk[i][j];
+ toHash[ndsRows + 2 * ii + 2] = L;
+ }
c = hash_to_scalar(toHash);
copy(c_old, c);
i = (i + 1) % cols;
@@ -224,7 +237,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, const keyV &II) {
+ bool MLSAG_Ver(key message, const keyM & pk, const mgSig & rv, const keyV &II, size_t dsRows) {
size_t cols = pk.size();
CHECK_AND_ASSERT_MES(cols >= 2, false, "Error! What is c if cols = 1!");
@@ -233,25 +246,27 @@ 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(II.size() == rows, false, "Bad II size");
+ CHECK_AND_ASSERT_MES(II.size() == dsRows, 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");
}
+ CHECK_AND_ASSERT_MES(dsRows <= rows, false, "Bad dsRows value");
- size_t i = 0, j = 0;
+ size_t i = 0, j = 0, ii = 0;
key c, L, R, Hi;
key c_old = copy(rv.cc);
- vector<geDsmp> Ip(rows);
- for (i= 0 ; i< rows ; i++) {
+ vector<geDsmp> Ip(dsRows);
+ for (i = 0 ; i < dsRows ; i++) {
precomp(Ip[i].k, II[i]);
}
- keyV toHash(1 + 3 * rows);
+ size_t ndsRows = 3 * dsRows; //non Double Spendable Rows (see identity chains paper
+ keyV toHash(1 + 3 * dsRows + 2 * (rows - dsRows));
toHash[0] = message;
i = 0;
while (i < cols) {
sc_0(c.bytes);
- for (j = 0; j < rows; j++) {
+ for (j = 0; j < dsRows; j++) {
addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
hashToPoint(Hi, pk[i][j]);
addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j].k);
@@ -259,6 +274,11 @@ namespace rct {
toHash[3 * j + 2] = L;
toHash[3 * j + 3] = R;
}
+ for (j = dsRows, ii = 0 ; j < rows ; j++, ii++) {
+ addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
+ toHash[ndsRows + 2 * ii + 1] = pk[i][j];
+ toHash[ndsRows + 2 * ii + 2] = L;
+ }
c = hash_to_scalar(toHash);
copy(c_old, c);
i = (i + 1);
@@ -376,7 +396,7 @@ namespace rct {
ctkeyV signed_data = outPk;
signed_data.push_back(ctkey({message, identity()}));
key msg = cn_fast_hash(signed_data);
- return MLSAG_Gen(msg, M, sk, index);
+ return MLSAG_Gen(msg, M, sk, index, rows);
}
@@ -403,7 +423,7 @@ namespace rct {
sk[0] = copy(inSk.dest);
sc_sub(sk[1].bytes, inSk.mask.bytes, a.bytes);
}
- return MLSAG_Gen(message, M, sk, index);
+ return MLSAG_Gen(message, M, sk, index, rows);
}
@@ -451,7 +471,7 @@ namespace rct {
key msg = cn_fast_hash(signed_data);
DP("message:");
DP(msg);
- return MLSAG_Ver(msg, M, mg, II);
+ return MLSAG_Ver(msg, M, mg, II, rows);
}
//Ring-ct Simple MG sigs
@@ -472,7 +492,7 @@ namespace rct {
subKeys(M[i][1], pubs[i].mask, C);
}
//DP(C);
- return MLSAG_Ver(message, M, mg, II);
+ return MLSAG_Ver(message, M, mg, II, rows);
}
//These functions get keys from blockchain
@@ -729,7 +749,7 @@ namespace rct {
{
for (size_t n = 0; n < II->size(); ++n)
{
- CHECK_AND_ASSERT_MES((*II)[n].size() == 2, false, "Bad II size");
+ CHECK_AND_ASSERT_MES((*II)[n].size() == 1, false, "Bad II size");
}
}
diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h
index d150e7180..558af22fd 100644
--- a/src/ringct/rctSigs.h
+++ b/src/ringct/rctSigs.h
@@ -90,8 +90,8 @@ namespace rct {
// the signer knows a secret key for each row in that column
// 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, const keyV &II);
+ mgSig MLSAG_Gen(key message, const keyM & pk, const keyV & xx, const unsigned int index, size_t dsRows);
+ bool MLSAG_Ver(key message, const keyM &pk, const mgSig &sig, const keyV &II, size_t dsRows);
//mgSig MLSAG_Gen_Old(const keyM & pk, const keyV & xx, const int index);
//proveRange and verRange
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h
index 1ba280aba..8df403c68 100644
--- a/src/ringct/rctTypes.h
+++ b/src/ringct/rctTypes.h
@@ -148,16 +148,7 @@ namespace rct {
BEGIN_SERIALIZE_OBJECT()
FIELD(ss)
FIELD(cc)
- if (II.size() == 0) {
- // loading
- FIELD(II)
- }
- else {
- // saving
- keyV II;
- II.push_back(this->II.back());
- FIELD(II)
- }
+ // FIELD(II) - not serialized, it can be reconstructed
END_SERIALIZE()
};
//contains the data for an asnl sig
diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
index 0da23c0d2..9311ca016 100644
--- a/tests/unit_tests/serialization.cpp
+++ b/tests/unit_tests/serialization.cpp
@@ -582,8 +582,7 @@ TEST(Serialization, serializes_ringct_types)
ASSERT_TRUE(mg0.cc == mg1.cc);
// mixRing and II are not serialized, they are meant to be reconstructed
- ASSERT_TRUE(mg1.II.size() == 1);
- ASSERT_TRUE(mg1.II[0] == mg0.II.back());
+ ASSERT_TRUE(mg1.II.empty());
rg0 = s0.rangeSigs.front();
ASSERT_TRUE(serialization::dump_binary(rg0, blob));
@@ -605,8 +604,7 @@ TEST(Serialization, serializes_ringct_types)
}
ASSERT_TRUE(s0.MG.cc == s1.MG.cc);
// mixRing and II are not serialized, they are meant to be reconstructed
- ASSERT_TRUE(s1.MG.II.size() == 1);
- ASSERT_TRUE(s1.MG.II[0] == s0.MG.II.back());
+ ASSERT_TRUE(s1.MGs[0].II.empty());
// mixRing and II are not serialized, they are meant to be reconstructed
ASSERT_TRUE(s1.mixRing.size() == 0);