ringct: new {gen,decode}Rct APIs for convenience

A new version of genRct takes the mixRing as parameter, instead
of the inPk. inPk are part of the mixRing, and it is cleaner to
pass the mixRing data than to fetch it from the RingCT code.

A new version of decodeRct also returns the mask.

Also, failure to decode throws, so errors are properly detected.
This commit is contained in:
moneromooo-monero 2016-06-12 21:13:12 +01:00
parent 789b2e21f6
commit 66f96260b2
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
2 changed files with 27 additions and 11 deletions

View file

@ -466,11 +466,13 @@ namespace rct {
//decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) //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 // 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 // must know the destination private key to find the correct amount, else will return a random number
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, unsigned int index) {
CHECK_AND_ASSERT_THROW_MES(mixin >= 0, "Mixin must be positive");
CHECK_AND_ASSERT_THROW_MES(amounts.size() > 0, "Amounts must not be empty"); CHECK_AND_ASSERT_THROW_MES(amounts.size() > 0, "Amounts must not be empty");
CHECK_AND_ASSERT_THROW_MES(inSk.size() == inPk.size(), "Different number of public/private keys");
CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size(), "Different number of amounts/destinations"); CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size(), "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) {
CHECK_AND_ASSERT_THROW_MES(mixRing[n].size() == inSk.size(), "Bad mixRing size");
}
rctSig rv; rctSig rv;
rv.outPk.resize(destinations.size()); rv.outPk.resize(destinations.size());
@ -496,12 +498,19 @@ namespace rct {
} }
unsigned int index; rv.mixRing = mixRing;
tie(rv.mixRing, index) = populateFromBlockchain(inPk, mixin);
rv.MG = proveRctMG(rv.mixRing, inSk, outSk, rv.outPk, index); rv.MG = proveRctMG(rv.mixRing, inSk, outSk, rv.outPk, index);
if (!verRctMG(rv.MG, rv.mixRing, rv.outPk)) { printf("proveRctMG genreated bad data\n"); }
return rv; return rv;
} }
rctSig genRct(const ctkeyV & inSk, const ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const int mixin) {
unsigned int index;
ctkeyM mixRing;
tie(mixRing, index) = populateFromBlockchain(inPk, mixin);
return genRct(inSk, destinations, amounts, mixRing, index);
}
//RingCT protocol //RingCT protocol
//genRct: //genRct:
// creates an rctSig with all data necessary to verify the rangeProofs and that the signer owns one of the // creates an rctSig with all data necessary to verify the rangeProofs and that the signer owns one of the
@ -542,15 +551,16 @@ namespace rct {
//decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) //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 // 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 // must know the destination private key to find the correct amount, else will return a random number
xmr_amount decodeRct(rctSig & rv, const key & sk, unsigned int i) { xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i, key & mask) {
CHECK_AND_ASSERT_THROW_MES(rv.rangeSigs.size() > 0, "Empty rv.rangeSigs"); 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"); CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.rangeSigs.size(), "Mismatched sizes of rv.outPk and rv.rangeSigs");
CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index"); CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
//mask amount and mask //mask amount and mask
ecdhDecode(rv.ecdhInfo[i], sk); ecdhTuple ecdh_info = rv.ecdhInfo[i];
key mask = rv.ecdhInfo[i].mask; ecdhDecode(ecdh_info, sk);
key amount = rv.ecdhInfo[i].amount; mask = ecdh_info.mask;
key amount = ecdh_info.amount;
key C = rv.outPk[i].mask; key C = rv.outPk[i].mask;
DP("C"); DP("C");
DP(C); DP(C);
@ -559,9 +569,13 @@ namespace rct {
DP("Ctmp"); DP("Ctmp");
DP(Ctmp); DP(Ctmp);
if (equalKeys(C, Ctmp) == false) { if (equalKeys(C, Ctmp) == false) {
printf("warning, amount decoded incorrectly, will be unable to spend"); CHECK_AND_ASSERT_THROW_MES(false, "warning, amount decoded incorrectly, will be unable to spend");
} }
return h2d(amount); return h2d(amount);
} }
xmr_amount decodeRct(const rctSig & rv, const key & sk, unsigned int i) {
key mask;
return decodeRct(rv, sk, i, mask);
}
} }

View file

@ -133,9 +133,11 @@ namespace rct {
//decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) //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 // 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 // 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 ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const int mixin);
bool verRct(const rctSig & rv); bool verRct(const rctSig & rv);
xmr_amount decodeRct(rctSig & rv, const key & sk, unsigned int i); 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);