Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -60,7 +60,8 @@ T offset_horner_group_sub(T a, T b) noexcept
|
|||
return static_cast<T>(static_cast<u>(static_cast<u>(a) - static_cast<u>(b)));
|
||||
}
|
||||
|
||||
/// `eta = x - r` and `center = 2r`, both in the input group.
|
||||
/// @brief `eta = x - r` and `center = 2r`, both in the input group.
|
||||
/// @tparam T value type
|
||||
template <typename T>
|
||||
struct offset_horner_x_plus_r
|
||||
{
|
||||
|
|
@ -218,8 +219,11 @@ T domain_min() noexcept
|
|||
return T{0};
|
||||
}
|
||||
|
||||
/// Public center-space cut where `center + eta` crosses the domain end.
|
||||
/// Empty when that cut is outside the domain, including `eta == 0`.
|
||||
/// @brief Public center-space cut where `center + eta` crosses the domain end.
|
||||
/// @details Empty when that cut is outside the domain, including `eta == 0`.
|
||||
/// @tparam T value type
|
||||
/// @param eta the `eta`
|
||||
/// @return Public center-space cut where `center + eta` crosses the domain end
|
||||
template <typename T>
|
||||
HEDLEY_NO_THROW
|
||||
std::optional<T> carry_threshold(T eta) noexcept
|
||||
|
|
@ -246,7 +250,11 @@ std::optional<T> carry_threshold(T eta) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
/// `center + kappa` is the wrapped representative, as a mathematical integer.
|
||||
/// @brief `center + kappa` is the wrapped representative, as a mathematical integer.
|
||||
/// @tparam T value type
|
||||
/// @param left the `left`
|
||||
/// @param eta the `eta`
|
||||
/// @return `center + kappa` is the wrapped representative, as a mathematical integer
|
||||
template <typename T>
|
||||
HEDLEY_NO_THROW
|
||||
int64_t kappa_for(T left, T eta) noexcept
|
||||
|
|
@ -363,9 +371,14 @@ std::vector<prepared_piece<Degree, InputT>> prepare_pieces(
|
|||
return out;
|
||||
}
|
||||
|
||||
/// `out[k]` sums to the polynomial at the wrapped input. It is
|
||||
/// @brief `out[k]` sums to the polynomial at the wrapped input. It is
|
||||
/// `center^k` times the public binomial coefficient of `kappa`, not a
|
||||
/// coefficient you Horner-evaluate at `eta`.
|
||||
/// @tparam Degree degree
|
||||
/// @param seg the `seg`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param kappa the `kappa`
|
||||
/// @return `out[k]` sums to the polynomial at the wrapped input
|
||||
template <std::size_t Degree>
|
||||
std::array<uint64_t, Degree + 1> contributions(
|
||||
const std::array<std::vector<uint64_t>, Degree + 1> & seg,
|
||||
|
|
@ -386,7 +399,9 @@ std::array<uint64_t, Degree + 1> contributions(
|
|||
|
||||
} // namespace offset_horner_detail
|
||||
|
||||
/// Both parties' comparison keys and wrap-piece shares for one center.
|
||||
/// @brief Both parties' comparison keys and wrap-piece shares for one center.
|
||||
/// @tparam InputT input domain type
|
||||
/// @tparam Degree degree
|
||||
template <typename InputT, std::size_t Degree = offset_horner_max_degree>
|
||||
struct offset_horner_keys
|
||||
{
|
||||
|
|
@ -398,9 +413,9 @@ struct offset_horner_keys
|
|||
using key_pair = decltype(dpf::make_dpf(std::declval<InputT>(), dpf::gt(uint64_t{0})));
|
||||
|
||||
InputT center{};
|
||||
/// `keys[m]` is `gt(center^m)` keyed at `center`. `.first` is party 0.
|
||||
/// @brief `keys[m]` is `gt(center^m)` keyed at `center`. `.first` is party 0.
|
||||
std::array<key_pair, Degree + 1> keys;
|
||||
/// Random additive split of `center^m`, indexed `[power][party]`.
|
||||
/// @brief Random additive split of `center^m`, indexed `[power][party]`.
|
||||
std::array<std::array<uint64_t, 2>, Degree + 1> wrap_share{};
|
||||
};
|
||||
|
||||
|
|
@ -424,9 +439,17 @@ offset_horner_keys<InputT, Degree> make_offset_horner_keys(InputT center)
|
|||
return mat;
|
||||
}
|
||||
|
||||
/// Cleartext binomial coefficients of the selected refined piece in the
|
||||
/// @brief Cleartext binomial coefficients of the selected refined piece in the
|
||||
/// variable `center`: Horner at `lift(center)` is the polynomial at the
|
||||
/// wrapped input.
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @param center the `center`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param eta the `eta`
|
||||
/// @return Cleartext binomial coefficients of the selected refined piece in the variable `center`:
|
||||
/// Horner at `lift(center)` is the polynomial at the wrapped input
|
||||
template <std::size_t Degree, typename InputT>
|
||||
std::array<uint64_t, Degree + 1> offset_horner_clear_coefficients(
|
||||
InputT center,
|
||||
|
|
@ -447,7 +470,14 @@ std::array<uint64_t, Degree + 1> offset_horner_clear_coefficients(
|
|||
piece.coeff, static_cast<uint64_t>(piece.kappa));
|
||||
}
|
||||
|
||||
/// Cleartext value of the selected piece at the wrapped `center + eta`.
|
||||
/// @brief Cleartext value of the selected piece at the wrapped `center + eta`.
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @param center the `center`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param eta the `eta`
|
||||
/// @return Cleartext value of the selected piece at the wrapped `center + eta`
|
||||
template <std::size_t Degree, typename InputT>
|
||||
uint64_t offset_horner_clear(
|
||||
InputT center,
|
||||
|
|
@ -459,7 +489,18 @@ uint64_t offset_horner_clear(
|
|||
return offset_horner_detail::horner_at<Degree>(c, offset_horner_detail::lift(center));
|
||||
}
|
||||
|
||||
/// `Party` selects `.first` or `.second` of each key pair.
|
||||
/// @brief `Party` selects `.first` or `.second` of each key pair.
|
||||
/// @tparam Party party index, `0` or `1`
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @tparam KeyPair key pair
|
||||
/// @param keys the party keys
|
||||
/// @param wrap_share the `wrap_share`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param eta the `eta`
|
||||
/// @return `Party` selects `.first` or `.second` of each key pair
|
||||
/// @throws std::invalid_argument if `one comparison key per power`
|
||||
template <std::size_t Party, std::size_t Degree, typename InputT, typename KeyPair>
|
||||
std::array<uint64_t, Degree + 1> offset_horner_coefficient_share(
|
||||
const std::vector<KeyPair> & keys,
|
||||
|
|
@ -492,7 +533,15 @@ std::array<uint64_t, Degree + 1> offset_horner_coefficient_share(
|
|||
return contributions<Degree>(seg, ordered, kappa);
|
||||
}
|
||||
|
||||
/// One party's coefficient shares. `Party` is 0 or 1.
|
||||
/// @brief One party's coefficient shares. `Party` is 0 or 1.
|
||||
/// @tparam Party party index, `0` or `1`
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @param mat the `mat`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param eta the `eta`
|
||||
/// @return One party's coefficient shares
|
||||
template <std::size_t Party, std::size_t Degree, typename InputT>
|
||||
std::array<uint64_t, Degree + 1> offset_horner_coefficient_share(
|
||||
const offset_horner_keys<InputT, Degree> & mat,
|
||||
|
|
@ -506,10 +555,12 @@ std::array<uint64_t, Degree + 1> offset_horner_coefficient_share(
|
|||
keys, mat.wrap_share, knots, coeff, eta);
|
||||
}
|
||||
|
||||
/// Both parties' Horner shares from one joint Doerner–Shelat generation.
|
||||
/// `center0 XOR center1` is the comparison point, in geneval's share
|
||||
/// @brief Both parties' Horner shares from one joint Doerner–Shelat generation.
|
||||
/// @details `center0 XOR center1` is the comparison point, in geneval's share
|
||||
/// convention (the signed MSB of `center0` is flipped before the XOR, and
|
||||
/// flipped back here). `eta` is already public.
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
template <std::size_t Degree, typename InputT>
|
||||
struct geneval_offset_horner_result
|
||||
{
|
||||
|
|
@ -523,8 +574,12 @@ struct geneval_offset_horner_result
|
|||
uint64_t value1 = 0;
|
||||
};
|
||||
|
||||
/// Logical comparison point for geneval's XOR shares. Matches `make_dpf(P)`
|
||||
/// @brief Logical comparison point for geneval's XOR shares. Matches `make_dpf(P)`
|
||||
/// when `center1 = P XOR center0` or when `center0 = P` and `center1 = 0`.
|
||||
/// @tparam InputT input domain type
|
||||
/// @param center0 the `center0`
|
||||
/// @param center1 the `center1`
|
||||
/// @return Logical comparison point for geneval's XOR shares
|
||||
template <typename InputT>
|
||||
InputT geneval_offset_horner_center(InputT center0, InputT center1)
|
||||
{
|
||||
|
|
@ -602,12 +657,22 @@ geneval_offset_horner_result<Degree, InputT> geneval_at(
|
|||
|
||||
} // namespace offset_horner_detail
|
||||
|
||||
/// Geneval-style offset Horner. The center is XOR-shared as in `geneval_point`.
|
||||
/// Comparison keys are opened with the same local Doerner–Shelat protocol
|
||||
/// @brief Geneval-style offset Horner. The center is XOR-shared as in `geneval_point`.
|
||||
/// @details Comparison keys are opened with the same local Doerner–Shelat protocol
|
||||
/// geneval uses for its correction words. The value dot uses the per-piece
|
||||
/// carry shift and is local.
|
||||
/// A value-correction word is required on every level of the secret path, so
|
||||
/// this does not stop early the way a leaf trie does.
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @tparam Rng rng
|
||||
/// @param center0 the `center0`
|
||||
/// @param center1 the `center1`
|
||||
/// @param eta the `eta`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param rng the Doerner–Shelat randomness tapes
|
||||
/// @return Geneval-style offset Horner
|
||||
template <std::size_t Degree = offset_horner_max_degree,
|
||||
typename InputT,
|
||||
typename Rng>
|
||||
|
|
@ -629,13 +694,27 @@ geneval_offset_horner_result<Degree, InputT> geneval_offset_horner(
|
|||
const std::vector<std::array<uint64_t, Degree + 1>> & coeff)
|
||||
{
|
||||
using block = typename dpf::prg::aes128::block_type;
|
||||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
dpf::ds_randomness<block (*)(), dpf::detail::urandom_pad_rng> rng{
|
||||
dpf::uniform_sample<block>, {}};
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
return geneval_offset_horner<Degree>(
|
||||
center0, center1, eta, knots, coeff, std::move(rng));
|
||||
}
|
||||
|
||||
/// Additive shares of the center: `center0 + center1` is the comparison point.
|
||||
/// @brief Additive shares of the center: `center0 + center1` is the comparison point.
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @tparam Rng rng
|
||||
/// @param arith_input_t the `arith_input_t`
|
||||
/// @param center0 the `center0`
|
||||
/// @param center1 the `center1`
|
||||
/// @param eta the `eta`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param rng the Doerner–Shelat randomness tapes
|
||||
/// @return Additive shares of the center: `center0 + center1` is the comparison point
|
||||
template <std::size_t Degree = offset_horner_max_degree,
|
||||
typename InputT,
|
||||
typename Rng>
|
||||
|
|
@ -650,10 +729,21 @@ geneval_offset_horner_result<Degree, InputT> geneval_offset_horner(
|
|||
true, center0, center1, center, eta, knots, coeff, std::move(rng));
|
||||
}
|
||||
|
||||
/// Additive shares of the input `x` and the mask `r`. Reconstructs
|
||||
/// @brief Additive shares of the input `x` and the mask `r`. Reconstructs
|
||||
/// `eta = x - r` and passes additive shares of `center = 2r` (`2·r0`, `2·r1`)
|
||||
/// to arithmetic `geneval_cmp`. Returns both parties' Horner shares of the
|
||||
/// cubic at `x + r` (the group element `x + r`).
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @tparam Rng rng
|
||||
/// @param x0 the `x0`
|
||||
/// @param x1 the `x1`
|
||||
/// @param r0 the party 0's share of the mask
|
||||
/// @param r1 the party 1's share of the mask
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param rng the Doerner–Shelat randomness tapes
|
||||
/// @return Additive shares of the input `x` and the mask `r`
|
||||
template <std::size_t Degree = offset_horner_max_degree,
|
||||
typename InputT,
|
||||
typename Rng>
|
||||
|
|
@ -680,14 +770,25 @@ geneval_offset_horner_result<Degree, InputT> geneval_offset_horner(
|
|||
const std::vector<std::array<uint64_t, Degree + 1>> & coeff)
|
||||
{
|
||||
using block = typename dpf::prg::aes128::block_type;
|
||||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
dpf::ds_randomness<block (*)(), dpf::detail::urandom_pad_rng> rng{
|
||||
dpf::uniform_sample<block>, {}};
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
return geneval_offset_horner<Degree>(
|
||||
x0, x1, r0, r1, knots, coeff, std::move(rng));
|
||||
}
|
||||
|
||||
/// One party's share of the cubic at the wrapped `center + eta`.
|
||||
/// Sum the coefficient shares; they are already scaled by `center^k`.
|
||||
/// @brief One party's share of the cubic at the wrapped `center + eta`.
|
||||
/// @details Sum the coefficient shares; they are already scaled by `center^k`.
|
||||
/// @tparam Party party index, `0` or `1`
|
||||
/// @tparam Degree degree
|
||||
/// @tparam InputT input domain type
|
||||
/// @param mat the `mat`
|
||||
/// @param knots the `knots`
|
||||
/// @param coeff the public coefficient
|
||||
/// @param eta the `eta`
|
||||
/// @return One party's share of the cubic at the wrapped `center + eta`
|
||||
template <std::size_t Party, std::size_t Degree, typename InputT>
|
||||
uint64_t offset_horner_eval(
|
||||
const offset_horner_keys<InputT, Degree> & mat,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue