diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2019-01-06 19:49:52 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2019-01-22 23:17:31 +0000 |
commit | 99d946e6191056f747225d36a2408085624b516e (patch) | |
tree | 9b81751a703e40d188c26d035edb34e945e28422 /src/ringct | |
parent | ringct: save 3 bytes on bulletproof size (diff) | |
download | monero-99d946e6191056f747225d36a2408085624b516e.tar.xz |
ringct: encode 8 byte amount, saving 24 bytes per output
Found by knaccc
Diffstat (limited to 'src/ringct')
-rw-r--r-- | src/ringct/rctOps.cpp | 28 | ||||
-rw-r--r-- | src/ringct/rctOps.h | 4 | ||||
-rw-r--r-- | src/ringct/rctSigs.cpp | 8 | ||||
-rw-r--r-- | src/ringct/rctTypes.h | 15 |
4 files changed, 44 insertions, 11 deletions
diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index 0ec654af6..b28aa4fe6 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -670,18 +670,38 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec) { + static key ecdhHash(const key &k) + { + char data[38]; + rct::key hash; + memcpy(data, "amount", 6); + memcpy(data + 6, &k, sizeof(k)); + cn_fast_hash(hash, data, sizeof(data)); + return hash; + } + static void xor8(key &v, const key &k) + { + for (int i = 0; i < 8; ++i) + v.bytes[i] ^= k.bytes[i]; + } + void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool short_amount) { key sharedSec1 = hash_to_scalar(sharedSec); 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); + if (short_amount) + xor8(unmasked.amount, ecdhHash(sharedSec)); + else + sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); } - void ecdhDecode(ecdhTuple & masked, const key & sharedSec) { + void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool short_amount) { key sharedSec1 = hash_to_scalar(sharedSec); key sharedSec2 = hash_to_scalar(sharedSec1); //decode sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); - sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); + if (short_amount) + xor8(masked.amount, ecdhHash(sharedSec)); + else + sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); } } diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index 60e920b3a..01cdd6fd7 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -182,7 +182,7 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec); - void ecdhDecode(ecdhTuple & masked, const key & sharedSec); + void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, bool short_amount); + void ecdhDecode(ecdhTuple & masked, const key & sharedSec, bool short_amount); } #endif /* RCTOPS_H */ diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 298afd0d9..6687c91cd 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -716,7 +716,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(amounts[i]); - hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2); } //set txn fee @@ -853,7 +853,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(outamounts[i]); - hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2); } //set txn fee @@ -1151,7 +1151,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - hwdev.ecdhDecode(ecdh_info, sk); + hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; @@ -1181,7 +1181,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - hwdev.ecdhDecode(ecdh_info, sk); + hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 5578a51dc..54fca1d05 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -283,7 +283,20 @@ namespace rct { return false; for (size_t i = 0; i < outputs; ++i) { - FIELDS(ecdhInfo[i]) + if (type == RCTTypeBulletproof2) + { + ar.begin_object(); + FIELD_N("mask", ecdhInfo[i].mask); + if (!typename Archive<W>::is_saving()) + memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes)); + crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount; + FIELD(amount); + ar.end_object(); + } + else + { + FIELDS(ecdhInfo[i]) + } if (outputs - i > 1) ar.delimit_array(); } |