Explaining wipe of private secrets so that no smartass will "improve" it

This commit is contained in:
Cheng 2024-09-06 00:55:54 +00:00
parent 76b1948972
commit d81b7043df
No known key found for this signature in database

View File

@ -334,7 +334,11 @@ namespace ristretto255 {
std::array<uint8_t, crypto_core_ristretto255_SCALARBYTES> blob; std::array<uint8_t, crypto_core_ristretto255_SCALARBYTES> blob;
static_assert(sizeof(blob) == 32, "watch for size and alignment bugs. Everyone should standarize on 256 bit secret keys except for special needs"); static_assert(sizeof(blob) == 32, "watch for size and alignment bugs. Everyone should standarize on 256 bit secret keys except for special needs");
explicit scalar() = default; explicit scalar() = default;
~scalar() noexcept { wxSecretValue::Wipe(sizeof(*this), this); } ~scalar() noexcept { wxSecretValue::Wipe(sizeof(*this), this); } /*calls wipe to avoid leaving secrets around in memory.
Because wxSecretValue::Wipe is in a different optimisation unit, a separately compiled library,
optimisation of the destructor cannot optimise away the call to the wipe,
because the destructor optimiser does not know that all wipe does is
write to memory that is about to be discarded, nor can the wipe optimiser know that. */
explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>&& in) : blob{ in } {}; explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>&& in) : blob{ in } {};
explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>* in) :blob(*in) {}; explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>* in) :blob(*in) {};
explicit constexpr scalar(uintmax_t k){ for (auto& j : blob) { j = k; k = k >> 8; } } explicit constexpr scalar(uintmax_t k){ for (auto& j : blob) { j = k; k = k >> 8; } }
@ -345,9 +349,9 @@ namespace ristretto255 {
static_assert (ro::is_standard_signed_integer<T>); static_assert (ro::is_standard_signed_integer<T>);
if (i < 0) crypto_core_ristretto255_scalar_negate(&blob[0], &blob[0]); if (i < 0) crypto_core_ristretto255_scalar_negate(&blob[0], &blob[0]);
} }
scalar(scalar&&) = default; // Move constructor scalar(scalar&&) = default; // Move constructor. Does not need to call wipe, because destructor will be called on source
scalar(const scalar&) = default; // Copy constructor scalar(const scalar&) = default; // Copy constructor
scalar& operator=(scalar&&) = default; // Move assignment. scalar& operator=(scalar&&) = default; // Move assignment. Does not need to call wipe, because destructor will be called on source
scalar& operator=(const scalar&) = default; // Copy assignment. scalar& operator=(const scalar&) = default; // Copy assignment.
/* Don't need constant time equality test /* Don't need constant time equality test
bool operator==(const scalar& sc) const& { bool operator==(const scalar& sc) const& {