ringct: make rctSigBase serialization follow strict aliasing rule

Accessing an object of type `char` thru an lvalue of type `crypto::hash8` is undefined behavior.
https://developers.redhat.com/blog/2020/06/03/the-joys-and-perils-of-aliasing-in-c-and-c-part-2
This commit is contained in:
jeffro256 2023-10-23 16:28:02 -05:00
parent 67d190ce7c
commit 05231400ce
No known key found for this signature in database
GPG Key ID: 6F79797A6E392442

View File

@ -362,11 +362,17 @@ namespace rct {
{ {
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus) if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus)
{ {
// Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the
// first 8 bytes of ecdhInfo[i].amount
ar.begin_object(); ar.begin_object();
if (!typename Archive<W>::is_saving()) crypto::hash8 trunc_amount; // placeholder variable needed to maintain "strict aliasing"
if (!typename Archive<W>::is_saving()) // loading
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes)); memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount; else // saving
FIELD(amount); memcpy(trunc_amount.data, ecdhInfo[i].amount.bytes, sizeof(trunc_amount));
FIELD(trunc_amount);
if (!typename Archive<W>::is_saving()) // loading
memcpy(ecdhInfo[i].amount.bytes, trunc_amount.data, sizeof(trunc_amount));
ar.end_object(); ar.end_object();
} }
else else