aboutsummaryrefslogtreecommitdiff
path: root/src/ringct
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-01-06 19:49:52 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-01-22 23:17:31 +0000
commit99d946e6191056f747225d36a2408085624b516e (patch)
tree9b81751a703e40d188c26d035edb34e945e28422 /src/ringct
parentringct: save 3 bytes on bulletproof size (diff)
downloadmonero-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.cpp28
-rw-r--r--src/ringct/rctOps.h4
-rw-r--r--src/ringct/rctSigs.cpp8
-rw-r--r--src/ringct/rctTypes.h15
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();
}