Annotate noexcept and constexpr with HEDLEY, and add interval containment, ChaCha, and the dyadic range tables.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ryan Henry 2026-09-24 20:44:07 -06:00
parent 875f09fec1
commit 0d8a5a8131
97 changed files with 9212 additions and 1159 deletions

View file

@ -99,10 +99,19 @@ namespace detail
template <sharing Scheme, std::size_t Party, typename T>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr T party_coeff_times(const T & v) noexcept
{
if constexpr (Scheme == sharing::additive || Party == 0)
return v;
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
// Signed negation of the minimum is undefined. The two's-complement
// negation is well-defined on the unsigned width.
using unsigned_type = std::make_unsigned_t<T>;
return static_cast<T>(static_cast<unsigned_type>(0)
- static_cast<unsigned_type>(v));
}
else
return static_cast<T>(-v);
}
@ -122,13 +131,18 @@ struct secret_share
T value{};
secret_share() = default;
HEDLEY_NO_THROW
secret_share(const secret_share &) noexcept = default;
HEDLEY_NO_THROW
secret_share(secret_share &&) noexcept = default;
HEDLEY_NO_THROW
secret_share & operator=(const secret_share &) noexcept = default;
HEDLEY_NO_THROW
secret_share & operator=(secret_share &&) noexcept = default;
~secret_share() = default;
/// Bit-preserving construction. Does not apply a party coefficient.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_CONST
static constexpr secret_share from_raw(T v) noexcept
@ -138,15 +152,18 @@ struct secret_share
return s;
}
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_CONST
constexpr const T & raw() const noexcept { return value; }
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
constexpr T & raw() noexcept { return value; }
/// Secret-preserving conversion to an additive share of the same party.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
constexpr additive_share<T, Party> as_additive() const noexcept
@ -159,6 +176,7 @@ struct secret_share
}
/// Secret-preserving conversion to a subtractive share of the same party.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
constexpr subtractive_share<T, Party> as_subtractive() const noexcept
@ -174,18 +192,28 @@ struct secret_share
template <sharing NewScheme, std::size_t NewParty = Party>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, NewParty, NewScheme> retag() const noexcept
{
return secret_share<T, NewParty, NewScheme>::from_raw(value);
}
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
constexpr secret_share operator-() const noexcept
{
return from_raw(static_cast<T>(-value));
if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
using unsigned_type = std::make_unsigned_t<T>;
return from_raw(static_cast<T>(static_cast<unsigned_type>(0)
- static_cast<unsigned_type>(value)));
}
else
return from_raw(static_cast<T>(-value));
}
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
constexpr secret_share & operator+=(const secret_share & rhs) noexcept
{
@ -193,6 +221,7 @@ struct secret_share
return *this;
}
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
constexpr secret_share & operator-=(const secret_share & rhs) noexcept
{
@ -203,6 +232,7 @@ struct secret_share
template <typename Scalar,
std::enable_if_t<!is_secret_share_v<Scalar>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr secret_share & operator*=(const Scalar & c) noexcept
{
value = static_cast<T>(value * static_cast<T>(c));
@ -214,6 +244,7 @@ struct secret_share
std::enable_if_t<!is_secret_share_v<Plain>
&& std::is_convertible_v<Plain, T>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr secret_share & operator+=(const Plain & c) noexcept
{
if constexpr (Party == 0)
@ -225,6 +256,7 @@ struct secret_share
std::enable_if_t<!is_secret_share_v<Plain>
&& std::is_convertible_v<Plain, T>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_NO_THROW
constexpr secret_share & operator-=(const Plain & c) noexcept
{
if constexpr (Party == 0)
@ -240,6 +272,7 @@ struct secret_share
template <typename T, std::size_t Party, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator+(
secret_share<T, Party, Scheme> lhs,
const secret_share<T, Party, Scheme> & rhs) noexcept
@ -251,6 +284,7 @@ constexpr secret_share<T, Party, Scheme> operator+(
template <typename T, std::size_t Party, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator-(
secret_share<T, Party, Scheme> lhs,
const secret_share<T, Party, Scheme> & rhs) noexcept
@ -263,6 +297,7 @@ template <typename T, std::size_t Party, sharing Scheme, typename Scalar,
std::enable_if_t<!is_secret_share_v<Scalar>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator*(
secret_share<T, Party, Scheme> lhs, const Scalar & c) noexcept
{
@ -274,6 +309,7 @@ template <typename T, std::size_t Party, sharing Scheme, typename Scalar,
std::enable_if_t<!is_secret_share_v<Scalar>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator*(
const Scalar & c, secret_share<T, Party, Scheme> rhs) noexcept
{
@ -290,6 +326,7 @@ template <typename T, std::size_t Party, sharing LhsScheme, sharing RhsScheme,
std::enable_if_t<LhsScheme != RhsScheme, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, LhsScheme> operator+(
const secret_share<T, Party, LhsScheme> & lhs,
const secret_share<T, Party, RhsScheme> & rhs) noexcept
@ -306,6 +343,7 @@ template <typename T, std::size_t Party, sharing LhsScheme, sharing RhsScheme,
std::enable_if_t<LhsScheme != RhsScheme, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, LhsScheme> operator-(
const secret_share<T, Party, LhsScheme> & lhs,
const secret_share<T, Party, RhsScheme> & rhs) noexcept
@ -327,6 +365,7 @@ template <typename T, std::size_t Party, sharing Scheme, typename Plain,
&& std::is_convertible_v<Plain, T>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator+(
secret_share<T, Party, Scheme> lhs, const Plain & c) noexcept
{
@ -339,6 +378,7 @@ template <typename T, std::size_t Party, sharing Scheme, typename Plain,
&& std::is_convertible_v<Plain, T>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator+(
const Plain & c, secret_share<T, Party, Scheme> rhs) noexcept
{
@ -351,6 +391,7 @@ template <typename T, std::size_t Party, sharing Scheme, typename Plain,
&& std::is_convertible_v<Plain, T>, int> = 0>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr secret_share<T, Party, Scheme> operator-(
secret_share<T, Party, Scheme> lhs, const Plain & c) noexcept
{
@ -365,6 +406,7 @@ constexpr secret_share<T, Party, Scheme> operator-(
template <typename T, std::size_t Party, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr bool operator==(const secret_share<T, Party, Scheme> & lhs,
const secret_share<T, Party, Scheme> & rhs) noexcept
{
@ -374,6 +416,7 @@ constexpr bool operator==(const secret_share<T, Party, Scheme> & lhs,
template <typename T, std::size_t Party, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr bool operator!=(const secret_share<T, Party, Scheme> & lhs,
const secret_share<T, Party, Scheme> & rhs) noexcept
{
@ -387,10 +430,21 @@ constexpr bool operator!=(const secret_share<T, Party, Scheme> & lhs,
template <typename T, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr T reconstruct(const secret_share<T, 0, Scheme> & s0,
const secret_share<T, 1, Scheme> & s1) noexcept
{
if constexpr (Scheme == sharing::additive)
if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
using unsigned_type = std::make_unsigned_t<T>;
if constexpr (Scheme == sharing::additive)
return static_cast<T>(static_cast<unsigned_type>(s0.raw())
+ static_cast<unsigned_type>(s1.raw()));
else
return static_cast<T>(static_cast<unsigned_type>(s0.raw())
- static_cast<unsigned_type>(s1.raw()));
}
else if constexpr (Scheme == sharing::additive)
return static_cast<T>(s0.raw() + s1.raw());
else
return static_cast<T>(s0.raw() - s1.raw());
@ -399,6 +453,7 @@ constexpr T reconstruct(const secret_share<T, 0, Scheme> & s0,
template <typename T, sharing Scheme>
HEDLEY_ALWAYS_INLINE
HEDLEY_PURE
HEDLEY_NO_THROW
constexpr T reconstruct(const secret_share<T, 1, Scheme> & s1,
const secret_share<T, 0, Scheme> & s0) noexcept
{
@ -412,6 +467,7 @@ constexpr T reconstruct(const secret_share<T, 1, Scheme> & s1,
template <typename T>
HEDLEY_ALWAYS_INLINE
HEDLEY_CONST
HEDLEY_NO_THROW
constexpr auto make_additive_shares(T secret) noexcept
{
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
@ -423,6 +479,7 @@ constexpr auto make_additive_shares(T secret) noexcept
template <typename T>
HEDLEY_ALWAYS_INLINE
HEDLEY_CONST
HEDLEY_NO_THROW
constexpr auto make_subtractive_shares(T secret) noexcept
{
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
@ -460,13 +517,16 @@ struct party_key : Key
#endif
}
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
Key & key() noexcept { return static_cast<Key &>(*this); }
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
const Key & key() const noexcept { return static_cast<const Key &>(*this); }
/// Party-tagged additive share of the comparison absorb addend.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
auto cmp_addend() const noexcept
{