2026-09-26 23:51:06 -06:00
|
|
|
|
A *point function* is a huge list of zeros with one non-zero entry.
|
|
|
|
|
|
The index of that entry is secret. The value there is secret too.
|
2026-09-24 14:08:32 -06:00
|
|
|
|
|
2026-09-26 23:51:06 -06:00
|
|
|
|
A *(2,2) distributed point function* splits that list between two parties.
|
|
|
|
|
|
Each party gets a short key.
|
|
|
|
|
|
Either key alone looks random.
|
|
|
|
|
|
When both parties evaluate at the same public input and combine their shares,
|
|
|
|
|
|
they recover the true value of the point function there.
|
2026-09-24 14:08:32 -06:00
|
|
|
|
|
2026-09-26 23:51:06 -06:00
|
|
|
|
## Point functions {#point_functions}
|
|
|
|
|
|
|
|
|
|
|
|
Write `f_{α,β}` for the function that returns `β` at `α` and `0` elsewhere.
|
|
|
|
|
|
`make_dpf(α, β)` returns keys `(k0, k1)` such that:
|
|
|
|
|
|
|
|
|
|
|
|
- `Eval(k0, x)` and `Eval(k1, x)` are shares of `f_{α,β}(x)`
|
|
|
|
|
|
- `|k_i|` is about `O(λ · log |domain|)` for security parameter `λ`
|
|
|
|
|
|
|
|
|
|
|
|
Leaf payloads use subtractive shares. Comparison payloads use additive shares.
|
|
|
|
|
|
Open with `dpf::reconstruct`.
|
|
|
|
|
|
|
|
|
|
|
|
## What you pass to `make_dpf` {#make_dpf_args}
|
|
|
|
|
|
|
|
|
|
|
|
`make_dpf(x, y, ys...)` takes the secret index and one or more payloads.
|
|
|
|
|
|
`dpf::at<N>(y)` plants `y` on the public prefix of length `N`.
|
|
|
|
|
|
`dpf::idpf_at<N...>(ys...)` plants one payload per listed prefix.
|
|
|
|
|
|
`dpf::idpf(y0, y1, ...)` is the consecutive prefixes 1, 2, ….
|
|
|
|
|
|
Read a slot with `dpf::eval_point(dpf::out<I>, key, x)`, or
|
|
|
|
|
|
`dpf::out<I, W>` when `W` is that slot's prefix.
|
|
|
|
|
|
|
|
|
|
|
|
\code{cpp}
|
|
|
|
|
|
auto [k0, k1] = dpf::make_dpf(
|
|
|
|
|
|
std::uint8_t{0x2a},
|
|
|
|
|
|
dpf::at<4>(std::uint8_t{5}),
|
|
|
|
|
|
std::uint8_t{9});
|
|
|
|
|
|
auto hi = *dpf::eval_point(dpf::out<0, 4>, k0, std::uint8_t{0x2a});
|
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
|
A comparison payload is `dpf::lt`, `dpf::leq`, `dpf::gt`, or `dpf::geq`.
|
|
|
|
|
|
The same four names with `_at<N>` sit on a prefix. Evaluate that channel
|
|
|
|
|
|
with `dpf::cmp`. See [Comparisons and ranges](@ref tour_dcf).
|
|
|
|
|
|
|
|
|
|
|
|
Let `n` be the input bit length and `λ` the seed width. The key from
|
|
|
|
|
|
`make_dpf` is `Θ(n λ)` bits plus the payloads, and `eval_point` expands
|
|
|
|
|
|
`n` levels. That is the Boyle–Gilboa–Ishai CCS 2016 point key (full
|
|
|
|
|
|
version [ePrint 2018/707](@ref bib_fss2018)): one correction word per level, not their
|
|
|
|
|
|
[EUROCRYPT 2015](@ref bib_fss2015) key of `4n(λ+1)` bits. For a small output group `G`, Remark 3.4 of that full version stops
|
|
|
|
|
|
`ν = log2(λ / log2|G|)` levels early and shortens the key by `ν(λ+2)`
|
|
|
|
|
|
bits. This generator does that: the tree depth is `n` minus the log of
|
|
|
|
|
|
how many copies of `G` fit in one leaf, and those low bits select the lane.
|
|
|
|
|
|
Boyle, Gilboa, Ishai, and Kolobov ([ePrint 2023/028](@ref bib_itdpf)) give a statistically
|
|
|
|
|
|
private 3-server DPF and a perfectly private 4-server DPF;
|
|
|
|
|
|
`dpf::make_it_dpf3` is the additive three-server interface on a
|
|
|
|
|
|
`uint8_t` domain. `make_dpf` is a 2-party PRG key. Interval, sequence,
|
|
|
|
|
|
and full-domain costs are on [Evaluating DPFs](@ref evaluation).
|
|
|
|
|
|
|
|
|
|
|
|
Width literals (`100_u12`, `7_x12`, `1.5_fixed16`, `1_bit`, `2_twobit`,
|
|
|
|
|
|
`10_nyble`, `_bitstring`) are documented with the types that use them:
|
|
|
|
|
|
[Input types](@ref input_types), [Output types](@ref output_types).
|
|
|
|
|
|
|
|
|
|
|
|
**Defined in**\n
|
|
|
|
|
|
@ref dpf/dpf_key.hpp, @ref dpf/placement.hpp, @ref dpf/eval_target.hpp
|
|
|
|
|
|
|
|
|
|
|
|
## DPF Trees {#dpf_trees}
|
|
|
|
|
|
|
|
|
|
|
|
Keys store a seed and a list of *correction words*.
|
|
|
|
|
|
Evaluation walks a binary tree from the root toward `x`.
|
|
|
|
|
|
At each level a correction word mixes the two children so only the secret
|
|
|
|
|
|
path keeps differing seeds. Off-path nodes match and cancel when the parties
|
|
|
|
|
|
combine.
|
|
|
|
|
|
|
|
|
|
|
|
Classic keys use a Boyle–Gilboa–Ishai expand (CCS 2016, full version
|
|
|
|
|
|
[ePrint 2018/707](@ref bib_fss2018)).
|
|
|
|
|
|
Half-Tree keys (CCR interior PRG) follow Guo, Yang, Wang, Zhang, Xie,
|
|
|
|
|
|
Zhang, and Liu, [ePrint 2022/1431](@ref bib_halftree): mid-level children are `H(s)` and
|
|
|
|
|
|
`H(s) XOR s`. Their dealer point key keeps the CCS 2016 length and the
|
|
|
|
|
|
`n`-hash point evaluation; they state about `2n+2` random-permutation
|
|
|
|
|
|
calls to generate a key versus about `4n`, and `1.5N` calls for a
|
|
|
|
|
|
full-domain evaluation versus `2N`. See [tree_traits.hpp](@ref dpf/tree_traits.hpp).
|
|
|
|
|
|
|
|
|
|
|
|
For a slow, friendly walk through every feature, start at the
|
|
|
|
|
|
[guided tour](@ref guided_tour).
|