|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|