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-02-12 12:16:45 +0000 |
commit | 6ba3a116377ffdf03e0c3580ef5a0c7c6743f69f (patch) | |
tree | 1202fb01fad655c724be61964570e6259f30918a /src/ringct | |
parent | ringct: save 3 bytes on bulletproof size (diff) | |
download | monero-6ba3a116377ffdf03e0c3580ef5a0c7c6743f69f.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 41bbf6ca3..b4609caab 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -487,18 +487,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 42be80ac5..28d523e4f 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -682,7 +682,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 @@ -803,7 +803,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 @@ -1102,7 +1102,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; @@ -1132,7 +1132,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 0a4dad1a0..de026226e 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -282,7 +282,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(); } |