Initial import of libdpf.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
e4e666f459
4563 changed files with 1690372 additions and 0 deletions
5
doc/pages/basics.md
Normal file
5
doc/pages/basics.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<!-- # DPF Basics {#basics} -->
|
||||
|
||||
# Point functions {#point_functions}
|
||||
|
||||
# DPF Trees {#dpf_trees}
|
||||
80
doc/pages/evaluation.md
Normal file
80
doc/pages/evaluation.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<!-- # Evaluating DPFs {#evalaution} -->
|
||||
Once a `DPF` generated, the *eval_* * functions are used to evaluate differents inputs.
|
||||
The appropriate function depends on your specific needs. If you only need the DPF's output
|
||||
for a single input value, use `eval_point`. For evaluating a continuous range of inputs,
|
||||
`eval_interval` is suitable. To analyze the DPF's behavior across its entire domain, use `eval_full`.
|
||||
The code likely offers different implementations of memoization and output buffers, allowing you to
|
||||
optimize for memory usage or execution speed depending on your needs.\n
|
||||
Using a PRG while making a `DPF` allows the user to check how much it cost to manipulate the `DPF`s.
|
||||
|
||||
# Memoizers
|
||||
The `memoizers` remembers the most used path while the DPF is being created. These are usefull functions
|
||||
to improve the speed and the cost of execution.
|
||||
|
||||
**Code samples**\n
|
||||
For instance, in the code below the utilization of `dpf::make_basic_path_memoizer` reduced by 10 the time of execution
|
||||
compare to the code that is commented that doesn't use the `memoizers`.
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">memoizers.cpp</b> \include{cpp} evaluation/memoizers.cpp
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
# dpf::eval_point
|
||||
This function evaluate a single input of a DPF. The XOR result of the `eval_point` for both shares will only be equal to 1 if it represents the correct input in both evaluations. As input arguments it uses the `share` and the input to evaluate (note: it can't be a wildcard, otherwise it will throw an error).\n
|
||||
|
||||
**See also**\n
|
||||
PIR
|
||||
|
||||
**Pro tip**\n
|
||||
Use the `dpf::pathmemoizer` for a faster execution.\n
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">eval_point.cpp</b> \include{cpp} evaluation/eval_point.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::eval_interval
|
||||
This function evaluates a contiguous range of inputs. As input arguments it uses the `share` generated by `make_dpf`,
|
||||
`from` and `to` for the range of inputs to evaluate.\n
|
||||
|
||||
**See also**\n
|
||||
PIR
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">eval_interval.cpp</b> \include{cpp} evaluation/eval_interval.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::eval_full
|
||||
This function evaluate all the passible inputs it only uses as argument the `share` of the `DPF` to evaluate.
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">eval_full.cpp</b> \include{cpp} evaluation/eval_full.cpp
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
# dpf::eval_sequence
|
||||
This function evaluate a subset of inputs that is not contiguous (useful for a `DPF` made with `keyword`),
|
||||
it uses as arguments the `share` generated by `make_dpf`, `from` and `to` for the subset of inputs to evaluate.\n
|
||||
For a better utilization, you can use the `make_sequence_recipe` it takes as input a sorted list and returns a `recipe`.
|
||||
The cost of creating is a little bit worse than just calling `eval_sequence`, however once the `recipe` created
|
||||
`eval_sequence` is faster and has a better cost.
|
||||
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">eval_sequence.cpp</b> \include{cpp} evaluation/eval_sequence.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# Output buffers
|
||||
236
doc/pages/input_types.md
Normal file
236
doc/pages/input_types.md
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
<!-- # Input Types {#input_types} -->
|
||||
|
||||
An *input type* is the type used as the domain for the `x`-coordinate of a
|
||||
DPF. `libdpf++` ships with native support for a number of convenient input
|
||||
types, which are enumerated below. See also the [formal requirements](@ref custom_input_types)
|
||||
for a type not listed below to be used as an input type.
|
||||
|
||||
Within the `libdpf++` source, the (typically deduced) template parameter
|
||||
`typename InputT` indicates the input type of the DPF under consideration.
|
||||
Moreover, the `dpf::dpf_key` class (and some others) publicly expose the
|
||||
clause
|
||||
```
|
||||
using input_type = InputT;
|
||||
```
|
||||
providing an easy way to programmatically determine the input type.
|
||||
|
||||
# Integer scalar types
|
||||
Any integer scalar type—that is, any type `T` such that
|
||||
`std::numeric_limits<T>::is_integer == true`—may be used as an input
|
||||
type. In general, you should always opt for the "shortest" such type that
|
||||
suits your needs, as shorter bitlengths translate to smaller DPF keys and
|
||||
faster evaluations thereof.
|
||||
|
||||
**Pro tip**\n
|
||||
Prefer the use of [fixed width integer types](https://en.cppreference.com/w/cpp/types/integer)
|
||||
over [fundamental integer types](https://en.cppreference.com/w/cpp/language/types)
|
||||
for specifying input types. For example, use `uint16_t` in place of
|
||||
`unsigned short`, or `int32_t` in place of `int`. Doing so improves
|
||||
portability and makes it easier to keep track of the resulting DPF depth.
|
||||
|
||||
**See also**\n
|
||||
The `dpf::modint` class template for custom-bitlength integer types that
|
||||
allow tighter control over size of DPF keys.
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">integral_types.cpp</b> \include{cpp} input_types/integral_types.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# Extended-precision integer scalar types
|
||||
|
||||
The extended-precision (`128`-bit) integer scalar types provided as
|
||||
compiler extensions by most major C++ compilers (e.g., `__int128` and `unsigned __int128`), including `g++` and
|
||||
`clang++` when compiling for `64`-bit targets. (As these types are not
|
||||
defined in the C++17 standard, `std::numeric_limits` is not specialized
|
||||
for them, so that `std::numeric_limits<__int128>::is_integer` returns
|
||||
`false`.)
|
||||
|
||||
**Pro tip**\n
|
||||
Use `simde_uint128` (provided courtesy of (SIMD Everywhere)[https://github.com/simd-everywhere/simde])
|
||||
to declare such 128-bit integers in compiler-independent way.
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">extended_types.cpp</b> \include{cpp} input_types/extended_types.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::modint<Nbits>
|
||||
|
||||
Arbitrary-, yet fixed-bitlength unsigned integer types. `dpf::modint` is a
|
||||
lightweight class template that adapts one of the above-mentioned integer
|
||||
types for arithmetic modulo `2^Nbits`, where `std::size_t Nbits` is the
|
||||
template parameter. The specialization chooses an appropriate type for
|
||||
the underlying integer and uses bitmasking to lazily reduce that integer
|
||||
when the value is read (by anything other than a like-sized `modint`).
|
||||
This ensures that arithmetic on `modint`s is just as fast as arithmetic on
|
||||
the underlying integer type. Specializations with `Nbits` from `1` through
|
||||
`256` inclusive are supported. Compound assignments (`+=`, `-=`, `*=`,
|
||||
`&=`, `|=`, `^=`) modify the object even when the returned reference is
|
||||
discarded.
|
||||
|
||||
**Pro tip**\n
|
||||
Choose the smallest `Nbits` possible to get DPFs of the shortest length --
|
||||
and with the fastest evaluations -- possible.
|
||||
|
||||
**Defined in**\n
|
||||
@ref dpf/modint.hpp
|
||||
|
||||
**Code samples**\n
|
||||
Here are some examples of arithmetic operations with `dpf::modint`:
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">modint.cpp</b> \include{cpp} input_types/modint.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::bitstring<Nbits>
|
||||
|
||||
Arbitrary-, yet fixed- bitlength binary strings types. `dpf::bitstring` is
|
||||
a class template that represents a binary string of any given length.
|
||||
Compared with `dpf::modint`, a `dpf::bitstring` is well suited to cases
|
||||
where inputs do not semantically stand for numerical values. For example,
|
||||
the input may be a pseudorandom identifier or a cryptographic key. There
|
||||
is no fixed limit on the acceptable bitlength for a `dpf::bitstring`.
|
||||
|
||||
In contrast with `dpf::modint`, which uses a (possibly extended-precision)
|
||||
integer type for its internal representation, the `dpf::bitstring` class
|
||||
template derives from `dpf::static_bit_array` and, therefore, provides a
|
||||
wealth of methods and helpers for interacting with its individual bits.
|
||||
|
||||
**Pro tip**\n
|
||||
As always, choose the smallest `Nbits` possible to get DPFs of the
|
||||
shortest length -- and with the fastest evaluations -- possible.
|
||||
|
||||
**Defined in**\n
|
||||
@ref dpf/bitstring.hpp
|
||||
|
||||
**See also**\n
|
||||
`dpf::bit` and `dpf::static_bit_array`
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">bitstring.cpp</b> \include{cpp} input_types/bitstring.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::keyword<Alphabet, N>
|
||||
|
||||
Fixed-length strings over restricted alphabets. `dpf::keyword` is an alias
|
||||
for the class template `dpf::basic_fixed_length_string`, which represents
|
||||
a string of length `N` consisting solely of letters from
|
||||
`alphabet`, where `std::size_t N` and `static const char alphabet[]` are
|
||||
template parameters. To a first approximation, the `dpf::keyword` class
|
||||
template views each eligible string as an integer expressed in
|
||||
radix-`std::strlen(alphabet)` and then stores the associated binary number as its
|
||||
internal representation. This produces representations that are
|
||||
*significantly* shorter than that of the associated C-string, especially
|
||||
when `alphabet` comprises few elements.
|
||||
|
||||
For example
|
||||
\code{cpp}
|
||||
const char cstr[] = "7fffae02";
|
||||
std::cout << (sizeof(cstr) - 1) * CHAR_BIT << "\n"; // prints 64
|
||||
|
||||
using kw = dpf::keyword<8, dpf::alphabets::hex>;
|
||||
kw str = "7fffae02";
|
||||
std::cout << dpf::utils::bitlength_of_v<kw> << "\n"; // prints 32
|
||||
|
||||
using kw2 = dpf::keyword<8, dpf::alphabets::alphanumeric>;
|
||||
kw2 str2 = "7fffae02";
|
||||
std::cout << dpf::utils::bitlength_of_v<kw2> << "\n"; // prints 48
|
||||
|
||||
inline constexpr char my_alphabet[] = "7fae02";
|
||||
using kw3 = dpf::keyword<8, my_alphabet>;
|
||||
kw3 str3 = "7fffae02";
|
||||
std::cout << dpf::utils::bitlength_of_v<kw3> << "\n"; // prints 21
|
||||
|
||||
using kw4 = dpf::keyword<8, dpf::alphabets::lowercase_alpha>;
|
||||
kw4 str4 = "7fffae02"; // error (disallowed chars)
|
||||
\endcode
|
||||
|
||||
**Pro tip**\n
|
||||
Strings implicitly padded to length `N` with "zeros"; i.e., with the first
|
||||
letter in `alphabet`. To allow for strings of length *less than* `N`,
|
||||
simply set ``alphabet[0]='\0'``.
|
||||
|
||||
**Defined in**\n
|
||||
@ref dpf/keyword.hpp
|
||||
|
||||
**See also**\n
|
||||
The `dpf::alphabets` namespace for a catalog of predefined alphabets.
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">keyword.cpp</b> \include{cpp} input_types/keyword.cpp
|
||||
|
||||
</div>
|
||||
|
||||
# dpf::xor_wrapper<T>
|
||||
|
||||
An element of `GF(2)^N` for `N=8*sizeof(T)`. `xor_wrapper` is a
|
||||
lightweight class template that adapts "integer-like" types so that
|
||||
arithmetic behaves like component-wise `GF(2)^N` arithmetic; that is,
|
||||
(binary `+` and `-` both become `^`; binary `*` becomes `&`; unary `-`
|
||||
becomes a nop). This is useful for cases where instances of the input type
|
||||
are to be XOR-shared among two parties. `xor_wrapper` may be specialized
|
||||
with any of the above-mentioned input types.
|
||||
|
||||
**Defined in**\n
|
||||
@ref dpf/xor_wrapper.hpp
|
||||
|
||||
**Code samples**\n
|
||||
<div class="tabbed">
|
||||
|
||||
- <b class="tab-title">xor_wrapper</b> \include{cpp} input_types/xor_wrapper.cpp
|
||||
|
||||
</div>
|
||||
|
||||
- - -
|
||||
|
||||
# Custom input type requirements {#custom_input_types}
|
||||
|
||||
A type can be a DPF input when the library can walk its bits and, for interval
|
||||
or full-domain evaluation, order its values.
|
||||
|
||||
The walk uses `dpf::utils::msb_of<T>::value` as a mask. That mask must support
|
||||
`mask & x` (the tested bit) and `mask >>= 1` (the next-lower bit). `dpf::utils::bitlength_of<T>`
|
||||
is the number of steps; for a type that is not an integer it defaults to
|
||||
`CHAR_BIT * sizeof(T)`, so specialize it when the meaningful width is smaller.
|
||||
`dpf::utils::mod_pow_2<T>` extracts the low bits that select an output inside a
|
||||
packed leaf (`offset_within_block`).
|
||||
|
||||
Interval and full-domain evaluation also need `operator>`, `operator<`, and
|
||||
`std::numeric_limits<T>::min()` / `max()`. Sequence evaluation needs
|
||||
`dpf::utils::countl_zero_symmetric_difference<T>` when the default, which
|
||||
truncates to 64 bits, is not correct for `T`.
|
||||
|
||||
A complete example is `test/tests/helpers/custom_input_type.hpp`. The
|
||||
comparison must be a real order:
|
||||
|
||||
\code{cpp}
|
||||
bool operator>(input_type lhs, input_type rhs) { return lhs.i > rhs.i; }
|
||||
\endcode
|
||||
|
||||
`msb_of` for a 32-bit payload looks like this. The mask type has to be the
|
||||
type stored in `msb_of<T>::value`, and `mask & x` has to compile:
|
||||
|
||||
\code{cpp}
|
||||
namespace dpf::utils {
|
||||
template <> struct msb_of<input_type> {
|
||||
static constexpr input_type value{int32_t{1} << 31};
|
||||
};
|
||||
template <> struct mod_pow_2<input_type> {
|
||||
std::size_t operator()(input_type val, std::size_t n) const noexcept {
|
||||
if (n == 0) return 0;
|
||||
return static_cast<std::size_t>(static_cast<uint32_t>(val.i) & ((std::size_t{1} << n) - 1));
|
||||
}
|
||||
};
|
||||
}
|
||||
\endcode
|
||||
33
doc/pages/introduction.md
Normal file
33
doc/pages/introduction.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Introduction
|
||||
|
||||
## Synopsis {#synopsis}
|
||||
|
||||
`libdpf++` is a fast and extensible, header-only C++17 implementation of
|
||||
`(2,2)-`*distributed point functions* (or *DPFs*). In addition to core DPF
|
||||
functionality, `libdpf++` provides a plethora of data structures, helper
|
||||
functions, and syntactic sugar designed to facilitate seamless integration
|
||||
into higher-level cryptographic protocols and primitives. With its focus on
|
||||
speed and ease of use, `libdpf++` is an ideal building block for implementing
|
||||
private information retrieval (PIR), secure multiparty computation (MPC),
|
||||
zero-knowledge arguments, anonymous messaging, and more.
|
||||
|
||||
## Features {#features}
|
||||
|
||||
- <i class="fa-solid fa-right-from-bracket"></i> input types
|
||||
- <i class="fa-solid fa-right-to-bracket"></i> output types
|
||||
- <i class="fa-solid fa-shuffle"></i> wildcards
|
||||
- <i class="fa-brands fa-pagelines"></i> multiple leaves
|
||||
- <i class="fa-solid fa-ellipsis"></i> evaluation types
|
||||
- <i class="fa-solid fa-memory"></i> memoizers
|
||||
- <i class="fa-solid fa-file-lines"></i> json serialization
|
||||
- <i class="fa-solid fa-route"></i> asynchronous I/O
|
||||
|
||||
## Credits {#credits}
|
||||
|
||||
- Adithya Vadapalli (IIT Kanpur)
|
||||
- Kyle Storrier (UCalgary)
|
||||
- Allan Lyons (UCalgary)
|
||||
|
||||
## Disclaimer {#disclaimer}
|
||||
|
||||
We bet you $50 that there is at least one security bug in this code base. If you are you use this code, it is on you to verify that bug does not cross any of the same code paths as you.
|
||||
13
doc/pages/iterables.md
Normal file
13
doc/pages/iterables.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!-- # Iterables {#iterables} -->
|
||||
|
||||
# dpf::setbit_index_iterable
|
||||
|
||||
# dpf::subsequence_iterable
|
||||
|
||||
# dpf::subinterval_iterable
|
||||
|
||||
# dpf::zip_iterable
|
||||
|
||||
# dpf::parallel_bit_iterable
|
||||
|
||||
# dpf::advice_bit_iterable
|
||||
122
doc/pages/listings.md
Normal file
122
doc/pages/listings.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<!-- # Code Listings {#listings} -->
|
||||
|
||||
- \subpage input_type_examples
|
||||
- \subpage output_type_examples
|
||||
- \subpage evaluation_examples
|
||||
- \subpage iteratable_examples
|
||||
|
||||
\page input_type_examples input_types
|
||||
|
||||
- \subpage input_types_2integral_types_8cpp
|
||||
- \subpage input_types_2extended_types_8cpp
|
||||
- \subpage input_types_2modint_8cpp
|
||||
- \subpage input_types_2bitstring_8cpp
|
||||
- \subpage input_types_2keyword_8cpp
|
||||
- \subpage input_types_2xor_wrapper_8cpp
|
||||
- \subpage input_types_2custom_8cpp
|
||||
|
||||
\page "input_types_2integral_types_8cpp" input_types/integral_types.cpp
|
||||
\include{cpp} input_types/integral_types.cpp
|
||||
|
||||
\page "input_types_2extended_types_8cpp" input_types/extended_types.cpp
|
||||
\include{cpp} input_types/extended_types.cpp
|
||||
|
||||
\page "input_types_2modint_8cpp" input_types/modint.cpp
|
||||
\include{cpp} input_types/modint.cpp
|
||||
|
||||
\page "input_types_2bitstring_8cpp" input_types/bitstring.cpp
|
||||
\include{cpp} input_types/bitstring.cpp
|
||||
|
||||
\page "input_types_2keyword_8cpp" input_types/keyword.cpp
|
||||
\include{cpp} input_types/keyword.cpp
|
||||
|
||||
\page "input_types_2xor_wrapper_8cpp" input_types/xor_wrapper.cpp
|
||||
\include{cpp} input_types/xor_wrapper.cpp
|
||||
|
||||
\page "input_types_2custom_8cpp" input_types/custom.cpp
|
||||
\include{cpp} input_types/custom.cpp
|
||||
|
||||
\page output_type_examples output_types
|
||||
|
||||
- \subpage output_types_2integral_types_8cpp
|
||||
- \subpage output_types_2extended_types_8cpp
|
||||
- \subpage output_types_2bit_8cpp
|
||||
- \subpage output_types_2bitstring_8cpp
|
||||
- \subpage output_types_2wildcard_8cpp
|
||||
- \subpage output_types_2xor_wrapper_8cpp
|
||||
- \subpage output_types_2custom_8cpp
|
||||
|
||||
\page "output_types_2integral_types_8cpp" output_types/integral_types.cpp
|
||||
\include{cpp} output_types/integral_types.cpp
|
||||
|
||||
\page "output_types_2extended_types_8cpp" output_types/extended_types.cpp
|
||||
\include{cpp} output_types/extended_types.cpp
|
||||
|
||||
\page "output_types_2bit_8cpp" output_types/bit.cpp
|
||||
\include{cpp} output_types/bit.cpp
|
||||
|
||||
\page "output_types_2bitstring_8cpp" output_types/bitstring.cpp
|
||||
\include{cpp} output_types/bitstring.cpp
|
||||
|
||||
\page "output_types_2wildcard_8cpp" output_types/wildcard.cpp
|
||||
\include{cpp} output_types/wildcard.cpp
|
||||
|
||||
\page "output_types_2xor_wrapper_8cpp" output_types/xor_wrapper.cpp
|
||||
\include{cpp} output_types/xor_wrapper.cpp
|
||||
|
||||
\page "output_types_2custom_8cpp" output_types/custom.cpp
|
||||
\include{cpp} output_types/custom.cpp
|
||||
|
||||
\page evaluation_examples evaluation
|
||||
|
||||
- \subpage evaluation_2eval_point_8cpp
|
||||
- \subpage evaluation_2eval_interval_8cpp
|
||||
- \subpage evaluation_2eval_full_8cpp
|
||||
- \subpage evaluation_2eval_sequence_8cpp
|
||||
- \subpage evaluation_2memoizers_8cpp
|
||||
- \subpage evaluation_2output_buffers_8cpp
|
||||
|
||||
\page "evaluation_2eval_point_8cpp" evaluation/eval_point.cpp
|
||||
\include{cpp} evaluation/eval_point.cpp
|
||||
|
||||
\page "evaluation_2eval_interval_8cpp" evaluation/eval_interval.cpp
|
||||
\include{cpp} evaluation/eval_interval.cpp
|
||||
|
||||
\page "evaluation_2eval_full_8cpp" evaluation/eval_full.cpp
|
||||
\include{cpp} evaluation/eval_full.cpp
|
||||
|
||||
\page "evaluation_2eval_sequence_8cpp" evaluation/eval_sequence.cpp
|
||||
\include{cpp} evaluation/eval_sequence.cpp
|
||||
|
||||
\page "evaluation_2memoizers_8cpp" evaluation/memoizers.cpp
|
||||
\include{cpp} evaluation/memoizers.cpp
|
||||
|
||||
\page "evaluation_2output_buffers_8cpp" evaluation/output_buffers.cpp
|
||||
\include{cpp} evaluation/output_buffers.cpp
|
||||
|
||||
\page iteratable_examples iterables
|
||||
|
||||
- \subpage iterables_2setbit_index_iterable_8cpp
|
||||
- \subpage iterables_2advice_bit_iterable_8cpp
|
||||
- \subpage iterables_2parallel_bit_iterable_8cpp
|
||||
- \subpage iterables_2subinterval_iterable_8cpp
|
||||
- \subpage iterables_2subsequence_iterable_8cpp
|
||||
- \subpage iterables_2zip_iterable_8cpp
|
||||
|
||||
\page "iterables_2setbit_index_iterable_8cpp" iterables/setbit_index_iterable.cpp
|
||||
\include{cpp} iterables/setbit_index_iterable.cpp
|
||||
|
||||
\page "iterables_2advice_bit_iterable_8cpp" iterables/advice_bit_iterable.cpp
|
||||
\include{cpp} iterables/advice_bit_iterable.cpp
|
||||
|
||||
\page "iterables_2parallel_bit_iterable_8cpp" iterables/parallel_bit_iterable.cpp
|
||||
\include{cpp} iterables/parallel_bit_iterable.cpp
|
||||
|
||||
\page "iterables_2subinterval_iterable_8cpp" iterables/subinterval_iterable.cpp
|
||||
\include{cpp} iterables/subinterval_iterable.cpp
|
||||
|
||||
\page "iterables_2subsequence_iterable_8cpp" iterables/subsequence_iterable.cpp
|
||||
\include{cpp} iterables/subsequence_iterable.cpp
|
||||
|
||||
\page "iterables_2zip_iterable_8cpp" iterables/zip_iterable.cpp
|
||||
\include{cpp} iterables/zip_iterable.cpp
|
||||
90
doc/pages/output_types.md
Normal file
90
doc/pages/output_types.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<!-- # Output Types {#output_types} -->
|
||||
|
||||
An output type is the group element stored at the programmed input. Every
|
||||
output of one DPF must have the same `dpf::utils::bitlength_of_output` width,
|
||||
and each output type must be trivially copyable and standard layout. Leaf
|
||||
addition and subtraction are the group operation; leaf multiplication scales
|
||||
a leaf by one output element (used by wildcard Beaver triples and inner
|
||||
products).
|
||||
|
||||
# Integer scalar types
|
||||
|
||||
Fixed-width integers (`uint32_t`, `int64_t`, and the other `psnip` widths)
|
||||
are an additive group. Leaves use SIMD add, subtract, and multiply, including
|
||||
`char`, `long long`, `char16_t`, `char32_t`, and `wchar_t` at 8, 16, 32, and
|
||||
64 bits. `bool` is an 8-bit integer, not a packed bit. Use `dpf::bit` for one
|
||||
bit.
|
||||
|
||||
`dpf::modint<N>` is an output as well as an input. Packed leaves add the
|
||||
underlying word; values wider than one AES block add with `operator+`.
|
||||
|
||||
# Secret shares {#secret_shares}
|
||||
|
||||
`dpf::additive_share<T, Party>` and `dpf::subtractive_share<T, Party>` are
|
||||
layout-identical wrappers around a number-like `T` (`Party` is `0` or `1`).
|
||||
Reconstruction is `share0 + share1` for additive shares and `share0 - share1`
|
||||
for subtractive shares. Creating from a plaintext puts the value on party 0
|
||||
and zero on party 1.
|
||||
|
||||
Leaf evaluation returns subtractive shares of the payload. Comparison
|
||||
(`lt`/`leq`/`gt`/`geq`) returns additive shares. Public plaintexts absorb on
|
||||
party 0 only. Mixing additive and subtractive shares at the same party flips
|
||||
the differing-scheme operand on party 1 so the opened secret stays correct.
|
||||
Use `raw()` / `from_raw` / `retag` for intentional bit-level escapes.
|
||||
|
||||
`make_dpf` returns a `party_key` pair so each party's eval result is typed.
|
||||
Pass plaintext domain points and payloads; use `reconstruct` (or `raw()`)
|
||||
when you already hold shares.
|
||||
|
||||
# Extended-precision integer scalar types
|
||||
|
||||
`simde_int128`, `simde_uint128`, `uint128_t`, and `uint256_t` are additive.
|
||||
Their leaf arithmetic is ordinary addition of those integers.
|
||||
|
||||
# dpf::bit
|
||||
|
||||
A one-bit output. The group is XOR: `operator+` and `operator-` are both XOR,
|
||||
and a leaf multiply is AND with an all-zero or all-one mask. Many `dpf::bit`
|
||||
outputs are packed into each leaf.
|
||||
|
||||
# dpf::bitstring<Nbits>
|
||||
|
||||
A fixed string of bits in the XOR group. `operator+`, `operator-`, and leaf
|
||||
addition are XOR. The leftmost character of a literal or of `to_string` is
|
||||
the most significant bit, matching `0b` notation. Bits above `Nbits` are not
|
||||
part of the value.
|
||||
|
||||
# dpf::wildcard<T>
|
||||
|
||||
`dpf::wildcard_value<T>` is a placeholder. The leaf group is the group of
|
||||
`T`. The value can be filled in later; until then evaluation of that output
|
||||
throws. `operator()` accepts both lvalues and rvalues.
|
||||
|
||||
`float` and `double` wildcards are bitwise, not IEEE arithmetic. Leaf
|
||||
addition is XOR of the representation and leaf scaling is AND, which is an
|
||||
exact group. It is not floating-point addition.
|
||||
|
||||
# dpf::xor_wrapper<T>
|
||||
|
||||
An element of `GF(2)^n` for `n = 8 * sizeof(T)`, or `n = N` for
|
||||
`dpf::xint<N>`. `operator+` and `operator-` are XOR, `operator*` is AND, and
|
||||
`++` / `--` flip the low bit (the same XOR with 1). Leaf addition is XOR and
|
||||
leaf scaling is AND.
|
||||
|
||||
# Custom output type requirements {#custom_output_types}
|
||||
|
||||
Specialize `dpf::leaf_arithmetic::add_t`, `subtract_t`, and `multiply_t` for
|
||||
the exterior node type (`simde__m128i` for the default AES PRG, and
|
||||
`simde__m256i` when that node is used). Each functor's call operator receives
|
||||
two nodes for addition and subtraction, or a node and one output value for
|
||||
multiplication, and returns a node.
|
||||
|
||||
When the output is larger than one node, the leaf is
|
||||
`std::array<node, block_length>`. That path uses `operator+` and `operator-`
|
||||
on the output type when those expressions are valid, and otherwise XORs the
|
||||
blocks. Prefer an explicit specialization when the group is not
|
||||
component-wise `+` of one output object.
|
||||
|
||||
Outputs must be trivially copyable and standard layout. `dpf::utils::make_from_integral_value<T>`
|
||||
should build `T` from the integer `1` when tests or `make_default` need a
|
||||
nonzero payload. See `test/tests/helpers/custom_output_type_small.hpp`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue